Handling signals with gdb - c++

I'm debugging a C++ app for Ubuntu 10.04 that sometimes receives a SIGKILL signal.
I want to catch the signal and stop it from killing the execution, just to see if I can get some useful info of the app's state at that precise moment.
Reading the gdb documentation I found the handle command, so I tried to apply it to the SIGKILL signal:
(gdb) handle SIGKILL stop nopass
Signal Stop Print Pass to program Description
SIGKILL Yes Yes No Killed
So, as I understand this correctly:
stop
GDB should stop your program when this signal happens. This implies the print keyword as well.
print
GDB should print a message when this signal happens.
nopass
GDB should not allow your program to see this signal.
once the SIGKILL signal is emitted, gdb should somehow catch it, print the message, stop the execution and don't let the app kill itself, right?
The problem is that this doesn't happen and the app terminates.
Do you know how could I catch the signal?
Useful Info:
The piece of code that is running when the signal is emitted is executed in another thread.
gdb version: 4.4.3
g++ version: 7.1

From unix signal(7) man page:
The signals SIGKILL and SIGSTOP cannot be caught, blocked, or ignored.
So the debugger can set the handler but that doesn't make any sense. The OS directly performs the needed action. If SIGKILL could be handled from application the OS has no chance to terminate a broken application. For that reason SIGKILL is a bit special :-)

Related

Is GDB caching debuggee's signal by SIGCHLD?

Came across this doc: https://idea.popcount.org/2012-12-11-linux-process-states/ (a bit old). It says ptrace is handling debugee's signals by receiving SIGCHLD. Is GDB relying on this?
Related, does GDB get notification when signal handler is set to "noprint nostop pass"?
Further, the doc above says, in the case of ptrace, system blocks debuggee when some signal happens, until debugger finishes handling and continues debugee by waitpid(). Is this still the case nowadays?
Thanks in advance!
The answer is "yes" to every single question you posed, except:
and continues debugee by waitpid()
The waitpid doesn't continue debuggee, merely waits for it. The "continue" is done with (surprise!) ptrace(PTRACE_CONT, ...).

Use GDB to Debug SIGTERM

I have searched several questions on stackoverflow about debugging SIGTERM, but have not get the information I needed. Perhaps, I am still new to this issue.
My program terminated with the SIGTERM signal without core dump and I donot know how to track this down. My Question is, what is the general way of debugging this issue in GDB?
Thanks.
Although SIGTERM can be sent by the kernel in a few cases, it's almost always sent by another user process. If you run your program under gdb, then when it receives a SIGTERM it will become paused. You can then get some info about the signal by looking at the $_siginfo structure:
(gdb) print $_siginfo._sifields._kill
$2 = {si_pid = 3926, si_uid = 1001}
This is on Linux. It means that pid 3926 sent the signal, and the userid who sent it is 1001.
My program terminated with the SIGTERM signal without core dump
It is expected that if someone sends your program a SIGTERM, then no core dump is produced.
and I donot know how to track this down.
You need to figure out where that SIGTERM is coming from. Someone sends it your program, and the key question is who.
Usually SIGTERM is sent when either you type Control-C in the terminal in which you started the program (correction, that would send SIGINT, not SIGTERM), or you type kill <pid> in some other terminal.

Signals when debugging

I'm developing an application (a service/daemon, really) on Linux in C++ that needs to interface with a piece of hardware. If my program doesn't release the resources for this peice of hardware cleanly when terminating, then I have to reload the device driver, a process that takes about 10 minutes and for obvious reasons having to wait 10 minutes between each test of the program would be frustrating.
So I have used the sigaction() function to catch a SIGINT (a ctrl-c) so that my program can cleanly shutdown when I'm finished with it. When running the program from the console, this works fine. However, when debugging in Netbeans or Eclipse (I've tried both) things don't work.
In Eclipse, if I hit ctrl-c in the console it provides, it doesn't seem to register that a SIGINT ever occurred
In Eclipse, if I run the program in debug mode and then use kill -SIGINT <pid>, the program just breaks as if it hit a breakpoint
Netbeans actually seems to realise a signal has been sent when I hit ctrl-c in the console, and pops up a dialog asking if I want to forward it to the application. Clicking "Forward and continue" just seems to break the program and the signal is not received by the application. It also says I can configure this stuff in Debug -> Dbx configure, a menu item that doesn't exist
In Netbeans, if I run the program in debug mode and then use kill -SIGINT <pid>, the behaviour is the same as above
I then added a SIGQUIT handler and tried sending that via kill when debugging in Netbeans. This time, no dialog appears and the signal handler is never tripped.
I need some way to cleanly shutdown my app while I'm debugging. Any ideas?
It turns out the problem had nothing to do with Netbeans or Eclipse, but rather gdb.
gdb can be configured to handle signals in a variety of ways. If you run:
gdb
then type:
info signals
You'll get a list of signals and gdb actions on what to do if it receives that signal:
Signal Stop Print Pass to program Description
SIGHUP Yes Yes Yes Hangup
SIGINT Yes Yes No Interrupt
SIGQUIT Yes Yes Yes Quit
SIGILL Yes Yes Yes Illegal instruction
SIGTRAP Yes Yes No Trace/breakpoint trap
etc...
My temporary work around has been to use SIGALRM which gdb defaults to not breaking and sending to the process. However, you can also customise the default gdb settings by creating a .gdbinit file where you can set these
Even this post is old, hope it can help others.
To prevent Eclipse from catching the Ctrl+C, you can configure your gdb using .gbdinit file.
You create a .gdinit with this content
#we want Ctrl+C to be no break, pass to application and printed by the debugger
handle SIGINT nostop
handle SIGINT pass
handle SIGINT print
In your eclipse configuration, you can define where is your .gdbinit file to use in your Debug configuration
Simple solution.. Try using DEBUG macros to handle your situation.
// Register the signal handler to stop service.
#ifdef _DEBUG
signal(SIGKILL, <your signal handler>);
#endif
Also, you may try to clean up your app before exiting.

