I have a WinForms application which uses a couple of C++/CLI DLLs which in turn link with Boost. Because of some quirkiness with Boost or the std library, when I exit this application normally (even right after it loads) it crashes due to double-freeing a C++ locale facet. To get around this, I started using Process.GetCurrentProcess().Kill()
, but later switched to using Environment.Exit(0)
when I needed a normal exit to have a 0 exit code (i.e. for automated testing).
I just upgraded the dependencies from .NET 4 and Boost 1.54 compiled with VS 2010 to .NET 4.5 and Boost 1.56 compiled with VS 2013. Before the upgrade, Environment.Exit(0)
was working fine. After the upgrade, it hangs indefinitely. When I switch back to Process.GetCurrentProcess().Kill()
, it exits fine (except for the exit code). When I let it close normally without any workaround, I still get the locale facet crash (so I guess the problem in Boost or std C++ didn't get fixed). So I still need the workaround to work.
Some strange things I've observed:
- when I close the program and it hangs, then open up the Threads tab for the process in Process Explorer, the process finishes closing
- when I open the Threads tab for the process, THEN close the program, it hangs; even when I switch away from the Threads tab and back it stays hung
- in the latter case, there is a single thread still running (or waiting). The thread's start address is "!.ctor". The InteropQonverter.dll call to some Boost code attracted my attention, but I don't know if it's an accurate stack trace since this is a release build. InteropQonverter.dll is one of my C++/CLI DLLs obviously. But it doesn't use boost::serialization AFAIK.
Any ideas what's causing this or how to fix it?
Edit: Here's the stack trace from the debug build, which has the same symptoms. It makes more sense that it's hanging in the CRT init of my DLL. It seems to have thrown an exception, but I can't catch it?
ntdll.dll!ZwDelayExecution() + 0xa bytes
KernelBase.dll!SleepEx() + 0xb3 bytes
ntdll.dll!RtlpExecuteHandlerForException() + 0xd bytes
ntdll.dll!RtlDispatchException() + 0x38f bytes
ntdll.dll!KiUserExceptionDispatch() + 0x2e bytes
KernelBase.dll!RaiseException() + 0x3d bytes
InteropQonverter.dll!_CRT_INIT(void * hDllHandle, unsigned long dwReason, void * lpreserved) Line 415 C
InteropQonverter.dll!__DllMainCRTStartup(void * hDllHandle, unsigned long dwReason, void * lpreserved) Line 526 + 0x13 bytes C
InteropQonverter.dll!_DllMainCRTStartup(void * hDllHandle, unsigned long dwReason, void * lpreserved) Line 477 C
mscoreei.dll!000007fef8405795()
[Frames below may be incorrect and/or missing, no symbols loaded for mscoreei.dll]
mscoree.dll!ShellShim__CorDllMain() + 0xe1 bytes
mscoree.dll!_CorDllMain_Exported() + 0x37 bytes
ntdll.dll!LdrShutdownProcess() + 0x1d1 bytes
ntdll.dll!RtlExitUserProcess() + 0x90 bytes
mscoreei.dll!000007fef83f3067()
mscoreei.dll!000007fef83f3300()
mscorlib.ni.dll!000007fef706188b()
[Managed to Native Transition]
mscorlib.dll!System.Environment.Exit(int exitCode) + 0x7b bytes
IDPicker.exe!IDPicker.IDPickerForm.IDPickerForm_FormClosing(object sender, System.Windows.Forms.FormClosingEventArgs e) Line 1593 + 0x7 bytes C#