fly*_*bin 11 c c++ linux signals interrupt
在x86(64位或32位)Linux上 - 例如:
void signal_handler(int) {
// want to know where the program is interrupted ...
}
int main() {
...
signal(SIGALRM, signal_handler);
alarm(5);
...
printf(...); <------- at this point, we trigger signal_handler
...
}
Run Code Online (Sandbox Code Playgroud)
在signal_handler中,我们怎么知道我们在main()的printf中被中断了?
Nem*_*emo 12
在sa_flags中设置SA_SIGINFO时使用sigaction.
原型代码:
#define _GNU_SOURCE 1 /* To pick up REG_RIP */
#include <stdio.h>
#include <signal.h>
#include <assert.h>
static void
handler(int signo, siginfo_t *info, void *context)
{
const ucontext_t *con = (ucontext_t *)context;
/* I know, never call printf from a signal handler. Meh. */
printf("IP: %lx\n", con->uc_mcontext.gregs[REG_RIP]);
}
int
main(int argc, char *argv[])
{
struct sigaction sa = { };
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = handler;
assert(sigaction(SIGINT, &sa, NULL) == 0);
for (;;);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
运行它并点击Ctrl-C.(Ctrl-\用于终止...)
这适用于x86_64.对于32位x86,请使用REG_EIP而不是REG_RIP.
[编辑]
当然,如果你实际上在库函数(如printf)或系统调用(如write)中,RIP/EIP寄存器可能指向某个有趣的...
您可能希望使用libunwind来抓取堆栈.