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.
Related
got some big real time project to deal with (multiple processes (IPCs), multi Everything in short).
My working on process is started as service on Linux. I have the root access.
Here is the problem:
I'm trying to attach to a running proc, tried starting it through/with gdb but the result is the same: it stops the executable once I "touched" it with gdb or sometimes it throws:
Program received signal SIGUSR1, User defined signal 1. [Switching to Thread 0x7f9fe869f700 (LWP 2638)]
of course from there nothing can be done.
Tried:
handle all nostop
attach to launched as service (daemon) or launched as regular proc
started from gdb
thought maybe forking/multi-threaded problem - implemented in the very beginning sleep for 10 seconds - attached to it with "continue"
Guys, all I want it is to debug, hit the breakpoints, etc.
Please help! Share ideas.
Editing actual commands:
1) gdb attach myProcId. Then after reading symbols, I hit "c" which results:
Program received signal SIGUSR1, User defined signal 1.
[Switching to Thread 0x7f9fe869f700 (LWP 2638)]
0x00007f9fec09bf73 in select () from /lib64/libc.so.6
2) If I make the first line 10 seconds sleep in the code, attaching to the process, hit "c", result: it runs, shows info threads, backtrace of main, but never hits the breakpoint (for sure the code runs there - I get logs and different behaviour if I change code there), meaning the process is stuck.
3) All other combinations like gdb path/to/my/proc args list, then start. Where arg list played with different related options gdb gives us.
Maybe worth to mention: process network packets related, timers driven also.
But for me the important thing is a current snapshot on break, i don't care what will happen to the system after timers expired.
Since you mentioned that you are debugging a multiprocessing program, I think the underlying program you have is to set the breakpoint in the correct subprocess.
Try break fork and set follow-fork-mode child/parent. What you want to achieve is have gdb attached to the process that is running the code you want to debug.
Refer to this link.
Another thought is to generate a crash, since you can compile the programe. For example add a int i = *(int*)NULL and that will generate a core dump. You can then debug the core dump with gdb <program> <core dump>. You can refer to this page for how to configure core dump.
I've made sure to build my D program with the -g flag (add symbolic debug info) and it looks like I can set simple LOC breakpoints in both GDB and LLDB like this: b SomeModule.d:42 - the debugger replies with a memory address for the new breakpoint.
However when I run the program from the debugger, it gets stopped somewhere completely different than SomeModule.d:42. What am I missing?
D is a safe by default, garbage-collected by default, language.
So in addition to your own breakpoints, programs will often be interrupted by the Garbage Collector Signals (SIGUSR1, SIGUSR2).
In GDB, this can be prevented by:
(gdb) handle SIGUSR1 nostop noprint
Signal Stop Print Pass to program Description
SIGUSR1 No No Yes User defined signal 1
(gdb) handle SIGUSR2 nostop noprint
Signal Stop Print Pass to program Description
SIGUSR2 No No Yes User defined signal 2
Even better, automate by putting the above 2 commands in a file and start GDB with -x gdb_command_file.
The corresponding LLDB-ese sounds different:
(lldb) process handle --stop false --notify false SIGUSR1 SIGUSR2
I'm not sure it's possible to automate it similarly with LLDB alone.
If I run a program under gdb, how do I break at an arbitrary point? Pressing Ctrl+C kills the program. Ctrl+Break does nothing.
I can't enter gdb commands because my program is itself sitting in a REPL loop so anything I enter goes to my program, not to gdb.
My program uses linenoise to implement the REPL; I assume that this is hiding Ctrl+C, etc., from gdb.
Ctrl+\ results in a 001C square blob thingy in my program, rather than SIGUSR1.
Pressing Ctrl+C kills the program.
That is not the default GDB behavior.
Did you set handle SIGINT nostop pass?
You can examine current signal disposition with:
(gdb) handle SIGINT
Signal Stop Print Pass to program Description
SIGINT Yes Yes No Interrupt
Update:
My program is using linenoise for console input. I assume that it has done something to Ctrl+C
If your program is modifying terminal settings, you are going to have a very bad time debugging it from the same terminal.
For example, suppose the program sets no echo, and then hits a breakpoint. I think you would get a (gdb) prompt, but would not see any commands you are typing into GDB.
It seems that you would be much better off debugging this program from a different terminal. Use gdb -p $PID to attach to it from "outside".
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 :-)
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.