Search code examples
cpostgresqldebugginggdb

Debugging a program that uses SIGINT with gdb


I frequently work with PostgreSQL for debugging, and it uses SIGINT internally for some of its inter-backend signalling.

As a result when running certain backends under gdb execution tends to get interrupted a lot. One can use the signal command to make sure SIGINT is passed to the program and that it is not captured by gdb... but then gdb doesn't respond to control-C on the command line, since that sends SIGINT.

If you run:

handle SIGINT noprint nostop pass

gdb will complain

SIGINT is used by the debugger.
Are you sure you want to change it? (y or n) y

Is there any way to get gdb to use a different interrupt signal? Or any alternative method that'd let me have gdb ignore SIGINT?

(This isn't an issue for most PostgreSQL backend debugging, but it's a pain with background workers and autovacuum).


Solution

  • On UNIX-like systems, you can distinguish a tty-initiated SIGINT from one sent by kill by looking at the si_pid element in the siginfo struct. If the pid is 0, it came from a tty.

    So you could do something like this:

    catch signal SIGINT
    commands
      if $_siginfo._sifields._kill.si_pid == 0
        print "Received SIGINT from tty"
      else
        printf "Received SIGINT from %d; continuing\n", $_siginfo._sifields._kill.si_pid
        signal SIGINT
      end
    end