为什么我的64位C ++应用程序崩溃了?

时间:2009-02-24 17:24:25

标签: c++ visual-studio-2008 visual-c++

我编写了一个非常小的64位应用程序,它在Windows Vista x64的干净安装中崩溃。它在我的安装了Visual Studio 2008的开发机器(Windows 7 64位)上顺利运行。

64位C ++应用程序(非托管)由32位.NET应用程序启动,并在发生访问冲突错误后立即崩溃。这就是事件查看器所说的内容:

Faulting application MaxTo64.exe, version 0.0.0.0, time stamp 0x49a41d9e, 
faulting module USER32.dll, version 6.0.6001.18000, time stamp 0x4791adc5, 
exception code 0xc0000005, fault offset 0x00000000000236d6, process id 0x82c, 
application start time 0x01c996a346a3e805.

MaxTo64.exe 
0.0.0.0 
49a41d9e 
USER32.dll 
6.0.6001.18000 
4791adc5 
c0000005 
00000000000236d6 
82c 
01c996a346a3e805 

我已经安装了VC2008可再发行组件(2008 x86,2008 x64,2008 SP1 x86和2008 SP1 x64),所以这应该不是问题所在。 编辑:值得一提的是,在安装vcredist-package之前,它会因为并排配置错误而崩溃。

我是C ++ n00b,所以我真的不知道接下来要去哪看。

编辑:从Windows调试工具输出。

CommandLine: "C:\Program Files (x86)\MaxTo\MaxTo64.exe" maxto_a_do_run_run
Symbol search path is: *** Invalid ***
****************************************************************************
* Symbol loading may be unreliable without a symbol search path.           *
* Use .symfix to have the debugger choose a symbol path.                   *
* After setting your symbol path, use .reload to refresh symbol locations. *
****************************************************************************
Executable search path is: 
ModLoad: 00000001`3f2f0000 00000001`3f30b000   MaxTo64.exe
ModLoad: 00000000`77160000 00000000`772e0000   ntdll.dll
ModLoad: 00000000`77030000 00000000`7715b000   C:\Windows\system32\kernel32.dll
ModLoad: 00000001`80000000 00000001`80011000   C:\Program Files (x86)\MaxTo\Hooker.dll
ModLoad: 00000000`76f60000 00000000`7702d000   C:\Windows\system32\USER32.dll
ModLoad: 000007fe`fed70000 000007fe`fedd3000   C:\Windows\system32\GDI32.dll
ModLoad: 000007fe`fea20000 000007fe`feb28000   C:\Windows\system32\ADVAPI32.dll
ModLoad: 000007fe`fe850000 000007fe`fe98f000   C:\Windows\system32\RPCRT4.dll
ModLoad: 000007fe`fd8b0000 000007fe`fe502000   C:\Windows\system32\SHELL32.dll
ModLoad: 000007fe`fef70000 000007fe`ff00c000   C:\Windows\system32\msvcrt.dll
ModLoad: 000007fe`feee0000 000007fe`fef53000   C:\Windows\system32\SHLWAPI.dll
(3a4.964): Break instruction exception - code 80000003 (first chance)
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for ntdll.dll - 
ntdll!DbgBreakPoint:
00000000`771a4ea0 cc              int     3
0:000> g
ModLoad: 000007fe`fe780000 000007fe`fe7ad000   C:\Windows\system32\IMM32.DLL
ModLoad: 000007fe`ff010000 000007fe`ff111000   C:\Windows\system32\MSCTF.dll
ModLoad: 000007fe`feed0000 000007fe`feedd000   C:\Windows\system32\LPK.DLL
ModLoad: 000007fe`fede0000 000007fe`fee7a000   C:\Windows\system32\USP10.dll
ModLoad: 000007fe`fc150000 000007fe`fc349000   C:\Windows\WinSxS\amd64_microsoft.windows.common-controls_6595b64144ccf1df_6.0.6001.18000_none_152e7382f3bd50c6\comctl32.dll
(3a4.964): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Windows\system32\USER32.dll - 
USER32!DisableProcessWindowsGhosting+0x1a:
00000000`76f836d6 66f2af          repne scas word ptr [rdi]
*** ERROR: Module load completed but symbols could not be loaded for MaxTo64.exe
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Windows\system32\kernel32.dll - 

此时的调用堆栈是:

USER32!DisableProcessWindowsGhosting+0x1a
USER32!ChangeWindowMessageFilter+0x12d
USER32!RegisterClassExW+0x25
MaxTo64+0x11e4
MaxTo64+0x1075
MaxTo64+0x1920
kernel32!BaseThreadInitThunk+0xd
ntdll!RtlUserThreadStart+0x21

它似乎在MyRegisterClass中,看起来像这样:

ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;

wcex.cbSize = sizeof(WNDCLASSEX);

wcex.style          = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc    = WndProc;
wcex.cbClsExtra     = 0;
wcex.cbWndExtra     = 0;
wcex.hInstance      = hInstance;
wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MAXTO64));
wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszClassName  = szWindowClass;
wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

return RegisterClassEx(&wcex);
}

编辑:原来问题是我自己的愚蠢错误。显然,WNDCLASSEX结构中有一个未正确初始化的字段。这在Vista上崩溃了,但在Windows 7上却没有,奇怪的是。添加此项可以解决问题。

wcex.lpszMenuName   = NULL;

5 个答案:

答案 0 :(得分:5)

严重的是,我们无法从您的数据中推断:

我建议至少做以下其中一项

<强> 修改 : 在仅查看调试跟踪之后,我刚刚遇到两个可能的问题:

  • 你没有ZeroMemory WNDCLASSEX,所以也许Vista试图使用lpszMenuName。
  • Win7是测试版,可能隐藏了一个错误。

但是你仍然没有显示太多代码并且跟踪不完整,因此很难在没有psychic的情况下断言。

如果将VS生成的.pdb复制到Vista计算机上,则在.exe所在的文件夹中,您将获得更有意义的跟踪。

答案 1 :(得分:3)

安装适用于Windows的调试工具并获得真正的回溯 - 这应该会引导您了解正在发生的事情

答案 2 :(得分:1)

调试器怎么样?一些代码崩溃的地方?

此外,不要做愚蠢的事情,如在int中存储指针 - 它将不再适合。

答案 3 :(得分:0)

您有访问冲突,您很可能尝试读取或写入无效内存。

答案 4 :(得分:0)

异常代码0xc0000005是一种访问冲突:您的程序最有可能尝试写入或读取它不拥有的内存。 C / C ++中的常见原因是使用空指针。由于异常发生在USER32.dll中,您可能传递了一个空指针。由于您使用的是C ++,它可能涉及一个对象而不是一个结构,或者某个对象/类中的方法也包含USER32.dll函数。