Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to interpret a GDB backtrace?

0x004069f1 in Space::setPosition (this=0x77733cee, x=-65, y=-49) at space.h:44    
0x00402679 in Checkers::make_move (this=0x28cbb8, move=...) at checkers.cc:351
0x00403fd2 in main_savitch_14::game::make_computer_move (this=0x28cbb8) at game.cc:153
0x00403b70 in main_savitch_14::game::play (this=0x28cbb8) at game.cc:33
0x004015fb in _fu0___ZSt4cout () at checkers.cc:96
0x004042a7 in main () at main.cc:34

Hello, I am coding a game for a class and I am running into a segfault. The checker pieces are held in a two dimensional array, so the offending bit appears to be invalid x/y for the array. The moves are passed as strings, which are converted to integers, thus for the x and y were somehow ASCII NULL. I noticed that in the function call make_move it says move=...

Why does it say move=...? Also, any other quick tips of solving a segfault? I am kind of new to GDB.

like image 811
user1405177 Avatar asked Jun 02 '12 02:06

user1405177


People also ask

What does backtrace do in gdb?

A backtrace is a summary of how your program got where it is. It shows one line per frame, for many frames, starting with the currently executing frame (frame zero), followed by its caller (frame one), and on up the stack. Print a backtrace of the entire stack: one line per frame for all frames in the stack.

How do you find the backtrace?

A backtrace is a list of the function calls that are currently active in a thread. The usual way to inspect a backtrace of a program is to use an external debugger such as gdb. However, sometimes it is useful to obtain a backtrace programmatically from within a program, e.g., for the purposes of logging or diagnostics.

How do you do a full backtrace?

To print a backtrace of the entire stack, use the backtrace command, or its alias bt . This command will print one line per frame for frames in the stack. By default, all stack frames are printed. You can stop the backtrace at any time by typing the system interrupt character, normally Ctrl-c .

How do I use backtrace in Linux?

A backtrace is the series of currently active function calls for the program. Each item in the array pointed to by buffer is of type void *, and is the return address from the corresponding stack frame. The size argument specifies the maximum number of addresses that can be stored in buffer.


2 Answers

Basically, the backtrace is trace of the calls that lead to the crash. In this case:

game::play called game::make_computer_move which called Checkers::make_move which called Space::setPosition which crashed in line 44 in file space.h.

Taking a look at this backtrace, it looks like you passed -65 and -49 to Space::setPosition, which if they happen to be invalid coordinates (sure look suspicious to me being negative and all). Then you should look in the calling functions to see why they have the values that they do and correct them.

I would suggest using assert liberally in the code to enforce contracts, pretty much any time you can say "this parameter or variable should only have values which meet certain criteria", then you should assert that it is the case.

A common example is if I have a function which takes a pointer (or more likely smart pointer) which is not allowed to be NULL. I'll have the first line of the function assert(p);. If a NULL pointer is ever passed, I know right away and can investigate.

Finally, run the application in gdb, when it crashes. Type up to inspect the calling stack frame and see what the variables looked like: (you can usually write things like print x in the console). likewise, down will move down the call stack if you need to as well.

As for SEGFAULT, I would recommend runnning the application in valgrind. If you compile with debugging information -g, then it often can tell you the line of code that is causing the error (and can even catch errors that for unfortunate reasons don't crash right away).

like image 103
Evan Teran Avatar answered Oct 27 '22 06:10

Evan Teran


I am not allowed to comment, but just wanted to reply for anyone looking more recently on the issue trying to find where the variables become (-65, -49). If you are getting a segfault you can get a core dump. Here is a pretty good source for making sure you can set up gdb to get a core dump. Then you can open your core file with gdb:

gdb -c myCoreFile

Then set a breakpoint on your function call you'd like to step into:

b MyClass::myFunctionCall

Then step through with next or step to maneuver through lines of code:

step

or

next

When you are at a place in your code that you'd like to evaluate a variable you can print it:

p myVariable 

or you can print all arguments:

info args

I hope this helps someone else looking to debug!

like image 27
user2758501 Avatar answered Oct 27 '22 05:10

user2758501