![]() |
Chapter 6 | ![]() |
(gdb) backtrace #0  0x80483a6 in main (argc=1, argv=0xbffffd14) at gdbex1.c:7 (gdb) |
Well, this seems to be a rather uncomplicated stack - it's only 1 level deep. Not much to look at there, so I'm going to use a more complicated example. I'm going to add a call to strcmp with a NULL pointer in the function do_date() from the CircleMUD codebase. This will give us a more detailed backtrace, and will let us see what a 'real' program looks like. Note that I've abbreviated backtrace as 'bt'. Many of the commands in gdb have shortcuts, and after a while, it's a habit to type that instead. In anycase though, here's our output:
Program received signal SIGSEGV, Segmentation fault. 0x8063322 in do_date (ch=0x82ab598, argument=0xbffff94c "", cmd=52, subcmd=0)     at act.wizard.c:1564 1564       strcmp(NULL,NULL); (gdb) bt #0  0x8063322 in do_date (ch=0x82ab598, argument=0xbffff94c "", cmd=52,      subcmd=0) at act.wizard.c:1564 #1  0x807d12a in command_interpreter (ch=0x82ab598, argument=0xbffff948      "date") at interpreter.c:644 #2 0x806d83b in game_loop (mother_desc=6) at comm.c:720 #3 0x806cef8 in init_game (port=4000) at comm.c:353 #4 0x806ce75 in main (argc=3, argv=0xbffffcd4) at comm.c:317 (gdb) |
This is a bit more complex, but it is more like what you're going to see on a day to day basis. Here we see 5 different frames, and as you can see, each corresponds to a function call; do_date(), command_interpreter(), game_loop(),init_game(), and of course, main(). As we said a few times before, each frame in the stack has it's own seperate variables. For example, do_date's frame 0 and frame 1 both have a ch variable, and an argument variable. We can tell just by looking at the backtrace that the ch variable points to the same memory location, 0x82ab598. However, the argument variables are different. The question then, is how do we differentiate between the two? The answer is by using the 'frame' command.
(gdb) print argument $1 = 0xbffff94c "" (gdb) frame 1 #1  0x807d12a in command_interpreter (ch=0x82ab598, argument=0xbffff948    "date") at interpreter.c:644 644       ((*cmd_info[cmd].command_pointer) (ch, line, cmd,    cmd_info[cmd].submd)); (gdb) print argument $2 = 0xbffff948 "date" (gdb) |
It's a simple command that only takes one argument, a number, and sets up that frame to examine. That lets you switch frames.
To actually display the information in the stack, we have one last command; info. There are many (MANY) possible arguments to the info command, but we're just going to concentrate on three; frame, locals, args. In brief, they show information about the frame, the local variables, and the arguments to the function in the current frame. Here's an example;
Frame:
(gdb) info frame Stack level 0, frame at 0xbffff85c: eip = 0x8063322 in do_date (act.wizard.c:1564); saved eip 0x807d12a called by frame at 0xbffff894 source language c. Arglist at 0xbffff85c, args: ch=0x82ab598, argument=0xbffff94c "", cmd=52, subcmd=0 Locals at 0xbffff85c, Previous frame's sp is 0x0 Saved registers: ebx at 0xbffff840, ebp at 0xbffff85c, esi at 0xbffff844, edi at 0xbffff848, eip at 0xbffff860 (gdb) |
Locals:
(gdb) info locals __s1_len = 134624012 __s2_len = 4294967295 subcmd = 0 tmstr = 0x80aaa68 "" mytime = 1040 d = 0 h = 0 (gdb) |
Args:
(gdb) info args ch = (struct char_data *) 0x82ab598 argument = 0xbffff94c "" cmd = 52 subcmd = 0 (gdb) |
![]() |
Index | ![]() |
6.1.3.2 Examining Variables | 6.1.4 Run Time Debugging |