简体   繁体   English

当c#程序崩溃怎么知道为什么?

[英]when c# program crash how to know why?

Often my program crash by some reason.我的程序经常由于某种原因崩溃。 In this case I do see Windows message with "Close" button.在这种情况下,我确实看到带有“关闭”按钮的 Windows 消息。 Every time such thing happen I do really want to know what happened.每次发生这样的事情,我真的很想知道发生了什么。

Thanks to community I already know how to "handle" some situations, I've added such code in the beggining of my program:感谢社区,我已经知道如何“处理”某些情况,我在程序的开头添加了这样的代码:

    static void Main(string[] args)
    {
        AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;

        TaskScheduler.UnobservedTaskException +=
        (object sender, UnobservedTaskExceptionEventArgs excArgs) =>
        {
            Log.Push(LogItemType.Error, "Exception occured. Task terminated! + " + excArgs.Exception);
            excArgs.SetObserved();
        };

    .....

    static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        Console.WriteLine("Error: CurrentDomain_UnhandledException entered.");
        string message = (e.ExceptionObject as Exception).Message;
        Console.WriteLine(message);
        System.Diagnostics.Trace.WriteLine(message, "Unhandled UI Exception");
        Log.Push(LogItemType.Error, message);
    }

Sometimes this helps.有时这会有所帮助。 But sometimes program just crash with no message.但有时程序只是崩溃而没有消息。 What else can I do?我还可以做些什么? Every time program crash I want to know why.每次程序崩溃我都想知道为什么。

upd Windows Logs contains almost everything I need, except the most important thing - the stacktrace upd Windows 日志包含我需要的几乎所有东西,除了最重要的东西 - 堆栈跟踪

Faulting application name: MBClient.exe, version: 1.0.0.0, time stamp: 0x50a5da1d
Faulting module name: ntdll.dll, version: 6.1.7601.17725, time stamp: 0x4ec4aa8e
Exception code: 0xc0000374
Fault offset: 0x00000000000c40f2
Faulting process id: 0x10f8
Faulting application start time: 0x01cdc3c2041e2607
Faulting application path: C:\Oleg\bin\mbclient\MBClient.exe
Faulting module path: C:\Windows\SYSTEM32\ntdll.dll
Report Id: 810c805d-2fc3-11e2-bfb5-2c768a509157

Exception code 0xc0000374 means you're facing heap corruption .异常代码 0xc0000374 表示您正面临堆损坏

The most common causes for this kind of error are these two:此类错误的最常见原因是以下两个:

  • A faulty RAM module有故障的 RAM 模块
  • Buffer overrun, when one thread tries to read something and another thread has removed data in the meanwhile.缓冲区溢出,当一个线程尝试读取某些内容而另一个线程同时删除了数据时。 This shouldn't happen in managed code as far as I can tell.据我所知,这不应该发生在托管代码中。

You probably have to get Windows Debugging Tools to figure out what's wrong if you can't debug the application in the dev environment.如果您无法在开发环境中调试应用程序,您可能必须使用Windows 调试工具来找出问题所在。

You can try to use the WER - Microsofts Windows Error Reporting for that.您可以尝试使用 WER - Microsoft 的 Windows 错误报告。 It is per default on every system.它在每个系统上都是默认的。 So eg you can do an automatic dump instead of the windows popup message.因此,例如,您可以进行自动转储而不是窗口弹出消息。
There are a number of settings in the group policy editor.组策略编辑器中有许多设置。 see the following links http://msdn.microsoft.com/en-us/library/windows/desktop/bb787181(v=vs.85).aspx http://msdn.microsoft.com/en-us/library/windows/desktop/bb513638%28v=vs.85%29.aspx请参阅以下链接http://msdn.microsoft.com/en-us/library/windows/desktop/bb787181(v=vs.85).aspx http://msdn.microsoft.com/en-us/library/ windows/桌面/bb513638%28v=vs.85%29.aspx

I know this is an old question, but I came here after googling the exception code 0xc0000374.我知道这是一个老问题,但我在谷歌搜索异常代码 0xc0000374 后来到这里。

There is an update available for the MS Visual C++ 2013 Redistributable package that fixes a heap corruption bug in the MS Visual C++ 2013 redistributable package.有一个可用于 MS Visual C++ 2013 Redistributable 包的更新,它修复了 MS Visual C++ 2013 Redistributable 包中的堆损坏错误。

Note: This update is (at time of writing) not being distributed through Windows Update.注意:此更新(在撰写本文时)未通过 Windows 更新分发。 Note 2: Obviously, this update will only help, if you are using a library compiled with MS VC++ 2013 (like in my case: the MySQL ODBC Connector 5.3.x)注意 2:显然,如果您使用的是使用 MS VC++ 2013 编译的库(如我的情况:MySQL ODBC 连接器 5.3.x),此更新只会有帮助

The update link: https://support.microsoft.com/en-us/help/3138367/update-for-visual-c-2013-and-visual-c-redistributable-package更新链接:https: //support.microsoft.com/en-us/help/3138367/update-for-visual-c-2013-and-visual-c-redistributable-package

And the source that pointed me to this update: https://bugs.mysql.com/bug.php?id=86054以及将我指向此更新的来源: https ://bugs.mysql.com/bug.php?id=86054

In my case:就我而言:

I use unmanaged memory.我使用非托管内存。 So the most simple way to REPRODUCE this bug is:因此,重现此错误的最简单方法是:

var DataPtr = Marshal.AllocHGlobal(1000 * sizeof(int));//asign a pointer for 1000 integers
Marshal.FreeHGlobal(ptr);
Marshal.FreeHGlobal(ptr);

If you try this you'll get:如果你试试这个,你会得到:

The program '[12579] MyDemo.exe' has exited with code -1073740940 (0xc0000374).

So if you use such code [Alloc\Free] you might have copied some pointer to already released memory and later on release it, after it's already released.因此,如果您使用这样的代码 [Alloc\Free],您可能已经复制了一些指向已释放内存的指针,然后在它已经释放之后再释放它。

Hope this helps someone!希望这对某人有帮助!

I was able to obtain a CLR call stack by using WinDbg Preview .我能够使用WinDbg Preview获得 CLR 调用堆栈。

  1. Install and launch WinDbg Preview安装并启动 WinDbg 预览版
  2. Through the file menu, launch the application executable (may have to click the "Go" button in WinDbg if the application doesn't launch immediately)通过文件菜单,启动应用程序可执行文件(如果应用程序没有立即启动,可能需要单击 WinDbg 中的“开始”按钮)
  3. Perform some actions in the application that would trigger the ntdll.dll crash在应用程序中执行一些会触发 ntdll.dll 崩溃的操作
  4. (Optional) If you have.pdb files available, enter .symfix <path to folder containing pdb files> in the WinDbg command line (可选)如果您有 .pdb 文件可用,请在 WinDbg 命令行中输入.symfix <path to folder containing pdb files>
  5. Enter clrstack in the WinDbg command line (you can also use dumpstack to get a more detailed view).在 WinDbg 命令行中输入clrstack (也可以使用dumpstack获得更详细的视图)。

You should now see the full CLR call stack in the WinDbg output window, which should give you an indication of which part of your code caused the ntdll.dll crash.您现在应该在 WinDbg output window 中看到完整的 CLR 调用堆栈,它应该可以指示您的代码的哪一部分导致了 ntdll.dll 崩溃。

在此处输入图像描述

只需在您认为可能崩溃的代码“危险”部分使用try catch

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM