Re: Using frame to switch stacks
Simon Marchi <[email protected]>
| Newsgroups | gmane.comp.gdb.devel |
|---|---|
| Message-ID | <[email protected]> |
On 2018-02-28 13:05, Niklas Reiners wrote: > Hello everyone, > > I'm debugging a library which uses multiple stacks. The documentation > states that frame / select-frame can be used for this. However I can > only seem to get it to work with stack and pc address of frames that > are with in the current stack. Parameter pairs outside the stack > (composing another stack) yield an invalid frame. > > To show this behavior and how I invoke frame I prepared a minimal > example, containing a program with two stacks and a python script for > gdb. It can be found here: > https://github.com/NotAC0W/gdb-switch-stacks > > The repository also contains a more detailed description of the > program and the output of an example run. > > Am I using frame correctly or should I be using different commands? > > Thank you very much for your help, > > Niklas Hi Niklas, This is a late response, but I guess it's better late than never. I only took a quick look so excuse me if I a missing some obvious things. When switching from stack 1 to stack 2 in your application, you save the registers of the current frame of stack 1 to an application-defined area, much like an OS would do (it would store them in a task structure). When the crash happens, the values in the "physical" registers are those of the current frame of stack 2. When you instruct GDB to manually switch to a stack frame with a given sp and pc, it can create a frame with those values. But GDB probably still reads the register values of the current Linux thread (those of stack 2, which was the current one at the time of the crash), because that's the level of awareness it has. To get to the upper frames, it would need to read the registers associated to stack 1, which are currently stashed away. For example, according to the DWARF info, finding the value of rsp for the frame of "main" (also the return address) is "rsp of setup's frame + 48". But if GDB does that computation using the rsp from the other stack, it will certainly give something that doesn't make sense. If you try to set the registers directly, you can probably make GDB do what you want: (gdb) bt #0 asmfoo2 () at functions.S:14 #1 0x000055555555476c in asmfoo () at functions.S:31 #2 0x00005555555546b4 in new_world () at main.c:14 #3 0x0000000000000000 in ?? () (gdb) set $rip = 0x555555554727 (gdb) set $rsp = 0x7fffffffd8e0 (gdb) bt #0 setup () at main.c:28 #1 0x0000555555554743 in main (argc=1, argv=0x7fffffffda08) at main.c:31 You would need to restore all the registers like this to be sure to have coherent variable values. I'm not sure in what situations the "frame <stack-addr> <code-addr>" command is useful, maybe someone else can tell. Simon