Application hanging during CoCreateInstance of .NET-based COM object

被刻印的时光 ゝ 提交于 2019-12-04 15:02:38

With the assistance of Microsoft support and DebugDiag we have determined that the cause of the problem seems to be related to a Loader Lock. Loader Lock is documented in detail at https://msdn.microsoft.com/en-us/library/ms173266(v=vs.120).aspx but basically, there are certain restrictions that apply to code that runs within the scope of DllMain or dynamic initialization of static un-managed code objects whose instances require dynamic initialization on loading the DLL (because they're in global scope). One way around this is to tell the C++ compiler that the code should be compiled with CLR support so it's not handling the initialization in DllMain, but rather another function that doesn't retain the loader lock.

In our code we had a global declaration:

CFSCoCultureWrapper cultureWrapper;

Which had a constructor that called CoCreateInstance on a managed COM object, which in turn had a reference to Microsoft.InteropToolbox. Applying the /clr switch to that one source file allowed the DLL to be loaded without hanging.

It's not clear why the behavior changed in different deployments, but, as the article linked states, the hang does not necessarily always occur, so these can be difficult problems to debug. To illustrate, even our simple test case was 4 levels deep loading DLLs before we encountered the problem - EXE loads (LoadLibrary) unmanaged DLL loads (CoCreateInstance) managed DLL loads Microsoft DLL. We decided with the level of complexity involved in these sorts of problems it was well enough understood and did not pursue further understanding why the problem only occurred in certain deployments.

Simple answer, don't create global instances of objects that load managed code during the constructor from unmanaged code. Use lazy initialization or switch the code file to use the /clr switch or use some means of preventing the execution of managed code during DllMain-time initialization. Another work-around we discovered was switching the managed code to use .NET 4.5 instead of 2.0.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!