展开操作期间遇到无效或未对齐的堆栈 [英] An invalid or unaligned stack was encountered during an unwind operation
问题描述
我有一个与VirtualBox COM接口一起使用的64位程序,并为虚拟机实现了一个前端。最近,我开始变得很奇怪在展开操作期间遇到无效或未对齐的堆栈
异常,我希望至少了解这种情况的原因。据我了解,堆栈需要对齐16字节,因此,我认为未对齐的堆栈指针很可能导致这种情况。但问题是,由于我的所有程序都使用来自ATL的 STDMETHOD
宏实现了两个COM接口,这些宏应使用正确的调用约定,那么我该如何弄乱
I have a 64bit program that works with VirtualBox COM interface and implements a frontend for the virtual machine. Recently I started getting weird An invalid or unaligned stack was encountered during an unwind operation
exceptions and I wanted to at least understand the causes of this. As I understand the stack needs to be 16byte aligned so, I presume unaligned stack pointer likely to cause this. But the thing is, since all my program does is implement a couple of COM interfaces using the STDMETHOD
macros from ATL that should use the correct calling convention then how could I mess up the stack?
以下是发生问题时调用堆栈的示例:
Here is an example of the call stack when the issue occurs:
ntdll.dll!00007ffe679ac0b4() Unknown
ntdll.dll!00007ffe67913356() Unknown
msvcrt.dll!__longjmp_internal() Unknown
> VBoxREM.dll!000000006fb0f3c4() Unknown
我试图破坏 __ longjmp_internal
符号,但没有找到有用的符号-是否表示正在进行异常解除?
I tried to goole the __longjmp_internal
symbol but did not find anything useful - does it indicate that exception unwind is in progress?
有关如何调试此问题的任何指针或评论,可能会破坏堆栈对齐方式的内容受到欢迎,因为我知道在这种情况下,由于涉及VirtualBox,因此不可能给出确切的解决方案。
Any pointer on how to approach debugging of this issue or comments what could mess up the stack alignment are welcome, since I understand that in this case it will be impossible to give an exact solution because VirtualBox is involved.
推荐答案
我最近遇到了这个莫名其妙的问题。
I've faced this baffling problem recently.
我知道它只是在我从静态C / C ++运行时切换到DLL之后才开始发生版本,所以这可能意味着静态版本没有展开堆栈。
I know it only started happening after I switched from the static C/C++ runtime to the DLL version, so that probably means the static version didn't do stack unwinding.
然后,我跟踪了longjmp()的汇编代码,并注意到第一个条件分支之一是
I then traced the assembly code for longjmp() and noticed one of the 1st conditional branches was on _JUMP_BUFFER.Frame.
如果为0,则恢复一堆寄存器并返回。
if it's 0, then restore a bunch of registers and return.
啊哈!因此,这意味着如果_JUMP_BUFFER.Frame = 0,则展开功能被禁用。我尝试了一下,确实解决了问题。
Aha! so that must mean if _JUMP_BUFFER.Frame = 0, unwinding is disabled. I tried it and indeed, problem solved.
然后,我尝试观察setjmp()/ longjmp()对成功后应该是什么帧。我通常发现frame =堆栈指针,但是当展开失败时,frame!= SP。因此,我尝试将Frame设置为SP,这也消除了异常。
I then tried to observe what Frame should be when a setjmp()/longjmp() pair succeeds. I found usually, frame = stack pointer, but when the unwinding fails, frame != SP. So I tried setting Frame to SP and that also eliminates the exception.
我不知道为什么这样。我知道在SYSV x86-64 ABI中,帧指针是可选的。也许setjmp()需要适当的帧指针并且没有得到指针?
I don't know why that works. I know in the SYSV x86-64 ABI, the frame pointer is optional. Maybe setjmp() needs a proper frame pointer and isn't getting one?
这篇关于展开操作期间遇到无效或未对齐的堆栈的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!