I want to debug my C++ python extension library. Currently the library is throwing an exception and to figure out where, I want to use gdb. The problem is that gdb is not catching the exception stack. I did as following:
$ gdb python3
(gdb) run script.py
UserWarning: An exception occurred: sort_index(): detected NaN
And when I try to use backtrace:
(gdb) backtrace
No stack.
I know that such backtrace is possible because I already did that before, probably I am missing something. The library is being compiled with debug mode.
A Python exception will not cause GDB to stop—it knows only to stop on signals, not “normal”, private error handling. It might be possible to set a breakpoint on the Python functions that set the Python error indicator, but they might be inlined (or be macros).
Conveniently, you can set a “breakpoint” on the magic function that throws C++ exceptions—it’s called a catchpoint and is set with the odd-looking catch throw. (This will be very noisy if (caught) exceptions are more common than they ought to be in your code!)
Finally, note that you can’t ever let a C++ exception escape into Python—even to catch it in yet a larger C++ context, because Python doesn’t know how to clean up in that circumstance.
Related
I have a multi threaded program written in c++ running on ARM.
I have enabled global core dump of applications by running:
echo "/var/log/core.%e.%t" > /proc/sys/kernel/core_pattern
ulimit -c unlimited
An exception is thrown in the program which isn't being caught.
I open the core dump that was generated using eclipse.
I expect to see the code that throw the exception in the callstack.
But I can't see it.
The rest of the callstack for the other threads look ok
I tried to manually change the $SP of the first line in the callstack to the address defined in the verbose termiate line: 0xb6eba0d8 but that cause the callstack to only show the syscall line
How can I see more lines in this thread's stack?
There were two problems:
The stack was unwound. Until GCC 8 - When using std::thread, libstdc++'s function that calls the user's thread function contains a try/catch all statement. Using pthread instead solves this issue. See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55917 for details
I was using libstdc++ without debug symbols while trying to debug. The function that was called by the thread was compiled with debug symbols but that wasn't enough. I used the file command to see that the library inside /usr/lib didn't have debug symbols, so I used the libraries from my Linaro distribution installation which did have.
My application crashed due to uncaught exception (my c++ code throws uncaught exception under certain condition). I am trying to gdb the corefile. The binary library is "not striped". And the stack trace shows the function (my code) from which an uncaught exception is thrown, but when I try to print the function arguments, I always get "no symbol xxx in current context". info args also return "No symbol table info available".
Can anyone shed a light why ? is it due to the uncaught exception which unwind/corrupts the stack ?
Thanks,
Frank
Your binary lacks debug info.
If you built it with gcc, and want to debug the core you already have (if e.g. it's hard to reproduce the crash), you may be able to recover from this by rebuilding the binary with exactly the same source and command lines, adding -g to compile and link commands. (Note: you must use the same compile lines; replacing -O2 with -g wouldn't do.)
If the crash is not hard to reproduce, simply rebuild the binary with -g -O0, run it under GDB, and enjoy "easy" debugging.
The binary library is "not striped".
This doesn't mean what you think it means. Not stripped means that the symbol table is still present in the binary.
GDB will read this symbol table, and use it to map ranges of addresses to function names.
But to recover names and values of local variables and parameters, you must compile with debug info (which is what -g flag does for most compilers).
Is there any gcc option I can set that will give me the line number of the segmentation fault?
I know I can:
Debug line by line
Put printfs in the code to narrow down.
Edits:
bt / where on gdb give No stack.
Helpful suggestion
I don't know of a gcc option, but you should be able to run the application with gdb and then when it crashes, type where to take a look at the stack when it exited, which should get you close.
$ gdb blah
(gdb) run
(gdb) where
Edit for completeness:
You should also make sure to build the application with debug flags on using the -g gcc option to include line numbers in the executable.
Another option is to use the bt (backtrace) command.
Here's a complete shell/gdb session
$ gcc -ggdb myproj.c
$ gdb a.out
gdb> run --some-option=foo --other-option=bar
(gdb will say your program hit a segfault)
gdb> bt
(gdb prints a stack trace)
gdb> q
[are you sure, your program is still running]? y
$ emacs myproj.c # heh, I know what the error is now...
Happy hacking :-)
You can get gcc to print you a stacktrace when your program gets a SEGV signal, similar to how Java and other friendlier languages handle null pointer exceptions. See my answer here for more details:
how to generate a stacktace when my C++ app crashes ( using gcc compiler )
The nice thing about this is you can just leave it in your code; you don't need to run things through gdb to get the nice debug output.
If you compile with -g and follow the instructions there, you can use a command-line tool like addr2line to get file/line information from the output.
Run it under valgrind.
you also need to build with debug flags on -g
You can also open the core dump with gdb (you need -g though).
If all the preceding suggestions to compile with debugging (-g) and run under a debugger (gdb, run, bt) are not working for you, then:
Elementary: Maybe you're not running under the debugger, you're just trying to analyze the postmortem core dump. (If you start a debug session, but don't run the program, or if it exits, then when you ask for a backtrace, gdb will say "No stack" -- because there's no running program at all. Don't forget to type "run".) If it segfaulted, don't forget to add the third argument (core) when you run gdb, otherwise you start in the same state, not attached to any particular process or memory image.
Difficult: If your program is/was really running but your gdb is saying "No stack" perhaps your stack pointer is badly smashed. In which case, you may be a buffer overflow problem somewhere, severe enough to mash your runtime state entirely. GCC 4.1 supports the ProPolice "Stack Smashing Protector" that is enabled with -fstack-protector-all. It can be added to GCC 3.x with a patch.
There is no method for GCC to provide this information, you'll have to rely on an external program like GDB.
GDB can give you the line where a crash occurred with the "bt" (short for "backtrace") command after the program has seg faulted. This will give you not only the line of the crash, but the whole stack of the program (so you can see what called the function where the crash happened).
The No stack problem seems to happen when the program exit successfully.
For the record, I had this problem because I had forgotten a return in my code, which made my program exit with failure code.
When debugging a C++ program with the GNU GDB debugger, I can step over the next line of code with the GDB command:
next
However, when an exception is thrown within that next line, like e.g.
throw SomeException();
then GDB continues to run until the next breakpoint instead of stopping within the first line of the catch block.
Is this a bug within GDB, or am I just using the wrong command?
I'm using GDB version 7.7 on MinGW32 / Windows.
On Linux this works properly. In particular there is a special debugging marker (either a function or an "SDT probe", depending on how things were built) in the low-level unwinding code that is used when an exception is thrown. GDB puts a breakpoint at this spot. When this breakpoint is hit, GDB examines the target stack frame of the throw and, if it is above the nexting frame, puts a temporary breakpoint at the target of the throw.
This required some changes in GDB, but also some changes in the C++ runtime in order to inform GDB about throws. As far as I know, nobody has ever done the work to port this code to MinGW. Maybe it could be done by modifying the appropriate unwind-mumble.c file in the GCC sources.
I have a large C++ function which uses OpenCV library and running on Windows with cygwin g++ compiler. At the end it gives Aborted(core dumped) but the function runs completely before that. I have also tried to put the print statement in the end of the function. That also gets printed. So I think there is no logical bug in code which will generate the fault.
Please explain.
I am also using assert statements.But the aborted error is not due to assert statement. It does not say that assertion failed. It comes at end only without any message.
Also the file is a part of a large project so I cannot post the code also.
gdb results:
Program received signal SIGABRT, Aborted.
0x7c90e514 in ntdll!LdrAccessResource () from /c/WINDOWS/system32/ntdll.dll
It looks like a memory fault (write to freed memory, double-free, stack overflow,...). When the code can be compiled and run under Linux you can use valgrind to see if there are memory issues. Also you can try to disable parts of the application until the problem disappears, to get a clue where the error happens. But this method can also give false positives, since memory related bugs can cause modules to fail which are not the cause of the error. Also you can run the program in gdb. But also here the position the debugger points to may not be the position where the error happened.
You don't give us much to go on. However, this looks like you are running into some problem when freeing resources. Maybe a heap corruption. Have you tried running it under gdb and then looking where it crashes? Also, check if all your new/delete calls match.
Load the core dump together with the binary into gdb to get an idea at which location the problem list. Command line is:
gdb <path to the binary> <path to the core file>
For more details on gdb see GDB: The GNU Project Debugger.
Run it through AppVerifier and cdb.
E.g.
cdb -xd sov -xd av -xd ch <program> <args>