Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

missing call stack frame with assert for gdb 7.6 on mac

Tags:

c++

macos

gdb

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 ?? ()
like image 798
Pall Melsted Avatar asked Jan 03 '14 17:01

Pall Melsted


People also ask

How to navigate the call stack in gdb?

A common example of when we would need to navigate the call stack within GDB is if execution stops within library code. We can use, the where, up and frame commands to inspect variables within code that we wrote. It is assumed that you have the knowledge introduced in the Basic Use, Breakpoints, Viewing Data and Execution modules.

What are stack frames in C++?

Stack frames are regions of memory allocated on the stack to hold the local variables of functions each time they are called. When one function calls another, a new stack frame is allocated and placed on top of the current function’s stack frame. When a function returns, its stack frame is de-allocated.

How to view and traverse the function call stack?

Able to view and traverse the function call stack using the where, up, down and frame commands. In order to debug programs with functions (i.e. most programs), it is helpful to inspect the variables of all functions in the current call stack, i.e. the functions called to get to the current point in the program.


2 Answers

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.

like image 120
vershov Avatar answered Nov 13 '22 07:11

vershov


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.

like image 24
igagis Avatar answered Nov 13 '22 07:11

igagis