What is the correct way to force an app to core dump and quit?

I just came across some code which used the kill system call to send a SIGSEGV signal to an app. The rationale behind this was that this would force the app to core dump and quit. This seems so wrong to me, is this normal practice?
SIGQUIT is the correct signal to send to a program if you wish to produce a core dump. kill is the correct command line program to send signals (it is of course poorly named, since not all signals will kill the program).
Note, you should not send random signals to the program, not all of them will produce a core dump. Many of them will be handled by the program itself, either consumed, ignored, or induce other processing. Thus sending a SIGSEGV is wrong.
GCC Says:
http://www.gnu.org/s/libc/manual/html_node/Termination-Signals.html
POSIX/Unix Says:
http://pubs.opengroup.org/onlinepubs/009695399/basedefs/signal.h.html
Yes. kill is somewhat misnamed -- it can send any signal. There are many uses for kill which don't result in the process being killed at all!
If you want to make an application dump it's core from another program, pretty much the only way to do it is via a signal. SEGV would be fine for this. Alternatively you can hook a debugger up to the program and freeze it and view it's registers and such without killing it.
If you want to dump a core from within an application there are nicer ways to do it, like via an assert().
So, no, it's not particularly wrong to send a SEGV to a program. You could also send things like SIGILL for illegal instruction, or a divide by zero signal. It's all fine.
The way to do it in Unix/Linux is to call abort() which will send SIGABORT to current process. The other option is raise() where you can specify what signal you want to send to current process.
Richard Stevens (_Advanced Programming in the UNIX Environment) wrote:
The generation of core is an implementation features of most Unix. It is not part of POSIX.1.
He lists 12 signals whose default action is to terminate with a core (ANSI: SIGABRT, SIGFPE, SIGILL, SIGSEGV, POSIX: SIGQUIT, Other: SIGBUS, SIGEMT, SIGIOT, SIGSYS, SIGTRAP, SIGXCPU, SIGXFSZ), all of them are overwritable (the two signals which aren't overwritable are SIGKILL and SIGSTOP).
I've never seen a way to generate a core which isn't the use of a default signal handler.
So if your goal is to generate a core and stop, the best is to choose a signal whose default handler does the job (SIGSEGV does the job), reset the default handler for the signal if you are using it and then use kill.

Stopping the inferior process in GDB WITHOUT a signal?

Is there a way to stop the inferior without using Ctrl+C (or an equivalent signal sent from another process?) I'm using a windows platform and am managing GDB from another process, so with no notion of signals, it seems that there isn't a good way to break execution of my program when it's free running without any breakpoints.
EDIT FOR CLARITY:
There are 2 processes involved here. There's process A, which is the parent of GDB. GDB is managing a process, but it's on a remote host, and we'll call that process C.
When I tell GDB to "run" it kicks off process C on the remote host and blocks either until a breakpoint is hit, process C encounters an error or a fatal signal, or GDB itself receives an interrupt signal. If working interactively, you would simply press CTRL+C at the GDB command console, which GDB interprets as a SIGINT (somehow), triggering GDB to halt process C. Since I'm actually managing GDB with process A (and not dealing with it interactively at the shell) I can't very well press Ctrl+C, and since windows has no native notion of "Signals" like you have in UNIX, I can't figure out how to interrupt GDB when it's blocking waiting for process C to interrupt or hit a breakpoint.
Did you try to take a look at the remote control protocols? for instance, EMACS uses MI to control GDB, you should check how/if they offer such a ctrl-C mechanism, and how they implement it.
EDIT: it seems to be -exec-interrupt which interrupts the execution.