【问题标题】:C++/CLI application crashing randomly on Release buildsC++/CLI 应用程序在发布版本上随机崩溃
【发布时间】:2011-01-10 05:22:07
【问题描述】:

我创建了一个 C++/CLI 混合 DLL,我在 C# Winforms 应用程序中使用它。 我仔细检查了构建配置,以确保我链接到调试模式下的调试库和发布中的非调试库。

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

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

                return _me;
            };

_me 和 _impl 在哪里

private:
    NativeClass * _Impl;
    static ManagedClassWrapper ^ _me = nullptr;

在表单上单击按钮我就是这样做的:

private void button1_Click(object sender, EventArgs e)
{
    ManagedClassWrapper mcw = ManagedClassWrapper.GetInstance();
}

我也有一个标准的本地入口点,就像往常一样 DllMain。在 DEBUG 构建中,我使用

_CrtSetReportHook( QaDMemManager::report );
_CrtSetDbgFlag((_CRTDBG_LEAK_CHECK_DF) | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG));

在 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

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

NativeClass 的构造函数为空。

在调试版本中一切正常,我看到本机代码中存在内存泄漏,没有崩溃。

但在发布版本中,我的应用程序在 10 次中只有一次在我单击该按钮时崩溃 1。 这意味着:我可以启动我的应用程序的 10 个实例,无论我单击多少次 button1,9 个都可以正常工作,但是每次单击 button1 时,第 10 个实例都会崩溃(崩溃后我在异常窗口中单击 Continue 等等我可以多次点击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
----------------------------------------

可能是什么问题(据我了解,TypeInitializationException 表示对象的构造有问题)以及为什么它仅处于发布模式?

【问题讨论】:

  • 你不能将你的变量命名为_Impl,它是一个保留的标识符(所有的名字都是以下划线+大写字母开头的)。

标签: exception dll constructor random c++-cli


【解决方案1】:

它与您发布的代码 sn-p 没有任何关系,代码炸弹在 ManagedClassWrapper 被创建之前。 &lt;Module&gt; 类是您编写的所有非引用类代码的包装类。当它尝试调用非托管代码的初始化程序时,它会爆炸。这是一个 AccessViolation,非托管代码一头雾水的常用方法。

要对此进行调试,您必须在 C# 项目中启用非托管调试。项目+属性,调试选项卡,勾选“启用非托管代码调试”。然后 Debug + Exceptions,勾选“Win32 Exceptions”上的 Thrown 标志。运行您的代码直到崩溃发生,调试器将在崩溃位置停止。应该让您知道错误所在的位置。在使用非托管代码时,请使用您熟悉的常规调试技术。祝你好运。

【讨论】:

  • 感谢您的提示,唯一的问题是我无法在调试模式下重现崩溃,它仅在发布时发生,并且可能只有 10 次发生。我想,我将不得不尝试拿走我添加的所有东西和我一一更改的所有设置,看看什么时候崩溃会停止发生。
  • 您也可以调试发布版本。只是更难。
  • 哦,它似乎与这个有关:social.msdn.microsoft.com/Forums/en-US/clr/thread/… 并且修复在那里但我无法为 Dll 设置该入口点:(
  • 堆栈跟踪是任何非托管初始化代码的非常通用的。只要您只能看到托管堆栈跟踪而不是非托管代码的帧,它看起来总是一样的。您需要为其启用非托管调试。
  • 供将来参考,您能否记录下您为解决问题所做的具体更改?
猜你喜欢
  • 1970-01-01
  • 2017-03-15
  • 1970-01-01
  • 2015-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多