how to use gdb to catch "exit" of a program - gdb

I am debugging a rather complex project, I have its source code, currently I need to know the stack trace when daemon exits in certain case, but it is very time consuming to go through the whole code, I want to use gdb to help on this, but commands like "catch exit" won't work, it told me that "Catch of exit not yet implemented", so can anyone tell me how to use gdb to catch the exit event of a daemon? Thank you.

(gdb) catch syscall 60
Catchpoint 3 (syscall 'exit' [60])
(gdb) catch syscall 231
Catchpoint 4 (syscall 'exit_group' [231])

I think just setting breakpoints for exit, _exit, and abort should get you pretty far.

Related

AddressSanitizer kills GDB state, even when following Sanitizer Github advice

I have a double-free bug. I am able to reproduce it using a debug build with Address Sanitizer (AS) detects but when I run under GDB, AS kills the GDB session.
I found this Address Sanitizer page with instructions how to keep GDB:
https://github.com/google/sanitizers/wiki/AddressSanitizerAndDebugger
but when I do:
(gdb) break __asan::ReportGenericError
at the beginning of the session, the GDB state still disappears after the problem is detected:
(gdb) bt
No stack.
the GDB state still disappears after the problem is detected
There are several possible reasons for this:
Somehow you didn't set the breakpoint correctly
It's actually a child process that is dying
Somehow the thread in which the error is detected is not attached by GDB.
To eliminate 1, use catch syscall exit_group (and possibly also catch syscall exit) -- this way GDB is sure to stop before the process disappears.
For 2, AddressSanitizer message should indicate the thread id in which the error is detected, and that id should match one of the threads in GDB info thread output.
For 3, we'd need to understand more about how that thread was created.

Getting a backtrace for inferior process at its exit

I have a multi-threaded C++ program running on CentOS 5 exhibiting an Exit code 6 which is undesired:
[Inferior 1 (process 22898) exited with code 06]
It should be exiting with 00. I need to debug this issue using GDB. This program is heavily multi-threaded and I'm not sure what code is running on this particular thread.
What's the best (easiest and most effective) way to catch the exit in the inferior process and get a backtrace so I can see where the thread is exiting?
I have tried setting set detach-on-fork off but it just ends up hanging the program.
What's the best way to catch the exit in the inferior process and get a backtrace so I can see where the thread is exiting?
(gdb) catch syscall exit_group

GDB backtrace without stopping

I am trying to let my program run continously with GDB.
Currently I have a bash script which starts GDB with my program and when it crashes it prints the backtrace and starts GDB again (endless loop).
Now I added a signal handler for my program which kills specific threads when the handler gets a signal from them. Now I can achieve that GDB does not stop by doing this:
handle SIGSEGV nostop
But this leads me to the problem that I do not get a GDB backtrace which I would like to print automatically without stopping the program (or at least continuing automatically).
Any help would be appreciated!
Continue to use handle to suppress ordinary stops from SEGV. Then set a catchpoint that does what you want:
(gdb) catch signal SIGSEGV
(gdb) commands
> silent # this bit is optional
> bt
> continue
> end
This will print a backtrace on SIGSEGV but not otherwise interfere with normal operation. You may also want handle SIGSEGV noprint.

Generating a stack trace on exit in gdb

My C++ application is giving me some strange output but it runs to completion, I'd like to examine the stack trace but since it isn't segfaulting it is harder to pinpoint where it is. I've tried setting break points on exit, _exit, and abort, but when I call the stack I get something like this
#0 0x00002aaaab1a7620 in exit () from /lib64/libc.so.6
#1 0x000000000041f19e in main ()
This is probably because my application has a perl front end wrapped with sig, is there another way to generate a stack upon completion?
That's what the stack trace should look like. main calls exit at the end and you print the stack trace inside exit. You cannot find where something happens with a stack trace. Once you find where something happens, you can get the stack trace there and find out how the execution got there.
Whatever output you're looking for happened before exit and that function has already returned by the time you get the stack trace. So, you need to put your break point before the output happens. Then you can go over the code line by line to find out which line does the output.
did you build it in debug?
add a breakpoint with "b function_name"
press c to continue
type bt to print the backtrace

How does gdb attach to multi-threaded process?

I will try to be as specific as I can, but so far I have worded this problem so poorly that Google failed to return any useful results (hence my question here).
I am attaching gdb to a multi-threaded c++ server process. All I can say is that strange things have been happening while trying to do the usual set-breakpoint-break-investigate.
First, while waiting for the breakpoint to be hit (in 'Continuing' mode), I suddenly got back the (gdb) prompt with the message:
Continuing.
[Thread 0x54d5b940 (LWP 28503) exited]
[New Thread 0x54d5b940 (LWP 28726)]
Cannot get thread event message: debugger service failed
Second, also while waiting for the breakpoint to be hit, I'm suddenly told the program has received SIGSEGV and - back to the (gdb) prompt - backtrace tells me the segfault happened in pthread_cancel(). Note the process under investigation does not normally segfault.
I clearly lack enough information about how gdb works to even begin guessing what is happening. Am I doing anything wrong? The steps I take are the same each time:
gdb attach
break 'MyFunction()'
continue
Thoughts? Thanks.
I fought with similar gdb issues for a while. My case was having lots of threads spawned that executed few functions and then exited.
It appears if a thread exits too fast and there's lots of these happening sometimes gdb cannot keep up and when it fails, it fails with style as in crashes :) I think it tries to attach to a thread that is already done as per the error message.
I see this as an issue in gdb 6.5 to 7.6 and still happening. Did not try with older versions.
My advice is look for this use case or similar. Once I changed my design to have a thread serving a queue of requests gdb works flawlessly.
Design wise is healthier to have already created threads that digest actions than always spawning new threads.
Still same code debugs without a problem on Visual Studio so I do have to say that is a small disappointment to me with regards to gdb.
I use Eclipse and looking at the GDB traces (usually enabled by default) will give you a better hint of where GDB fails. One of the buttons on the console shows you the GDB trace.