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).
From the (gdb) prompt, type signal SIGINT . This will send (surprize) SIGINT to the program being debugged. Alternatively, handle SIGINT nostop print pass will make GDB pass the signal straight to the inferior (being debugged) process. Ctrl-Z works in GDB: it suspends the process and gets you to that (gdb) prompt.
The role of ptrace() in GDBIt lets GDB observe and control the execution of the inferior program. ptrace() can, for example, set the registers, peek and poke memory, continue or interrupt the inferior — all the good stuff we need for debugging. The inferior and GDB asynchronously communicate via signals.
Step-by-step example for using GDB within Emacs to debug a C or C++ program. You can debug a C or C++ program using GDB, the GNU debugger, which was developed by the same organization that released Emacs. You can easily integrate it with Emacs to interactively debug programs.
Readers who end up on this page (as I did) with a slightly different variation of this problem, would perhaps be more interested in this question:
Debugging a segmentation fault when I do ctrl c
... and its answer, which is:
send SIGINT from inside gdb itself:
(gdb) signal 2
(Normally I would post the link as a simple comment under the OP's question on this page, but since there are already 7 comments, comments are being hidden/buried.)
If you read all the details of the OP's question here, then it is obvious that my answer is not correct for OP.
However, my answer is correct for many situations that could be described by the same title: "Debugging a program that uses SIGINT with gdb"
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
This part of gdb is a bit tricky, both due to its history and also due to the various modes of operation it supports.
One might think that running gdb in a separate terminal and only using attach
would help it do the right thing, but I don't think it is that easy.
One way forward might be to only use async execution when debugging, and then use a command to interrupt the inferior. Something like:
(gdb) attach 5555
... attaches
(gdb) continue &
... lots of stuff happens
(gdb) interrupt -a
Depending on your version of gdb you might need to set target-async
for this to work.
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