c++ - 展开操作期间遇到无效或未对齐的堆栈

标签 c++ com 64-bit virtualbox

我有一个 64 位程序,可与 VirtualBox COM 接口(interface)配合使用并实现虚拟机的前端。最近,我开始遇到奇怪的在展开操作期间遇到无效或未对齐的堆栈异常,我想至少了解其原因。据我所知,堆栈需要 16 字节对齐,因此,我认为未对齐的堆栈指针可能会导致这种情况。但问题是,由于我的程序所做的只是使用 ATL 中的 STDMETHOD 宏实现几个 COM 接口(interface),而这些宏应该使用正确的调用约定,那么我怎么会弄乱堆栈呢?

以下是出现问题时的调用堆栈示例:

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() 需要一个适当的帧指针但没有得到一个?

关于c++ - 展开操作期间遇到无效或未对齐的堆栈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26605063/

相关文章:

C# 适用于 32 位但不适用于 64 位

asp.net-mvc - 64 位 ASP.NET MVC 应用程序无法运行

Python:当 KeyboardInterrupt 被转发到多处理子进程时?

c++ - 如何处理 vector 中的数据组?

c# - 你将如何通过 com 传递 C# 对象?

c++ - 为什么在没有声明的情况下不从 .cpp 文件中获取模板函数的完全特化?

.net - AxInterop和Interop有什么区别?

c++ - 获取字符串后对 CompStr(BSTR, BSTR) 的访问冲突?

c++ - N皇后问题。从函数C++返回数组

c++ - 如何在C套接字程序中接收HTTP GET和POST请求?