Prev: SetWindowLong GWL_WNDPROC XP,2003 - SOLVED
Next: Deadly embrace between SetUnhandledExceptionFilter() and thread rundown(???) in Server 2003
From: j_3140 on 4 Jan 2010 18:16 When our application starts up we call SetUnhandledExceptionFIlter() and save off the address it returns as the current exception handler. When we're exiting we pass this saved value back into SetUnhandledExceptionFIlter() to re-establish the exception handler that existed before we started. We also start a couple of threads. Very occasionally we find that we don't shut down cleanly and if we take a look with the debugger we find two thread in the process with the following call stacks. It appears there is some kind of deadly embrace in the use of critical sections between the code in SetUnhandledExceptionFilter() and whatever code the other thread is running (probably as part of thread cleanup but we're not sure). This is Windows Server 2003 R2 SP2 (Enterprise Edition). Does anyone know whether this is a known problem? Something which has been fixed perhaps in Server 2008? Thread #1: 0 > 3520 Main Thread Main Thread _unlock Normal 0 0 3200 Worker Thread Win32 Thread 7c82860c Normal 0 ntdll.dll!_ZwWaitForSingleObject(a)12() + 0xc bytes ntdll.dll!_RtlpWaitOnCriticalSection@8() - 0xe4 bytes ntdll.dll!_RtlEnterCriticalSection@4() + 0x22f51 bytes ntdll.dll!_LdrLockLoaderLock(a)12() + 0x6b bytes kernel32.dll!_GetModuleFileNameW(a)12() + 0x51 bytes kernel32.dll!_FillUEFInfo@8() + 0x4d bytes > kernel32.dll!_SetUnhandledExceptionFilter@4() + 0x2b bytes <user program calls SetUnhandledExceptionFilter()> <user program frames> digger.exe!__tmainCRTStartup() Line 586 + 0x17 bytes C kernel32.dll!_BaseProcessStart@4() + 0x23 bytes Thread #2: 0 3520 Main Thread Main Thread _unlock Normal 0 0 > 3200 Worker Thread Win32 Thread 7c82860c Normal 0 ntdll.dll!_KiFastSystemCallRet@0() ntdll.dll!_ZwWaitForSingleObject(a)12() + 0xc bytes ntdll.dll!_RtlpWaitOnCriticalSection@8() - 0xe4 bytes ntdll.dll!_RtlEnterCriticalSection@4() + 0x22f51 bytes > ntdll.dll!_LdrpInitializeThread@4() + 0x47 bytes ntdll.dll!__LdrpInitialize(a)12() + 0x56 bytes ntdll.dll!_KiUserApcDispatcher(a)16() + 0x25 bytes <top of stack>
From: Joey on 6 Jan 2010 11:07 On Jan 5, 3:14 am, "Jochen Kalmbach [MVP]" <nospam-n...(a)kalmbach- software.de> wrote: > > IMHO there is no need to restore the original handler... > > -- Thank you for the suggestion. We included this code because we may be loaded as a DLL by some other software package which may have a handler of its own and we are trying to be a good citizen and leave the process state the same as we found it. I suppose we could just remove this call to SetUnhandledExceptionFilter () but that still leaves a question as to whether there is some bug here in the kernel which needs to be fixed. In general this kind of deadly embrace is because someone has messed up the order of acquisition of resources so the two threads are blocking each other.
From: Pavel Lebedinsky [MSFT] on 7 Jan 2010 02:23 > Thread #1: > ntdll.dll!_RtlEnterCriticalSection@4() + 0x22f51 bytes > ntdll.dll!_LdrLockLoaderLock(a)12() + 0x6b bytes > kernel32.dll!_GetModuleFileNameW(a)12() + 0x51 bytes > kernel32.dll!_FillUEFInfo@8() + 0x4d bytes >> kernel32.dll!_SetUnhandledExceptionFilter@4() + 0x2b bytes > > Thread #2: > ntdll.dll!_RtlpWaitOnCriticalSection@8() - 0xe4 bytes > ntdll.dll!_RtlEnterCriticalSection@4() + 0x22f51 bytes >> ntdll.dll!_LdrpInitializeThread@4() + 0x47 bytes > ntdll.dll!__LdrpInitialize(a)12() + 0x56 bytes To me it looks like both of these threads are blocked on the loader lock. Can you check which thread owns it? In windbg/cdb you can use the following command to do this: 0:000> !cs ntdll!LdrpLoaderLock -- Pavel Lebedinsky/Windows Fundamentals Test This posting is provided "AS IS" with no warranties, and confers no rights.
From: m on 8 Jan 2010 21:16 In my experience, several of the Windows DLLs do not shutdown cleanly (specifically DNS APIs and others) and a call to ExitProcess from the main thread is necessary. This is usually performed by the CRT when Main returns, but may not be for some special applications. IMHO, the shutdown logic is less well tested and debugged in Windows than the other APIs. <j_3140(a)yahoo.com> wrote in message news:2340b5b1-382a-4285-9a8a-91d0724eeb1b(a)f5g2000yqh.googlegroups.com... > When our application starts up we call SetUnhandledExceptionFIlter() > and save off the address it returns as the current exception handler. > When we're exiting we pass this saved value back into > SetUnhandledExceptionFIlter() to re-establish the exception handler > that existed before we started. We also start a couple of threads. > > Very occasionally we find that we don't shut down cleanly and if we > take a look with the debugger we find two thread in the process with > the following call stacks. It appears there is some kind of deadly > embrace in the use of critical sections between the code in > SetUnhandledExceptionFilter() and whatever code the other thread is > running (probably as part of thread cleanup but we're not sure). > > This is Windows Server 2003 R2 SP2 (Enterprise Edition). > > Does anyone know whether this is a known problem? Something which has > been fixed perhaps in Server 2008? > > Thread #1: > 0 > 3520 Main Thread Main Thread _unlock Normal 0 > 0 3200 Worker Thread Win32 Thread 7c82860c Normal 0 > ntdll.dll!_ZwWaitForSingleObject(a)12() + 0xc bytes > ntdll.dll!_RtlpWaitOnCriticalSection@8() - 0xe4 bytes > ntdll.dll!_RtlEnterCriticalSection@4() + 0x22f51 bytes > ntdll.dll!_LdrLockLoaderLock(a)12() + 0x6b bytes > kernel32.dll!_GetModuleFileNameW(a)12() + 0x51 bytes > kernel32.dll!_FillUEFInfo@8() + 0x4d bytes >> kernel32.dll!_SetUnhandledExceptionFilter@4() + 0x2b bytes > <user program calls SetUnhandledExceptionFilter()> > <user program frames> > digger.exe!__tmainCRTStartup() Line 586 + 0x17 bytes C > kernel32.dll!_BaseProcessStart@4() + 0x23 bytes > > Thread #2: > 0 3520 Main Thread Main Thread _unlock Normal 0 > 0 > 3200 Worker Thread Win32 Thread 7c82860c Normal 0 > ntdll.dll!_KiFastSystemCallRet@0() > ntdll.dll!_ZwWaitForSingleObject(a)12() + 0xc bytes > ntdll.dll!_RtlpWaitOnCriticalSection@8() - 0xe4 bytes > ntdll.dll!_RtlEnterCriticalSection@4() + 0x22f51 bytes >> ntdll.dll!_LdrpInitializeThread@4() + 0x47 bytes > ntdll.dll!__LdrpInitialize(a)12() + 0x56 bytes > ntdll.dll!_KiUserApcDispatcher(a)16() + 0x25 bytes > <top of stack> >
From: m on 19 Jan 2010 19:42
Uh - why? The behaviour is easy to reproduce: create an application that does not use the CRT, or any other ENV, call certain APIs on some versions of Windows, and return from your entry point. The process will not die because ExitProcess was NOT called from the CRT wrapper code and there are running threads. To work around this problem, ensure that ExitProcess is always called. As good programming practice, one should always clean up resources, including exiting worker threads, before process exit. "Jonathan de Boyne Pollard" <J.deBoynePollard-newsgroups(a)NTLWorld.COM> wrote in message news:IU.20100115.015649.22ea.5(a)J.de.Boyne.Pollard.localhost... In my experience, several of the Windows DLLs do not shutdown cleanly (specifically DNS APIs and others) and a call to ExitProcess from the main thread is necessary. I suggest that you read the aforelinked, too. (-: |