有哪些技术可以解决Windows Mobile设备上非常间歇性的访问冲突问题?

时间:2008-12-31 13:28:56

标签: windows-mobile compact-framework access-violation

我有一个大型Compact Frameworks V2.0应用程序,在大多数情况下效果很好。在某些设备上大约每天一次,用户会收到未被标准托管的Try / Catch块捕获的本机错误0xC0000005。

我的应用程序以固定间隔通过ASMX呼叫与服务器同步。问题似乎发生在同步过程中。除了在同步时发生的ASMX调用之外,还有相当多的业务逻辑,但其中98%是托管代码。我已经回顾了我的所有P / Invokes和应用程序本机C ++库,此时我大约95%确定不是问题所在。

由于这只发生在某些设备上并且很少发生(每天不到一次),因此很难隔离。我已经对我的代码进行了解释,看起来好像它发生在应用程序中的随机位置,所以我怀疑某些东西会破坏内存。

有关如何进一步排除故障的任何想法都将不胜感激。

2 个答案:

答案 0 :(得分:5)

0xC0000005是一种访问冲突,因此有些东西试图读取或写入一个它无权访问的地址。这些往往很难找到,而且经验是最好的工具之一(而Platform Builder的调试器也非常有用,但这是一个完全独立的调试途径,需要你可能没有的经验,或者你已经拥有过的经验尝试过)。我发现,减法编码往往没那么有用 - 只要有可能就用模拟托管调用删除P / invoke调用。

托管应用中的访问冲突通常是由于以下原因之一而发生的:

  • 您P /调用传递托管对象句柄的本机API,本机A​​PI使用该句柄。如果在本机API运行时获得收集和压缩,则托管对象可能会移动并且指针变为无效。
  • 你P /调用某个缓冲区,该缓冲区太小或小于你传入的大小,并且API超出了读或写
  • 传递给P / Invoke调用的指针(IntPtr等)无效(-1或0),本机在使用前未检查
  • 你P /调用本机调用,本机代码内存不足(通常是虚拟的),并且没有检查失败的分配和对无效地址的读/写
  • 您使用未初始化的GCHandle或以某种方式指向已经完成并收集的对象(因此它不指向对象,它指向的对象曾经是一个地址)
  • 您的应用使用句柄来处理因睡眠/唤醒而失效的内容。这更为深奥,但肯定会发生。例如,如果您正在从存储卡运行应用程序,则整个应用程序不会加载到RAM中。正在使用的片段被请求分页以供执行。这一切都很好。现在,如果关闭设备,驱动程序全部关闭。重新启动电源时,许多设备只需重新安装存储设备即可。当你的应用程序需要在更多程序中请求页面时,它不再是它的位置而且它会消失。安装的商店中的数据库可能会发生类似的行为如果您有一个打开的数据库句柄,则在睡眠/唤醒周期后,连接句柄可能不再有效。

你会注意到这里的趋势,几乎所有这些都是P / Invokes,这不是偶然的。很难让托管代码自行完成。

答案 1 :(得分:1)

我的本​​机C ++异常处理不包括异步异常,因此没有捕获访问冲突异常。

这可能/可能对我的问题没有帮助,但可能对其他人有帮助。

使用此链接中记录的/ EHa开关可以捕获这些类型的异常:

http://msdn.microsoft.com/en-us/library/1deeycx5.aspx