我有一个 64 位程序,可与 VirtualBox COM 接口配合使用并实现虚拟机的前端。最近我开始变得奇怪An invalid or unaligned stack was encountered during an unwind operation
例外,我想至少了解其原因。据我了解,堆栈需要 16 字节对齐,因此,我认为未对齐的堆栈指针可能会导致此情况。但问题是,因为我的程序所做的只是使用以下方法实现几个 COM 接口STDMETHOD
ATL 中的宏应该使用正确的调用约定,那么我怎么会弄乱堆栈呢?
以下是发生问题时的调用堆栈示例:
ntdll.dll!00007ffe679ac0b4() Unknown
ntdll.dll!00007ffe67913356() Unknown
msvcrt.dll!__longjmp_internal() Unknown
> VBoxREM.dll!000000006fb0f3c4() Unknown
我试图谷歌__longjmp_internal
符号但没有找到任何有用的东西 - 它是否表明异常展开正在进行中?
欢迎任何有关如何调试此问题的指针或可能会扰乱堆栈对齐的评论,因为我知道在这种情况下,由于涉及 VirtualBox,因此不可能给出准确的解决方案。
我最近遇到了这个令人困惑的问题。
我知道它只是在我从静态 C/C++ 运行时切换到 DLL 版本后才开始发生,因此这可能意味着静态版本没有执行堆栈展开。
然后我跟踪了 longjmp() 的汇编代码,并注意到第一个条件分支之一位于 _JUMP_BUFFER.Frame 上。
如果是0,则恢复一堆寄存器并返回。
啊哈!所以这必定意味着如果 _JUMP_BUFFER.Frame = 0,则展开被禁用。我尝试了一下,确实,问题解决了。
然后,我尝试观察 setjmp()/longjmp() 对成功时的 Frame 应该是什么。我发现通常,frame = 堆栈指针,但是当展开失败时,frame != SP。所以我尝试将 Frame 设置为 SP,这也消除了异常。
我不知道为什么会这样。我知道在 SYSV x86-64 ABI 中,帧指针是可选的。也许 setjmp() 需要一个适当的帧指针但没有得到一个?
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)