3

I am working on a C project that has bunch of files. Now I want to find the signal handler functions, but no success while surfing the project tree.

The first way I think about approaching this problem is running the binary with GDB.

Is there a way I can ask GDB to break as soon as a signal (e.g. Ctrl-C) is received?

bagrat
  • 7,158
  • 6
  • 29
  • 47
  • 1
    [GDB manual signals section](https://sourceware.org/gdb/onlinedocs/gdb/Signals.html). By default gdb should stop on ctrl-c. Are you not seeing that behaviour in your debugging? – kaylum Nov 24 '15 at 10:01
  • To your original problem - is there a particular reason why you can't find the signal handlers from the source? You should able to easily search for `signal` and `sigaction` function calls. – kaylum Nov 24 '15 at 10:06
  • @kaylum you are completely right. I have searched for `signal(` and found some code. But anyway, globally I did not find what I wanted. So let's return to the original question. Is there a way I can ask GDB to *pause* right at the next instruction/line after receiving some signal, e.g. `SIGINT`? – bagrat Nov 24 '15 at 10:19
  • Yes. By default gdb will break on SIGTERM. Run `info signal` inside gdb to check whether it stops on the signal you are interested in. If not, then run `handle stop` to get gdb to break. Then when the signal occurs it will drop into gdb. Then run `step` to step into the signal handler. – kaylum Nov 24 '15 at 10:29

1 Answers1

8

Here is some reference:

http://nirbhay.in/2012/09/debug-signal-handlers-using-gdb/

Let's do some experiment with this program:

/*
  @file : sig.c
*/

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

void signalhandler(int signum) {
  printf("\n SIGINT caught : %d", signum);
}

int main() {
  signal(SIGINT, signalhandler);

  while (1) {
    printf("\n looping : inside main()");
    sleep(1);
  }
}

in this case you can do this way:

(gdb) handle SIGINT stop pass

after that, you step forward to get the signal handler function. Here I got:

$ gdb ./a

...

(gdb) handle SIGINT stop pass
SIGINT is used by the debugger.
Are you sure you want to change it? (y or n) y
Signal        Stop  Print   Pass to program Description
SIGINT        Yes   Yes Yes     Interrupt
(gdb) r
Starting program: /home/arc/a 

 looping : inside main()
 looping : inside main()
^C
Program received signal SIGINT, Interrupt.
0x00007ffff7aef900 in __nanosleep_nocancel () from /usr/lib/libc.so.6
(gdb) s
Single stepping until exit from function __nanosleep_nocancel,
which has no line number information.
0x0000000000400596 in signalhandler(int) ()
ibrohimislam
  • 717
  • 7
  • 21
  • Isn't that command the opposite of what the OP wants? Which is to break/stop on ctrl-c. And if you are going to provide a reference I would think that the official GDB documentation would be better. – kaylum Nov 24 '15 at 10:09
  • Pardon me. What I catch is "How to create breakpoint on signalhandler?" as he says "Now I want to find the signal handler functions, but no success while surfing the project tree.". – ibrohimislam Nov 24 '15 at 10:11
  • The question is: "Is there a way I can ask GDB to break as soon as a signal (e.g. Ctrl-C) is received?". That is, break into GDB when a signal occurs. How does setting the gdb signal disposition to `nostop pass` achieve that? I'm not understanding that part. – kaylum Nov 24 '15 at 10:13
  • I think your updated answer is exactly what is required. Minor issue: Don't call `printf` in your signal handler as that is not async safe. Use `write` to `STDOUT_FILENO` if you want to output something. – kaylum Nov 24 '15 at 10:31
  • Thanks a lot @ibrohimislam, this is exactly what I was looking for!! – bagrat Nov 24 '15 at 10:48