2

我快要绝望了。我正在使用 C# 和一些 p/Invoking 为 Windows Mobile 6.1 开发现场服务应用程序。(我想我引用了大约 50 个本机函数)

在正常情况下,这没有任何问题,但是当我开始强调 GC 时,我得到了一个令人讨厌的 0xC0000005 错误,女巫似乎无法捕获。在我的测试中,我正在快速关闭并打开一个对话框表单(该表单确实使用了本机功能,但为了测试,我将这些注释掉了),过了一会儿,Windows Mobile 错误报告器过来告诉我有一个致命的我的应用程序中的错误。

我的代码在事件中使用了 try-catchApplication.Run(masterForm);并挂钩CurrentDomain.UnhandledException,但应用程序仍然崩溃。即使我附加了调试器,Visual Studio 也会在发生异常时告诉我“与设备的远程连接已丢失”。

由于我没有成功在托管环境中捕获异常,因此我试图从 Error Reporter 日志文件中找出意义。但这没有任何意义,关于错误的唯一一致的是它发生的应用程序。

我不知道应用程序发生的线程,发生错误的模块有时会有所不同(我见过我的application.exe,WS2.dll,netcfagl3_5.dll和mscoree3_5.dll),甚至错误代码并不总是一样的。(大多数时候是 0xC0000005,但我也看到了 0X80000002 错误,这是第一个字节的警告?)

我尝试通过 bugtrap 进行调试,但奇​​怪的是,这会以相同的错误代码 (0xC0000005) 崩溃。我试图用visual studio打开kdmp文件,但我似乎没有任何意义,因为它只在我步入错误时显示反汇编代码(除非我有正确的.pbb文件,我没有't)。WinDbg 也是如此。

长话短说:坦率地说,我不知道在哪里寻找这个错误,我希望 stackoverflow 上有一些聪明的灵魂。我很高兴提供一些代码,但目前我不知道要提供哪一部分..

任何帮助是极大的赞赏!

[编辑 2010 年 5 月 3 日]

正如您在我对 Hans 的评论中看到的那样,我在取消所有 P/Invokes 的注释后重新测试了整个程序,但这并没有解决我的问题。我尝试用尽可能少的代码重现错误,最终看起来多线程访问给我带来了所有问题。

在我的应用程序中,我有一个用作手指/轻弹滚动列表的用户控件。在这个控件中,我为列表中的每个项目使用一个位图作为画布。在这个画布上绘图是由一个单独的线程处理的,当我禁用这个线程时,错误似乎消失了。我会对此做更多的测试,并将结果发布在这里。

4

2 回答 2

4

捕获此异常不是一种选择。这是线程可能遭受的最严重的心脏病发作,CPU 检测到严重问题并且无法继续运行代码。这总是由行为不端的非托管代码引起的,听起来您的程序中运行了很多它。您需要专注于调试非托管代码才能到达某个地方。

两个最常见的 AV 原因是

  • 堆损坏。非托管代码不正确地将数据写入堆,破坏了堆的结构完整性。通常由溢出分配的内存块的边界引起。或者在释放后使用堆块。很难诊断,异常会在损坏完成后很长时间内引发。

  • 堆栈损坏。最常见的原因是溢出在堆栈上分配的数组的边界。这可以覆盖堆栈上其他变量的值或破坏函数返回地址。更容易诊断,它往往会很好地重复并且有立竿见影的效果。一个副作用是调试器失去了在损坏完成后立即显示调用堆栈的能力。

堆损坏是可能的,也是最难的。这通常通过使用调试分配器调试调试构建中的代码来解决,该调试分配器监视堆的完整性。标题<crtdbg.h>提供了一个。这不是一种有保证的方法,您可能会遇到一些非常讨厌的 Heisenbug,它们只会在发布版本中抬起头来。除了仔细的代码审查之外,可用的选项很少。祝你好运,你会需要它。

于 2010-04-28T12:32:24.243 回答
0

原来是Interlocked引起的异常。

在我的代码中,有一个整数_drawThreadIsRunning在绘制线程运行时设置为 1,否则设置为 0。我使用互锁设置这个值:

if (Interlocked.Exchange(ref _drawThreadIsRunning, 1) == 0) { /* run thread */ }

当我改变这条线时,整个事情都起作用了,所以似乎某个地方的线程安全存在问题,但我无法弄清楚。(即。我不想浪费更多时间弄清楚)

谢谢你们的帮助!

于 2010-05-25T14:14:46.270 回答