From: j_3140 on
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
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

> 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
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
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. (-: