最近,我将一个大型 C++(MFC) 解决方案从 VS2010 转换为 VS2012。而且我在发布配置中遇到了应用程序崩溃。经过一番调查,我找到了导致崩溃的线路。它的功能是这样的:
void CMyWnd::Foo()
{
if (!m_sub_wnd.GetSafeHwnd())
return;
// some other code goes here
// here used m_sub_wnd and another member m_data
}
在发布模式下,disasm 显示第一个条件的以下代码:
if (!m_sub_wnd.GetSafeHwnd())
00000001405F6E30 add rcx,260h
00000001405F6E37 je CMyWnd::Foo+0DBh (01405F6F0Bh)
00000001405F6E3D push rsi
00000001405F6E3E sub rsp,30h
00000001405F6E42 cmp qword ptr [rcx+40h],0
00000001405F6E47 mov rsi,rcx
00000001405F6E4A je CMyWnd::Foo+0D6h (01405F6F06h)
return;
似乎“添加 rcx,260h”在任何情况下都会更改此指针,并且其他代码使用损坏的此指针。我不熟悉asm。是对的还是我错过了什么?如果它似乎是 C++ 编译器错误,我会向 Microsoft 支持报告问题。
更新:
当我将“this”指针添加到我的函数转储中时 - 崩溃消失了。
void CMyWnd::Foo()
{
00000001405F6BE0 mov qword ptr [rsp+20h],rbx
00000001405F6BE5 push rsi
00000001405F6BE6 sub rsp,30h
if (!m_sub_wnd.GetSafeHwnd())
00000001405F6BEA lea rbx,[rcx+260h]
00000001405F6BF1 mov rsi,rcx
00000001405F6BF4 test rbx,rbx
00000001405F6BF7 je CMyWnd::Foo+101h (01405F6CE1h)
00000001405F6BFD cmp qword ptr [rbx+40h],0
00000001405F6C02 je CMyWnd::Foo+101h (01405F6CE1h)
return;
s << this << endl;
00000001405F6C08 mov rdx,rcx
00000001405F6C0B lea rcx,[s (0140D16320h)]
00000001405F6C12 mov qword ptr [this],rbp
00000001405F6C17 mov qword ptr [rsp+50h],r14
00000001405F6C1C call qword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (01409325A0h)]
00000001405F6C22 mov rdx,qword ptr [__imp_std::endl (01409326D8h)]
00000001405F6C29 mov rcx,rax
00000001405F6C2C call qword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (0140932700h)]