在我的一个项目中,我需要手动编辑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