setting a gdb exit breakpoint not working?

gdb, linux, unix

Solution

There are two common reasons for `_exit` breakpoint to "miss" -- either `GDB` didn't set the breakpoint in the right place, or the program performs (a moral equivalent of) `syscall(SYS_exit, ...)`

What do `info break` and `disassemble _exit` say?

You might be able to convince `GDB` to set the breakpoint correctly with `break *&_exit`. Alternatively, `GDB-7.0` supports `catch syscall`. Something like this should work (assuming `Linux/x86_64`; note that on `ix86` the numbers will be different) regardless of how the program exits:

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

Catchpoint 4 (call to syscall 'exit_group'), 0x00007ffff7912f3d in _exit () from /lib/libc.so.6

Update: Your comment indicates that _exit breakpoint is set correctly, so it's likely that your process just doesn't execute `_exit`.

That leaves `syscall(SYS_exit, ...)` and one other possibility (which I missed before): all threads executing `pthread_exit`. You might want to set a breakpoint on `pthread_exit` as well (and execute `info thread` each time you hit it -- the last thread to do `pthread_exit` will cause the process to terminate).

Edit:

Also worth noting that you can use mnemonic names, rather than syscall numbers. You can also simultaneously add multiple syscalls to the catch list like so:

(gdb) catch syscall exit exit_group
Catchpoint 2 (syscalls 'exit' [1] 'exit_group' [252])

Problem

I've set breakpoints on exit and _exit and my program (multithreaded app, running on linux 2.6.16.46-0.12 sles10), is somehow still exiting in a way I can't locate ``` (gdb) c ... [New Thread 47513671297344 (LWP 15279)] [New Thread 47513667103040 (LWP 15280)] [New Thread 47513662908736 (LWP 15281)] Program exited with code 0177. (gdb) ``` the exit functions reside in libc so there's no deferred load shared library issues. Anybody know of some other mysterious trigger for exit that can't be caught? EDIT: the problem is now academic only. I tried binary search debugging, backing out a subset of my changes (the problem went away). After I applied them again in sequence, I can no longer repro the problem, even with things restored to the original state. EDIT2: I found one reason for this sort of error recently, which may have been the original source for this problem. For historical reasons our product uses the evil linker flag -Bsymbolic. Among the side effects of this is that when a symbol is undefined but called, the GLIBC runtime linker will bomb in exactly this way, and you see it in the debugger as a process exited with 0177. When the runtime linker aborts this way, I'd guess it makes the syscall to _exit directly (rather than using the C runtime library exit() or _exit()). That would be consistent with the fact that I was unable to catch this with an the exit breakpoints in the debugger.

Original source