我正在编写一些代码来调试使用 Boost.Contextmake_fcontext
和的堆栈协程jump_fcontext
,并且遇到了一个小问题。
通常不可能backtrace
越过堆栈协程的入口,因为它在自己的堆栈上执行。这意味着我无法从调试器中确定协程是从哪里输入的。然而,这不是我要问的问题。我已经通过在传递给的函数中添加一些内联汇编和 DWARF 字节码解决了这个问题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 有一个“健全性检查”:如果堆栈指针在调用帧之间以“错误”的方向移动,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“相信我,我知道我在做什么”?