tags:

views:

407

answers:

3

GDB seems to always just work for C programs, but for C++ I often get these cryptic stacks:

(gdb) bt
#0  0x08055fa4 in std::runtime_error::what ()
#1  0x080576c8 in std::runtime_error::what ()
#2  0x08057dda in std::runtime_error::what ()
#3  0x080580d2 in std::runtime_error::what ()
#4  0x08058662 in std::runtime_error::what ()
#5  0x08058725 in std::runtime_error::what ()
#6  0x0806ef7a in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string<char*> ()
#7  0x00c0adec in __libc_start_main () from /lib/libc.so.6
#8  0x0804d011 in std::runtime_error::what ()

Which on the surface offer absolutely no clues as to where the problem occurred. Is there anyway to get more information out of such a core file - or make the program dump something more useful?

+2  A: 

I use GDB all the time for C++, and usually have no problem with stack backtraces, providing of course, that the stack hasn't been smashed by some buffer overflow.

There is nothing intrinsically different about a stack backtrace in a C++ program versus a C program that should make it more difficult for you to interpret the backtrace. Are you sure that:

A) your program is not smashing the stack somehow?
B) you are compiling with the -g flag?

Charles Salvia
+5  A: 

It's unlikely that the text for std::runtime_error::what() actually covers a range from 0x0804d011 through 0x08058725 as suggested by the backtrace. That would be more than 45KB of code.

It's more likely that the symbol lookup code that is trying to resolve 0x08055fa4, 0x080576c8, etc. is simply locating std::runtime_error::what() as the last usable symbol prior to those addresses, which is often the result of stripping the executable (as you have done by passing -s switch to the linker).

I'd focus on stack frame #6. Since this is a ctor for a fairly straightforward class, my SWAG would be that you've passed in a NULL pointer or a pointer to a non-NULL terminated string.

EDIT: Note that if you simply rebuild the executable from exactly the same sources without the -s switch, you will get a much more usable stack from GDB, using the core file you already have. There is no need to wait for the newly-built executable to dump core again.

David Joyner
A: 

First, make sure you've set -pg -ggdb compiler flags:

g++ -pg -ggdb prog.cpp -o prog

The first one generates profiling information for gprof (you may need it), and the second one includes debugging information in executables.

To examine the core file, use this:

gdb -quiet -se=prog -c prog.core

This should always give enough information to troubleshoot core dumps :)
Cheers!

o_O Tync