C ++ / CLI程序集中的异常0xC0020001

Exception 0xC0020001 in C++/CLI assembly

The string binding is invalid. This is what happens when I try to shut down a fairly complex application that consists of a C# EXE using a C++/CLI DLL than in turn references several C++ native static libraries and DLLs. (I'm using VS2013 and Boost 1.55.)

The problem occurs because _atexit (on DLL termination) is trying to call _t2m@???__Fep@?1???$get_static_exception_object@Ubad_exception_@exception_detail@boost@@@exception_detail@boost@@YA?AVexception_ptr@1@XZ@YAXXZ@?A0x8b93c95f@@YAXXZ, which is a native-to-managed thunk, and the CLR has presumably already been shut down by that point.

My main question is why a managed thunk is being registered in a native termination handler, since by definition that can't work. A related question is why a managed thunk is being generated for this type at all, since as far as I can tell every single #include of anything that could reference this type is either in a non-/clr-compiled file, or in a #pragma unmanaged block in a /clr-compiled file, so there shouldn't be any managed versions of it at all. (The help for #pragma managed says that it's the point of definition that defines whether templates are managed or not, not the point of instantiation.)

Perhaps I'm wrong about this, but I've always assumed that when #includeing the header file for native types (implemented in a non-/clr file) in a /clr file, it should be wrapped in an unmanaged block to prevent ODR problems.

A question (that I remember reading here but can't now find a link to) suggests that the solution is to remove all the pragmas and just let the compiler figure it out. However doing that results in Managed Debugging Assistant 'LoaderLock' has detected a problem on startup. (The call stack just points to the C# code that causes the C++/CLI DLL to be loaded, which is not entirely helpful.)

This question suggests that there's a compiler bug regarding template instantiation. Given that get_static_exception_object is a template, this seems plausible, but I'm not sure how to work around it.

Although another function that is similarly registered incorrectly is _t2m@???__FstrMgr@?1??GetInstance@CAtlStringMgr@ATL@@SAPAUIAtlStringMgr@2@XZ@YAXXZ@@YAXXZ, which is not a template, so that might be a red herring.

(I've tried reproducing the problem in a smaller example, but haven't been able to do so yet. Clearly there's some trigger I'm unaware of.)