This is the mail archive of the gdb@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Examining copied stack contents


Hello everyone.

I'm currently implementing a high-level debugger based on GDB for a coroutine-based simulation framework. The platform is GNU/Linux on x86.

That framework implements coroutines by using the C/C++ setjmp/longjmp instructions and by copying the call stack that is used by each coroutine to dynamically allocated memory on the heap. It's this latter aspect that gives me terrible headaches in GDB.

My question is simply: Is it possible to point GDB to the copied contents of the call stack and tell it to print out the information contained therein?

The documentation [1] does contain the following note:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
frame addr
f addr
Select the frame at address addr. This is useful mainly if the chaining of stack frames has been damaged by a bug, making it impossible for gdb to assign numbers properly to all frames. In addition, this can be useful when your program has multiple stacks and switches between them.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


Additionally, the docs about the "info frame" command also say that it accepts memory addresses as arguments.


Unfortunately, this does not seem to work as well as I anticipated. I tried several versions of the GDB, from 6.8 to the newest 7.1, but they all exhibit the same issues.


When I stop the program directly after the call stack was saved, the situation presents itself as follows:

The stack pointer register is at 0xbfffeec0. The first two stack frames return the following data:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(gdb) info frame 0
Stack frame at 0xbfffeef0:
eip = 0x805a972 in [CODE LINE]; saved eip 0x805a588
called by frame at 0xbfffef30
source language c++.
Arglist at 0xbfffeee8, args: this=0x80b3238
Locals at 0xbfffeee8, Previous frame's sp is 0xbfffeef0
Saved registers:
 ebp at 0xbfffeee8, eip at 0xbfffeeec

(gdb) info frame 1
Stack frame at 0xbfffef30:
eip = 0x805a588 in [CODE LINE]; saved eip 0x806b2a6
called by frame at 0xbfffef70, caller of frame at 0xbfffeef0
source language c++.
Arglist at 0xbfffef28, args: this=0x80b2bd8
Locals at 0xbfffef28, Previous frame's sp is 0xbfffef30
Saved registers:
ebx at 0xbfffef20, ebp at 0xbfffef28, esi at 0xbfffef24, eip at 0xbfffef2c
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


The program copied the whole stack (including a bit of safety margin) beginning with the address 0xbfffeedf to the address 0x80b39c8.

Now, if I tell GDB to print information about the stack frame located at 0xbfffeef0, it does so correctly:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(gdb) info frame 0xbfffeef0
Stack frame at 0xbfffeef0:
eip = 0x805a972 in [CODE LINE]; saved eip 0x805a588
called by frame at 0xbfffef30
source language c++.
Arglist at 0xbfffeee8, args: this=0x80b3238
Locals at 0xbfffeee8, Previous frame's sp is 0xbfffeef0
Saved registers:
 ebp at 0xbfffeee8, eip at 0xbfffeeec

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

But if I point it to the exact copy of that frame, beginning with 0x80b39d9, I get the following "fail safe" information that the GDB also prints when I point it to *any* arbitrary address:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(gdb) info frame 0x80b39d9
Stack frame at 0x80b39d9:
eip = 0x0; saved eip 0x80b39c8
called by frame at 0xbfffeef0
Arglist at 0xbfffeebc, args:
Locals at 0xbfffeebc, Previous frame's sp is 0xbfffeec4
Saved registers:
 eip at 0xbfffeec0
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

But if I examine the memory ranges, they are absolutely identical:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(gdb) x/8x 0x80b39d9
0x80b39d9: 0x080b3238 0x080b2bd8 0x080b2ca4 0x080b2ca4
0x80b39e9: 0x0021a73c 0x080b2bc8 0x080b3238 0x00000000
(gdb) x/8x 0xbfffeef0
0xbfffeef0: 0x080b3238 0x080b2bd8 0x080b2ca4 0x080b2ca4
0xbfffef00: 0x0021a73c 0x080b2bc8 0x080b3238 0x00000000
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


Obviously, the GDB doesn't even attempt to interpret the given address as a stack frame. I am aware that the GDB needs debugging symbols to make any sense out of the stack (after all, the frame size depends on the actual call they represent); and also that the addresses inside the copied stack can't be followed, because they still point to the original memory addresses.


But I'm also aware that the GDB *should be* able to do what I want it to do. For one, the documentation explicitly mentions that the feature works with programs that utilize multiple stacks. Furthermore, the GDB is also able to debug Multi-Threaded programs, which also need to save the call stack to dynamic heap memory.



So, my question is: Is it possible to examine the copied stack? And if yes, what do I need to give to the GDB to allow it?



Thanks in advance,
   Martin Schröder.


[1] - http://sourceware.org/gdb/current/onlinedocs/gdb/Selection.html



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]