On x86 (either 64-bit or 32-bit) Linux -- for example:
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
...
}
In signal_handler, how can we know we are interrupted at printf in main()?
The signal handler can indeed be interrupted by another signal (assuming it isn't the same signal as the one which invoked the handler in the first place). your handler can still be interrupted by delivery of another kind of signal.
An interrupt is a signal emitted by a device attached to a computer or from a program within the computer. It requires the operating system (OS) to stop and figure out what to do next. An interrupt temporarily stops or terminates a service or a current process.
A signal handler is a function which is called by the target environment when the corresponding signal occurs. The target environment suspends execution of the program until the signal handler returns or calls longjmp() . Signal handlers can be set with signal() or sigaction() .
Use sigaction with SA_SIGINFO set in sa_flags.
Prototype code:
#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 it and hit Ctrl-C. (Use Ctrl-\ to terminate...)
This is for x86_64. For 32-bit x86, use REG_EIP
instead of REG_RIP
.
[edit]
Of course, if you are actually in a library function (like printf
) or a system call (like write
), the RIP/EIP register might point somewhere funny...
You might want to use libunwind to crawl the stack.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With