无法访问的AccessViolationException

时间:2010-04-28 08:19:36

标签: c# compact-framework native access-violation

我已经接近绝望了......我正在使用C#开发一个Windows Mobile 6.1的现场服务应用程序,而且还有一些p / Invoking。 (我想我正在引用大约50个原生函数)

在正常情况下,这没有任何问题,但是当我开始强调GC我得到一个令人讨厌的0xC0000005错误时,女巫似乎无法捕捉。在我的测试中,我正在快速关闭并打开一个对话框表单(表单确实利用了本机功能,但是为了测试我评论了这些)并且过了一段时间Windows Mobile错误记者来告诉我有一个致命的我的申请中出错。

我的代码在Application.Run(masterForm);周围使用try-catch并挂钩到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日]

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

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

2 个答案:

答案 0 :(得分:4)

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

AV最常见的两个原因是

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

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

堆腐败是可能的,也是最难的。这通常通过使用调试分配器调试调试版本中的代码来解决,该调试分配器监视堆的完整性。 <crtdbg.h>标题提供了一个。这不是一种保证的方法,你可以拥有一些非常讨厌的Heisenbugs,它们只能在Release版本中占据优势。除了仔细的代码审查之外,当时可用的选项很少。祝你好运,你需要它。

答案 1 :(得分:0)

事实证明这是由Interlocked引起的例外。

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

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

当我更改这一行时,整个过程都有效,所以似乎某个地方存在线程安全问题,但我无法弄明白。 (即,我不想浪费更多时间来搞清楚)

感谢帮助人员!