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]

Re: Using frame to switch stacks


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


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