Почему моя MFC DLL блокируется в одном потоке рядом с автозагрузкой? - PullRequest
1 голос
/ 04 февраля 2010

Используя Visual Studio 2005, отладчик сообщает мне, что сразу после запуска приложения, которое я пишу, возникла тупиковая ситуация - я хорошо знаком с WinMain () на этом этапе. Стеки вызовов показывают, что мы находимся в критической секции, при этом вызывая AFX_MANAGE_STATE2 (в 666 раз, довольно пугающе) из MFC DLL. Это только начало происходить: вчера код работал нормально. Как ни странно, откат кода, перезагрузка компьютера и перестройка по-прежнему приводят к тупику.

Когда все останавливается, я нажимаю паузу на отладчике, и появляется сообщение (в конце концов):


Microsoft Visual Studio

Процесс, кажется, заблокирован (или не выполняется код пользовательского режима). Все темы были остановлены.

OK

Стек вызовов выглядит следующим образом:

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 ]

3 голосов
/ 06 февраля 2010

Вы захотите отложить в этом случае встроенный отладчик Visual Studio и использовать windbg, который знает об объектах ожидания и имеет команды для определения того, на каком объекте ожидают, и (для мьютексов и критических секций), которому принадлежит поток в данный момент объект.

Некоторые дополнительные ресурсы можно найти здесь:

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

0 голосов
/ 08 февраля 2010

Я обнаружил, что другой член моей команды вызвал TerminateThread вместо CloseHandle в функции несколькими инструкциями ранее. Исправление, которое решило проблему. Я посмотрю в WINDBG, хотя. Проблемы с потоками возникают, когда мы живем в многоядерном мире.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...