堆栈协程 + gdb = "previous frame inner to this frame (corrupt stack)?"
Stackful coroutines + gdb = "previous frame inner to this frame (corrupt stack)?"
我正在编写一些代码来调试使用 Boost.Context 的 make_fcontext
和 jump_fcontext
的堆栈协程,并将 运行 变成一个小问题。
通常不可能 backtrace
越过堆栈协程的入口,因为它在自己的堆栈上执行。这意味着我无法通过调试器确定协程的输入位置。然而,这不是我要问的问题。我已经通过在传递给 make_fcontext
:
的函数中添加一些内联汇编和 DWARF 字节码解决了这个问题
__asm__ volatile (
"mov %[caller_fcontext_t] %[somewhere]\n\t"
".cfi_escape /* DWARF bytecode to load caller_fcontext_t from "
" * somewhere and use it to load all the registers saved "
" * there by jump_fcontest */"
"call %[another_function]"
: /* stuff */ : /* stuff */ : /* stuff */)
这确实有效,我现在可以 backtrace
到调用方启动或恢复内部协程的位置 - 但只是有时。
事实证明,gdb 有一个 "sanity check":如果堆栈指针在调用帧之间向 "wrong" 方向移动,gdb 假定堆栈已损坏并停止跟踪并显示消息“ Backtrace stopped: previous frame inner to this frame (corrupt stack?)
".
当我的堆栈以特定方式而非以其他方式分配时会触发此事件。我什至对静态分配的堆栈进行了测试,当以正向顺序使用时会触发此故障,但在反向顺序使用时不会。
我什至在这里找到了执行此检查的 gdb 源代码部分:https://github.com/bminor/binutils-gdb/blob/master/gdb/frame.c#L737-L816
现在这是我的实际问题:我该如何解决这个问题?
有没有我可以写的汇编指令告诉 GDB "trust me, I know what I'm doing"?
Now here's my actual question: How can I fix this?
Is there some assembly incantation I can write that tells GDB "trust
me, I know what I'm doing"?
目前没有办法做到这一点。这将是一个好主意,但可能需要某种 DWARF 扩展。所以,执行起来可能比较困难。
您可以在 gdb 源代码中看到这方面的证据:GCC 有一个涉及 -fsplit-stack
的类似问题,只需将有问题的函数的名称编码到 gdb 中即可解决此问题:
if (!morestack_name || strcmp (morestack_name, "__morestack") != 0)
您个人使用的一个快速解决方法是注释掉 early return here。
我正在编写一些代码来调试使用 Boost.Context 的 make_fcontext
和 jump_fcontext
的堆栈协程,并将 运行 变成一个小问题。
通常不可能 backtrace
越过堆栈协程的入口,因为它在自己的堆栈上执行。这意味着我无法通过调试器确定协程的输入位置。然而,这不是我要问的问题。我已经通过在传递给 make_fcontext
:
__asm__ volatile (
"mov %[caller_fcontext_t] %[somewhere]\n\t"
".cfi_escape /* DWARF bytecode to load caller_fcontext_t from "
" * somewhere and use it to load all the registers saved "
" * there by jump_fcontest */"
"call %[another_function]"
: /* stuff */ : /* stuff */ : /* stuff */)
这确实有效,我现在可以 backtrace
到调用方启动或恢复内部协程的位置 - 但只是有时。
事实证明,gdb 有一个 "sanity check":如果堆栈指针在调用帧之间向 "wrong" 方向移动,gdb 假定堆栈已损坏并停止跟踪并显示消息“ Backtrace stopped: previous frame inner to this frame (corrupt stack?)
".
当我的堆栈以特定方式而非以其他方式分配时会触发此事件。我什至对静态分配的堆栈进行了测试,当以正向顺序使用时会触发此故障,但在反向顺序使用时不会。
我什至在这里找到了执行此检查的 gdb 源代码部分:https://github.com/bminor/binutils-gdb/blob/master/gdb/frame.c#L737-L816
现在这是我的实际问题:我该如何解决这个问题?
有没有我可以写的汇编指令告诉 GDB "trust me, I know what I'm doing"?
Now here's my actual question: How can I fix this?
Is there some assembly incantation I can write that tells GDB "trust me, I know what I'm doing"?
目前没有办法做到这一点。这将是一个好主意,但可能需要某种 DWARF 扩展。所以,执行起来可能比较困难。
您可以在 gdb 源代码中看到这方面的证据:GCC 有一个涉及 -fsplit-stack
的类似问题,只需将有问题的函数的名称编码到 gdb 中即可解决此问题:
if (!morestack_name || strcmp (morestack_name, "__morestack") != 0)
您个人使用的一个快速解决方法是注释掉 early return here。