【发布时间】:2012-09-17 09:44:25
【问题描述】:
我有一个计算量很大的多线程 C# 应用程序,它似乎在运行 30-90 分钟后一直崩溃。它给出的错误是
运行时遇到致命错误。错误地址位于线程 0xbcc 上的 0xec37ebae。错误代码为 0xc0000005。此错误可能是 CLR 中的错误或用户代码的不安全或不可验证部分中的错误。此错误的常见来源包括 COM-interop 或 PInvoke 的用户封送错误,这可能会损坏堆栈。
(0xc0000005 是Access Violation 的错误代码)
我的应用不调用任何本机代码,也不使用任何不安全的块,甚至不使用任何不符合 CLS 的类型,例如 uint。事实上,调试器所说的导致崩溃的代码行是
overallLength += distanceTravelled;
其中两个值的类型均为double
鉴于这一切,我认为崩溃一定是由于编译器或 CLR 或 JIT 中的错误。我想弄清楚是什么原因造成的,或者至少写一个较小的复制品发送给微软,但我什至不知道从哪里开始。我从来不需要查看 CIL 二进制文件、编译的 JIT 输出或本机堆栈跟踪 (崩溃时没有托管堆栈跟踪),所以我不确定如何.我什至无法弄清楚如何在崩溃时查看所有变量的状态(不幸的是,VS 不会像在托管异常之后那样告诉我,并将它们输出到控制台/文件会将应用程序减慢 1000 倍,这显然不是一种选择)。
那么,我该如何调试呢?
[编辑] 在 VS 2010 SP1 下编译,运行最新版本的 .Net 4.0 Client Profile。显然是 ".Net 4.0C/.Net 4.0E, .Net CLR 1.1.4322"
【问题讨论】:
-
你确定不是你的电脑内存问题?当指针损坏并设置为无效的内存位置时,我在其他程序中看到了相同的错误代码。
-
@Matthew:我将运行一些内存测试,并尝试在另一台机器上重现它。但我对此表示怀疑 - 该程序不是很占用内存,而且我对任何其他程序都没有任何问题。此外,它总是在同一行崩溃。
-
我不熟悉 CLR,但是在 Sun JVM 上,有一个标志可以记录所有已编译的方法——如果您可以确定 (1) 是否调用了 JIT,这可能会有所帮助,以及 (2) 崩溃发生后多长时间。可能有一个工具可以让您检查内存映射以找出在该地址加载的内容(甚至是否在代码块中)。
-
@AlexeiLevenkov:详细说明如何执行这些技巧和类似技巧的答案正是我想要的。
-
@BlueRaja-DannyPflughoeft 您能否回答 Jon 的一些问题:例如,您是否能够在另一台机器上复制?您可以在更新当前 PC 上的所有内容后重现吗?你能轻松地复制它吗(即即使需要 90 分钟也可以按需复制)?如果其中任何一个的答案是“是”,那么您应该通过 WinDbg 启动您的进程,该进程将在您的应用退出(崩溃)之前中断,这样您就可以看到发生了什么
标签: c# .net debugging compiler-errors jit