C++/CLI应用程序在发布版本上随机崩溃

Jus*_*tin 4 random dll constructor c++-cli exception

我创建了一个C++/CLI混合DLL,我在C#Winforms应用程序中使用它.我仔细检查了Build config,以确保我链接到Debug模式下的调试库和Release中的非调试库.

现在应用程序什么都不做,只是在这样的托管包装器中创建一个本机类(单例模式以确保该类的单个实例):

static ManagedClassWrapper ^ GetInstance(){
                if(_me == nullptr){
                    _me = gcnew ManagedClassWrapper();
                    _me->_Impl = new NativeClass();
                }

                return _me;
            };
Run Code Online (Sandbox Code Playgroud)

其中_me和_impl是

private:
    NativeClass * _Impl;
    static ManagedClassWrapper ^ _me = nullptr;
Run Code Online (Sandbox Code Playgroud)

在单击按钮的表单中,我这样做:

private void button1_Click(object sender, EventArgs e)
{
    ManagedClassWrapper mcw = ManagedClassWrapper.GetInstance();
}
Run Code Online (Sandbox Code Playgroud)

我也像往常一样有一个标准的原生入口点DllMain.在我使用的DEBUG构建中

_CrtSetReportHook( QaDMemManager::report );
_CrtSetDbgFlag((_CRTDBG_LEAK_CHECK_DF) | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG));
Run Code Online (Sandbox Code Playgroud)

在DllMain的开头,在DEBUG构建中我也重新定义了新的:

#ifdef _DEBUG
#define _CRTDBG_MAP_ALLOC
#define LOG_LEVEL Logger::NOTICE
#include <stdlib.h>
#include <crtdbg.h>
#pragma warning(disable:4291)
#define new new(_NORMAL_BLOCK,__FILE__, __LINE__)
#else
#define LOG_LEVEL Logger::INFO
#endif
Run Code Online (Sandbox Code Playgroud)

正如我通常为我的非MFC应用程序做的那样,以获得良好的内存泄漏.

NativeClass的构造函数为空.

在Debug构建中一切正常,我看到本机代码中的内存泄漏,没有崩溃.

但是在Release版本中,当我点击那个按钮1时,我的应用程序中只有一次崩溃.这意味着:我可以启动我的应用程序的10个实例,9无论我点击button1多少次都可以正常工作,但每次点击button1时第10个都会崩溃(崩溃后我在异常窗口中点击继续等等我可以多次点击button1).

例外情况如下:

************** Exception Text **************
System.TypeInitializationException: The type initializer for '<Module>' threw an exception. ---> System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
   at _initterm((fnptr)* pfbegin, (fnptr)* pfend)
   at <CrtImplementationDetails>.LanguageSupport.InitializeNative(LanguageSupport* )
   at <CrtImplementationDetails>.LanguageSupport._Initialize(LanguageSupport* )
   at <CrtImplementationDetails>.LanguageSupport.Initialize(LanguageSupport* )
   at .cctor()
   --- End of inner exception stack trace ---
   at TestAudioInOut.TestForm.button1_Click(Object sender, EventArgs e)
   at System.Windows.Forms.Control.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ButtonBase.WndProc(Message& m)
   at System.Windows.Forms.Button.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)


************** Loaded Assemblies **************
mscorlib
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.1 (RTMRel.030319-0100)
    CodeBase: file:///C:/Windows/Microsoft.NET/Framework/v4.0.30319/mscorlib.dll
----------------------------------------
TestAudioInOut
    Assembly Version: 1.0.0.0
    Win32 Version: 1.0.0.0
    CodeBase: file:///V:/Test/bin/Release/Test.exe
----------------------------------------
System.Windows.Forms
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.1 built by: RTMRel
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Windows.Forms/v4.0_4.0.0.0__b77a5c561934e089/System.Windows.Forms.dll
----------------------------------------
System.Drawing
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.1 built by: RTMRel
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Drawing/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll
----------------------------------------
System
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.1 built by: RTMRel
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System/v4.0_4.0.0.0__b77a5c561934e089/System.dll
----------------------------------------
Mixed.DLL
    Assembly Version: 1.0.4026.39493
    Win32 Version: 
    CodeBase: file:///V:/Test/bin/Release/Mixed.DLL
----------------------------------------
Run Code Online (Sandbox Code Playgroud)

可能是什么问题(据我所知,TypeInitializationException意味着对象的构造有问题)以及为什么它只在Release模式下?

Han*_*ant 5

它与你发布的代码片段没有任何关系,在创建ManagedClassWrapper之前代码炸弹.该<Module>班是周围的一切,你写的非引用类代码的包装类.它在尝试调用非托管代码的初始化程序时会发生炸弹.这是一个AccessViolation,这是非托管代码采取行动的常用方法.

要调试它,您必须在C#项目中启用非托管调试.Project + Properties,Debug选项卡,勾选"启用非托管代码调试".然后调试+异常,勾选"Win32 Exceptions"上的Thrown标志.运行代码直到崩溃发生,调试器将停在崩溃位置.应该让你知道bug的位置.在使用非托管代码时,请使用您熟悉的常规调试技术.祝它好运.