展开操作期间遇到无效或未对齐的堆栈 [英] An invalid or unaligned stack was encountered during an unwind operation

查看:31
本文介绍了展开操作期间遇到无效或未对齐的堆栈的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 64 位程序,可与 VirtualBox COM 接口配合使用并为虚拟机实现前端.最近我开始变得奇怪在展开操作期间遇到无效或未对齐的堆栈异常,我想至少了解造成这种情况的原因.据我了解,堆栈需要对齐 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() 的汇编代码并注意到第一个条件分支之一在 _JUMP_BUFFER.Frame 上.

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 = stack pointer,但是当展开失败时,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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