内存转储分析(应用程序挂起)

我试图分析我的应用程序中发生起后从我的最终用户收到的内存转储。 这似乎与我的应用程序的audio播放部分有关。 我相信有两个线程,即即将开始播放声音的主线程,以及一个更新线程,它迭代链表中的声音以不断更新其状态。 但是,我不明白这个挂机的来源是什么。

我的WinDbg的知识是有限的,但我已经设法弄清楚挂起似乎发生在audio库的SetLoop方法(在静态声音代码中)。 我使用DirectSound,在这种情况下应用程序运行在Windows 7 32位(我正在开发自己的XP,我从来没有像这样的问题)。 静态声音类会在检查声音是否正在播放之前locking关键部分,如果不是,则会将循环标记设置为true或false。 在这种情况下,主线程正在调用SetLoop将其设置为false,因为它想要以非循环状态播放声音。 我可以看到,挂起时,主线程停留在对ntdll.dll中的EtwEventEnabled调用,这显然是由静态声音类的SetLoop方法。 我不知道它是否卡在EnterCriticalSection调用中,或者是在调用DirectSound的GetStatus方法的辅助缓冲区的时候进一步下去? 这里是我对内存转储分析知识不足的地方,如果有人花时间看看转储,我将非常感激。

这里是转储的链接,具体应用符号如下: https : //dl.dropbox.com/u/5121962/hangdump.zip

非常感谢您的帮助。

    两个线程(一个是WinMain )正在等待没有所有者的相同关键部分03cb6ffc 。 看看StaticSound::UpdateStaticSound::SetLoop 。 也许线程目前正在终止仍然拥有一个关键部分。 尝试使用带锁的应用程序验证程序停止详细信息 – 验证关键部分的正确用法。

     0:000> !analyze -hang -v [...] BUGCHECK_STR: HANG [...] DERIVED_WAIT_CHAIN: Dl Eid Cid WaitType -- --- ------- -------------------------- 0 768.d1c Critical Section (Self) WAIT_CHAIN_COMMAND: ~0s;k;; BLOCKING_THREAD: 00000d1c DEFAULT_BUCKET_ID: APPLICATION_HANG_SELF_Unowned_CriticalSection PRIMARY_PROBLEM_CLASS: APPLICATION_HANG_SELF_Unowned_CriticalSection LAST_CONTROL_TRANSFER: from 77d56a24 to 77d57094 [...] 0:000> !locks CritSec +13af7d0 at 013af7d0 WaiterWoken No LockCount 0 RecursionCount 1 OwningThread 10a8 EntryCount 0 ContentionCount 2b7 *** Locked CritSec +3cb6ffc at 03cb6ffc WaiterWoken No LockCount 2 RecursionCount 0 OwningThread 0 EntryCount 0 ContentionCount d *** Locked 0:000> ~* . 0 Id: 768.d1c Suspend: 0 Teb: 7ffde000 Unfrozen Start: pontefract_timer!WinMainCRTStartup (01299030) Priority: 0 Priority class: 32 Affinity: f [...] 4 Id: 768.10a8 Suspend: 0 Teb: 7ffdb000 Unfrozen Start: pontefract_timer!_threadstartex (012ae09f) Priority: 2 Priority class: 32 Affinity: f [...] 0:004> kb ChildEBP RetAddr Args to Child 021af9b4 77d56a24 77d42278 000002f0 00000000 ntdll!KiFastSystemCallRet 021af9b8 77d42278 000002f0 00000000 00000000 ntdll!ZwWaitForSingleObject+0xc 021afa1c 77d4215c 00000000 00000000 00000000 ntdll!RtlpWaitOnCriticalSection+0x13e 021afa44 012882c2 03cb6ffc 013af7cc 00326ee8 ntdll!RtlEnterCriticalSection+0x150 021afa60 0128a1ed 021afa8c 021afa80 013af810 pontefract_timer!StaticSound::Update+0x12 021afa84 012ae079 013af700 73a14e26 00000000 pontefract_timer!UpdaterTick+0x7d 021afabc 012ae103 00000000 021afad4 7750ed6c pontefract_timer!_callthreadstartex+0x1b 021afac8 7750ed6c 013af810 021afb14 77d7377b pontefract_timer!_threadstartex+0x64 021afad4 77d7377b 013af810 6b63b5bd 00000000 kernel32!BaseThreadInitThunk+0xe 021afb14 77d7374e 012ae09f 013af810 00000000 ntdll!__RtlUserThreadStart+0x70 021afb2c 00000000 012ae09f 013af810 00000000 ntdll!_RtlUserThreadStart+0x1b 0:000> kb ChildEBP RetAddr Args to Child 0020c39c 77d56a24 77d42278 000002f0 00000000 ntdll!KiFastSystemCallRet 0020c3a0 77d42278 000002f0 00000000 00000000 ntdll!ZwWaitForSingleObject+0xc 0020c404 77d4215c 00000000 00000000 774f8e38 ntdll!RtlpWaitOnCriticalSection+0x13e 0020c42c 012881af 03cb6ffc 00000000 03cb6ff8 ntdll!RtlEnterCriticalSection+0x150 0020c440 0128682c 00000000 00000000 00000000 pontefract_timer!StaticSound::SetLoop+0xf 0020c460 012616ac 00000000 00000000 01765bac pontefract_timer!DeviceManager::SetLoop+0x6c 0020c474 0121a2ce 01a46ddc 00000000 0178ea9c pontefract_timer!BgtSound::play+0x6c 0020c61c 01219d02 0178ea9c 01765bf4 01a46ddc pontefract_timer!CallSystemFunctionNative+0x42e 0020c64c 0121d450 00000000 00000000 0178ea9c pontefract_timer!CallSystemFunction+0xd2 0020c6d4 0121c276 01a46dfc 77b6ea11 00000000 pontefract_timer!asCContext::ExecuteNext+0x930 0020c708 0127a293 719b431a 0020f780 00000000 pontefract_timer!asCContext::Execute+0x1d6 0020f780 0127a1d5 719b4c6a 77b1f2a9 0010000c pontefract_timer!execute+0x83 0020f8f0 0127acff 77b1f2a9 77b18d02 0020f958 pontefract_timer!RunApplication+0x805 0020f908 0127b085 0020f908 0127b339 00000000 pontefract_timer!run_script+0x9f 0020f910 0127b339 00000000 00000000 7ffdf000 pontefract_timer!main_game+0x35 0020f958 01298fdd 01210000 00000000 00361f32 pontefract_timer!WinMain+0x2a9 0020f9e8 7750ed6c 7ffdf000 0020fa34 77d7377b pontefract_timer!__tmainCRTStartup+0x11a 0020f9f4 77d7377b 7ffdf000 6959b49d 00000000 kernel32!BaseThreadInitThunk+0xe 0020fa34 77d7374e 01299030 7ffdf000 00000000 ntdll!__RtlUserThreadStart+0x70 0020fa4c 00000000 01299030 7ffdf000 00000000 ntdll!_RtlUserThreadStart+0x1b 

    你可以尝试使用微软的调试诊断工具分析转储 – 它似乎证实了你的怀疑,但是如果你不知道代码或你的exe的发布版PDB,我无法从调用堆栈获得更多的信息。

    从报告(您可以使用该工具自行运行完整分析)涉及两个线程 – 摘要如下:

    问题摘要

    线程0和4的调用堆栈如下所示:

    线程0

    和…

    线程4

    这些可能会给你一些更多的信息,让你再次移动….

    希望有所帮助,

    罗杰