私のプロジェクトの 1 つで、RFLAGS レジスタを手動で編集して、TF ビットを使用して各命令で SIGTRAP を発生させる必要があります。プログラムを直接実行する場合は機能しますが、Valgrind で実行する場合は機能しません。
ここに私が何を意味するかを示す簡単なプログラムがあります:
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#define REG_EFL 17
#define TRAP_FLAG 0x100
void handler(int sig, siginfo_t *siginfo, void *ctx) {
const char msg[] = "From handler\n";
write(STDOUT_FILENO, msg, sizeof(msg)-1);
((ucontext_t*)ctx)->uc_mcontext.gregs[REG_EFL] &= ~TRAP_FLAG;
}
int main() {
struct sigaction act = {0};
act.sa_sigaction = &handler;
act.sa_flags = SA_SIGINFO;
sigaction(SIGTRAP, &act, NULL);
puts("Raising SIGTRAP 1");
__asm__("pushfq;"
"pop %rax;"
"or $0x100, %rax;"
"push %rax;"
"popfq;");
puts("Raising SIGTRAP 2");
__asm__("int3;");
return 0;
}
予想される出力は次のとおりです。
Raising SIGTRAP 1
From handler
Raising SIGTRAP 2
From handler
Valgrind の出力は次のとおりです。
Raising SIGTRAP 1
Raising SIGTRAP 2
From handler