Используйте sigaction с SA_SIGINFO, установленным в sa_flags.
Код прототипа:
#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;
}
Запустите его и нажмите Ctrl-C .(Используйте Ctrl - \ для завершения ...)
Это для x86_64.Для 32-битного x86, используйте REG_EIP
вместо REG_RIP
.
[edit]
Конечно, если вы на самом деле находитесь в библиотечной функции (например, printf
) илисистемный вызов (например, write
), регистр RIP / EIP может указывать на что-то смешное ...
Возможно, вы захотите использовать libunwind для сканирования стека.