代码之家  ›  专栏  ›  技术社区  ›  hatcat

为什么我的mfc dll在接近启动的单个线程上死锁?

  •  1
  • hatcat  · 技术社区  · 16 年前

    使用Visual Studio 2005,调试器告诉我在我编写的应用程序启动后发生了死锁-此时我已经很熟悉winmain()。调用堆栈显示我们处于一个关键部分,同时从一个MFC DLL中调用AFX_Manage_State2(666次,够吓人的)。这才刚刚开始:代码昨天工作得很好。奇怪的是,回滚代码、重新启动PC和重新构建仍然会导致死锁。

    当一切都停止时,我在调试器上单击了“暂停”,这条消息(最终)会出现:


    Microsoft Visual Studio

    进程似乎已死锁(或未运行任何用户模式代码)。所有线程都已停止。

    好啊

    调用堆栈如下所示:

    ntdll.dll!_KiFastSystemCallRet@0()  
    ntdll.dll!_ZwWaitForSingleObject@12()  + 0xc bytes  
    ntdll.dll!_RtlpWaitForCriticalSection@4()  + 0x8c bytes 
    ntdll.dll!_RtlEnterCriticalSection@4()  + 0x46 bytes    
    mfc80ud.dll!CThreadSlotData::GetThreadValue(int nSlot=1)  Line 247  C++
    mfc80ud.dll!CThreadLocalObject::GetData(CNoTrackObject * (void)* pfnCreateObject=0x7832e030)  Line 419 + 0x11 bytes C++
    mfc80ud.dll!CThreadLocal<_AFX_THREAD_STATE>::GetData()  Line 177 + 0xd bytes    C++
    mfc80ud.dll!AFX_MAINTAIN_STATE2::AFX_MAINTAIN_STATE2(AFX_MODULE_STATE * pNewState=0x029a80d8)  Line 57 + 0xa bytes  C++
    EmpireConsole.UnityDebug.dll!WIN_CON::SPOOL::BUFFER::overflow(unsigned short c=65)  Line 979 + 0x13 bytes   C++
    Empire.UnityDebug.exe!UTILITYLIB::UniCharStreamBuf::sputc(CA::UniChar ch={...})  Line 113 + 0x68 bytes  C++
    Empire.UnityDebug.exe!UTILITYLIB::operator<<(UTILITYLIB::UniCharOStream & ucos={...}, const char * val=0x0888019c)  Line 868 + 0x2f bytes   C++
    Empire.UnityDebug.exe!EMPIRE::ENVIRONMENT::auto_analyse()  Line 319 + 0x2b bytes    C++
    Empire.UnityDebug.exe!EMPIRE::EMPIRE_APP_MODULE::run_vars(CA::UniString CmdLine={UniString [...] ...)  Line 2531    C++
    Empire.UnityDebug.exe!`anonymous namespace'::winmain_inner(HINSTANCE__ * hInstance=0x08440000, HINSTANCE__ * __formal=0x00000000, wchar_t * lpCmdLine=0x00020a92)  Line 1981    C++
    Empire.UnityDebug.exe!wWinMain(HINSTANCE__ * hInstance=0x08440000, HINSTANCE__ * hPrevInstance=0x00000000, wchar_t * lpCmdLine=0x00020a92, int __formal=1)  Line 4808 + 0x11 bytes  C++
    Empire.UnityDebug.exe!__tmainCRTStartup()  Line 589 + 0x35 bytes    C
    Empire.UnityDebug.exe!wWinMainCRTStartup()  Line 414    C
    kernel32.dll!_BaseProcessStart@4()  + 0x23 bytes    
    

    “线程”选项卡如下所示:

    1008|wWinMainCRTStartup|CThreadSlotData::GetThreadValue|Normal|0
    

    偶尔,这也会出现在“线程”选项卡中:

    1596|_MixerCallbackThread@4|_KiFastSystemCallRet@0|Time Critical|0
    

    但一般来说,只有一个线程是活动的。

    2 回复  |  直到 16 年前
        1
  •  2
  •   Ben Voigt    16 年前

    您需要将Visual Studio的集成调试器放在一边,然后使用windbg,windbg知道等待对象,并具有用于查找等待对象的命令,以及(对于mutex和关键部分)线程当前拥有该对象的命令。

    可以在此处找到一些其他资源:

    http://www.debuginfo.com/articles/easywindbg.html#debugdeadlocks

    http://blogs.msdn.com/greggm/archive/2004/02/05/68232.aspx

    http://msdn.microsoft.com/en-us/magazine/cc164040.aspx

    http://dalelane.co.uk/blog/?p=19

        2
  •  0
  •   hatcat    16 年前

    我发现我的团队中的另一个成员在前面的几条指令中调用了TerminateThread而不是CloseHandle。解决了这个问题。不过,我还是得去温德伯格家看看。既然我们生活在一个多核的世界里,线程问题就会出现。