Signals when debugging
Asked Answered
L

3

11

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?

Licastro answered 26/5, 2011 at 9:36 Comment(0)
L
12

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

Licastro answered 27/6, 2011 at 11:12 Comment(3)
So, is it possible to make gdb handle SIGINT sensibly? What would be the .gdbinit content to do so?Ceasar
This has been a lifesaver for me, I really love in javascript how there is the "debugger;" statement, and I implemented a version in C++, essentially if its building in debug mode, send itself a SIGTRAPPanpipe
for lldb you can type: pro handPolaroid
S
8

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

Eclipse capture

Scyphozoan answered 22/1, 2015 at 8:50 Comment(0)
L
2

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.

Lilienthal answered 26/5, 2011 at 11:19 Comment(4)
Thanks for that, but how would I choose when to terminate the application? If I just put this at the end of my main() block or similar the service would start and stop immediatelyLicastro
Explain 'how would I choose when to terminate the application?' :)Lilienthal
As I said, this will be a service or a daemon. Sometimes I will need to test it for only a few seconds, other times I will need to run more extensive tests. The point is, I can't just say Sleep for 15 seconds and then send a signal - I need to be able to terminate the program at a time of my choosing.Licastro
Ok... as you mention it is a daemon/service you will be continuously running the main thread (or looping). If this is right then you can spawn a signal to your service to 'free the resources and exit'. In such cases you can also avoid "Sleep for 15 seconds and then send a signal". This a again, just my suggestion. Rework on your design considering required strategies for your daemon. :)Lilienthal

© 2022 - 2024 — McMap. All rights reserved.