c++ - 在代码的不同部分获取访问冲突错误

标签 c++ visual-studio-2010 winapi

我一直在我们的 win32 应用程序中遇到这些随机访问冲突,并且完全不知道是什么导致了它。我可以发布代码,但它在不同的部分,而且会太长。但是,我想我知道问题可能是什么:

基本上,我们有一个 wndproc:

LRESULT CALLBACK WndProc (HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
    static ProgramParams params;

    switch(msg) {
        case WM_CREATE:
            params.hwnd = hwnd;
            params.connected = TRUE;
            //more params assignment here
            return 0;

        case WM_RUNTHREADS:
            _beginthread(Func1, 0, &params);
            _beginthread(Func2, 0, &params);
            return 0;

        case WM_DISCONNECT:
            params.connected = FALSE;
            return 0;

// lot more code
}

在 Func1 和 Func2 中,大量使用了指向 params 的指针。严重的是,我的意思是多重赋值和 if 语句。我不确定这是否是个坏主意,但我觉得这种用法会导致问题。它就像一个全局变量,将所有线程连接在一起。

这里还有一些反汇编的摘录:

dc final v2.exe 中 0x77c815ee 的未处理异常:0xC0000005:访问冲突。

    return TRUE;
001E3AE5  mov         eax,1  
}
001E3AEA  push        edx  
001E3AEB  mov         ecx,ebp  
001E3AED  push        eax  
001E3AEE  lea         edx,[ (1E3B10h)]  
001E3AF4  call        @ILT+220(@_RTC_CheckStackVars@8) (1E10E1h)  
----> 001E3AF9  pop         eax  //green arrow (after clicking "break") pointing here
001E3AFA  pop         edx  
001E3AFB  pop         edi  
001E3AFC  pop         esi  
001E3AFD  pop         ebx  
001E3AFE  add         esp,0E8h  
001E3B04  cmp         ebp,esp  
001E3B06  call        @ILT+610(__RTC_CheckEsp) (1E1267h)  
001E3B0B  mov         esp,ebp  
001E3B0D  pop         ebp  
001E3B0E  ret  

在地址 0x77c815ee 附近汇编

77C815C3  nop  
77C815C4  mov         eax,12Eh  
77C815C9  xor         ecx,ecx  
77C815CB  lea         edx,[esp+4]  
77C815CF  call        dword ptr fs:[0C0h]  
77C815D6  add         esp,4  
77C815D9  ret         18h  
77C815DC  mov         eax,12Fh  
77C815E1  xor         ecx,ecx  
77C815E3  lea         edx,[esp+4]  
77C815E7  call        dword ptr fs:[0C0h]  
----> 77C815EE  add         esp,4 
77C815F1  ret         0Ch  
77C815F4  mov         eax,130h  
77C815F9  xor         ecx,ecx  
77C815FB  lea         edx,[esp+4]  
77C815FF  call        dword ptr fs:[0C0h]  
77C81606  add         esp,4  
77C81609  ret         18h  
77C8160C  mov         eax,131h  
77C81611  xor         ecx,ecx  
77C81613  lea         edx,[esp+4]  
77C81617  call        dword ptr fs:[0C0h]  

通过调试打开所有异常 > 异常结果为:

dc final v2.exe 中 0x00000000 处的第一次异常:0xC0000005:访问冲突。

SendMessage(parentHwnd, WM_TERM, (WPARAM) "ABCD", NULL);
001F1CAF  mov         esi,esp  
001F1CB1  push        0  
001F1CB3  push        465h  
001F1CB8  push        402h  
001F1CBD  mov         eax,dword ptr [pparams]  
001F1CC0  mov         ecx,dword ptr [eax]  
001F1CC2  push        ecx  
001F1CC3  call        dword ptr [__imp__SendMessageW@16 (1FE68Ch)]  
----> 001F1CC9  cmp         esi,esp //green arrow here
001F1CCB  call        @ILT+610(__RTC_CheckEsp) (1F1267h)  

如果这太含糊,我真的很抱歉,但我不确定如何描述它。我会像鹰一样关注这个话题,所以如果你需要什么,请告诉我。

即使它只是“可能是由于未分配变量造成的”之类的事情,我也会很高兴听到它,因为我现在不知道从哪里开始寻找。

谢谢!

最佳答案

如果您在代码的各个部分遇到随机访问冲突,您的堆很可能已损坏。

这些错误很难发现。首先,我建议下载适用于 Windows 的调试工具并使用启用了完整堆检查的应用程序验证程序。请务必附加调试器(Visual Studio 或 windbg),因为它会在堆损坏发生时引发异常。

在那之后,您唯一真正能做的就是查看所有代码,寻找任何看起来可疑的东西。确保每个指针都已初始化,并且您没有越界访问任何数组或容器。

如果多个线程并行写入同一个共享对象,则它可能已损坏。尝试锁定对共享对象的所有访问,尤其是当它有任何与索引关联的指针或数据时。

关于c++ - 在代码的不同部分获取访问冲突错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8283831/

相关文章:

visual-studio-2010 - MSB6006 : "cmd.exe" exited with code 9009

c# - Debug.Assert() 仅在跨过它时触发

c++ - 如何设置工具栏按钮的高度?

c - windows应用程序开发: a nebie's dilemna! EXE和安装的.exe版本?

c++ - Objective-C++ 调用 C 或 C++ 函数

c++ - QListView selectionModel 不发送 selectionChanged 信号

java - SWIG 不接受指针参数的包装对象

c++ - 调试程序集时,如何在 VS2019 watch 窗口中将内存地址转换为用户定义的类型?

vb.net - ListView – ItemCheck 事件的旧检查状态

c++ - 如何将 int 字符串与消息框一起使用?