7

When debugging a program that fails an assert I can't get the call stack in gdb. I'm using g++4.8 and gdb from Homebrew on Mavericks.

/usr/local/bin/g++-4.8 --version 
g++-4.8 (GCC) 4.8.2
/usr/local/bin/gdb --version
GNU gdb (GDB) 7.6.2

Here is the smallest test to reconstruct the problem

//test.cpp
#include <iostream>
#include <cassert>
int main()
{
  int i = 42;
  std::cout << "Hello World!" << i << std::endl;
  assert(0); // this also happens with abort() which assert(0) winds up calling
}

Compiling and with

/usr/local/bin/g++-4.8 -g -c test.cpp -o test.o
/usr/local/bin/g++-4.8 -g test.o -o test       
/usr/local/bin/gdb test                        
(gdb) r
Starting program: /Users/pmelsted/tmp/test/test 
Hello World!42
Assertion failed: (0), function main, file test.cpp, line 7.

Program received signal SIGABRT, Aborted.
0x00007fff9447d866 in ?? ()
(gdb) where
#0  0x00007fff9447d866 in ?? ()
#1  0x00007fff9229835c in ?? ()
#2  0x0000000000000000 in ?? ()
Pall Melsted
  • 358
  • 1
  • 12
  • I followed your steps on a different OS (Ubuntu 12.04, 32-bits), could not reproduce the problem; pretty normal stack dump. I must admit that was an older version of g++ (4.6.3) and gdb (7.4-2012.04). Just an idea: have you tried option `-ggdb`? – Ruud Helderman Jan 05 '14 at 19:31
  • The -ggdb makes no difference here. My feeling is that this is mac related as anything this simple would not make it through testing on linux. – Pall Melsted Jan 05 '14 at 20:36
  • 1
    Please check if your executable contains debug info, by following the instructions in this thread: http://stackoverflow.com/questions/8390881/gdb-doesnt-show-function-names Turn off all optimizations and try experimenting with different debug options and formats (`-gdwarf-2`, `-gstabs`, `-gsplit-dwarf` etc); see http://gcc.gnu.org/onlinedocs/libstdc++/manual/debug.html – Ruud Helderman Jan 06 '14 at 20:24
  • None of these options make any difference. The nm program on mac does not have --debug-sym options. When debugging I can step through and see source code just fine, even print values of variables, it's just the assert that fails. – Pall Melsted Jan 06 '14 at 22:57
  • 1
    Does this locally-installed gcc come with its own libstdc++.so, or does it use`the one supplied with the OS? Is that library compiled with debugging information? – Mark Plotnick Jan 08 '14 at 18:35
  • This gcc does not have its own libstdc++.so. I also tried replacing this with vanilla c code and the problem persists. – Pall Melsted Jan 08 '14 at 21:21

2 Answers2

7

It seems gdb on MacOS don't display call stack correctly (or call stack is corrupted after assert() function call) for 64-bit programs. Here is the program slightly modified:

//test.cpp
#include <iostream>
#include <cassert>

int foo() {
        assert(0);
}
int bar() {
        return foo();
}
int main()
{
        int i = 42;
        std::cout << "Hello World!" << i << std::endl;
        return bar();
}

I have compiled it invoking the g++ -g 15.cpp -m32 command and have ran it under ggdb. The bt full command shows call stack as the following:

(gdb) bt full
#0  0x9843f952 in ?? ()
No symbol table info available.
#1  0x96193340 in ?? ()
No symbol table info available.
#2  0x9615e43e in ?? ()
No symbol table info available.
#3  0x0000216f in foo () at 15.cpp:6
No locals.
#4  0x0000217b in bar () at 15.cpp:9
No locals.
#5  0x000021e4 in main () at 15.cpp:15
        i = 42
(gdb) quit

So, all debug symbols are displayed correctly, first 3 function addresses are corrected and have no name because my libgcc is in release mode.

If I don't use -m32 key during compilation, the call stack is as follows:

(gdb) bt full
#0  0x00007fff8b442866 in ?? ()
No symbol table info available.
#1  0x00007fff8c64735c in ?? ()
No symbol table info available.
#2  0x0000000000000000 in ?? ()
No symbol table info available.

That is definitely wrong call stack, #2 frame function address is 0x0. So, the root cause is gdb can't display call stack correctly for 64-bit applications.

vershov
  • 928
  • 4
  • 6
  • 3
    Knowing the root cause is great, thanks! Does anyone know if there's a way to fix it? I'd rather not do all my debugging in 32bit. – katyhuff May 27 '14 at 23:52
1

I found a workaround for the problem. Just set the breakpoint to abort() function in gdb:

b abort

then when assert is called it will halt at the breakpoint and at this moment one can see the call stack with bt.

igagis
  • 1,959
  • 1
  • 17
  • 27