解释访问冲突异常?

时间:2017-09-13 14:16:34

标签: c++ vb.net unhandled dep

我们使用围绕VB / C ++代码构建的自定义应用程序。 此代码将运行数天,数周,数月,而不会导致异常错误。

我试图了解更多关于如何抛出此错误的信息,以及如何解释(如果可以)抛出异常时列出的错误。我已经搜索了一些信息,并阅读了微软提供的错误说明,但我仍然遇到了在蓝色月亮中发生一次问题的问题。没有已知的软件交互集导致这种情况并且似乎是随机发生的。

第一个例外是根本原因吗?它是否一直在堆栈调用?任何人都可以提供有关如何阅读这些代码的任何见解,以便我可以解释我实际需要查看的位置。

有关阅读异常或使用异常的任何信息或指导,然后对其进行故障排除将会有所帮助。抛出事件时,将从Windows日志中复制以下测试。

提前感谢您的帮助。

Application: Epic.exe Framework Version: v4.0.30319 Description: The process was terminated due to an unhandled exception. Exception Info: System.AccessViolationException [![enter image description here][1]][1]
at MemMap.ComBuf.IsCharAvailable(Int32) 
at HMI.frmPmacStat.RefreshTimer_Elapsed(System.Object, System.Timers.ElapsedEventArgs) 
at System.Timers.Timer.MyTimerCallback(System.Object) 
at System.Threading.TimerQueueTimer.CallCallbackInContext(System.Object) 
at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, 
System.Threading.ContextCallback, System.Object, Boolean) 
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, 
System.Threading.ContextCallback, System.Object, Boolean) 
at System.Threading.TimerQueueTimer.CallCallback() 
at System.Threading.TimerQueueTimer.Fire() 
at System.Threading.TimerQueue.FireQueuedTimerCompletion(System.Object) 
at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem() 
at System.Threading.ThreadPoolWorkQueue.Dispatch() 
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()

enter image description here enter image description here

2 个答案:

答案 0 :(得分:2)

由于执行throw表达式,c ++运行时环境会抛出异常,并且操作系统或硬件捕获指令会导致其他类型的错误。对c ++中的代码通常不会引发对内存的无效访问,但是在评估试图访问无效地址的内存的表达式时会产生副作用,从而导致操作系统发出信号通知,通常会将其删除。因为它在C ++之外,它往往是特定于平台的,但典型的错误是:

  • 读取空指针
  • 使用指向已删除对象的指针
  • 超出数组的有效元素范围
  • 将无效的迭代器用于STL容器

一般来说,您可以在运行时测试null和数组边界,以便在问题发生之前检测它。使用悬空指针更难以追踪,因为删除和错误使用该指针之间的时间可能很长,并且很难找到没有内存调试器的原因,例如valgrind。使用智能指针而不是原始指针可以帮助缓解错误管理内存的问题,并可以帮助避免此类错误。

无效的迭代器是一般悬空指针问题的子集,但是很常见,值得一提的是它们自己的类别。了解容器以及哪些操作使它们失效是至关重要的,有些实现可以在“调试模式”下编译,这有助于检测无效迭代器的使用。

答案 1 :(得分:1)

正如其他人所说,这种类型的错误很难识别,无需深入研究代码和运行测试(自动或手动)。您可以拉出并且仍然可以重现它的系统越多越好。分而治之是你的朋友。

除此之外,这一切都取决于你解决这个问题的重要性以及你愿意付出多少努力。至少有三类工具可以帮助解决这些间歇性问题:

  1. 应用程序监视器在应用程序运行时跟踪潜在错误。这些往往会显着减慢您的程序(减速10倍或更多)。例子包括:
    1. Microsoft Application Verifier
    2. 开源和跨平台Dr. Memory
    3. Google的Crashpad。与前两个程序不同,这个程序需要检测代码。对Backtrace's commercial integration for analyzing Crashpad output
    4. 这样的帮助者来说,它(据称 - 并未尝试过)也更容易使用
    5. Google的Sanitizers - 免费,有些内置于gcc和clang中。还有一个Windows port of Address Sanitizer,但粗略的看起来表明它可能是一个二等公民。
    6. 如果您可以运行并重新启动它也可以在Linux上运行它,您可以使用valgrind; rr(请参阅this CppCast ep)这是gdb的免费扩展,用于记录和重放您的程序,以便您可以记录崩溃的调试会话,然后单步执行以查看出现了什么问题;和/或UndoDB以及来自Undo软件的朋友,这是一种更复杂的商业产品,如rr。
  2. 代码的静态分析。这是一组工具,用于查找代码中的常见错误。它通常具有较低的信噪比,因此如果您在一个大型的现有项目上运行它,可以通过很多小的事情来挖掘(如果可能的话,最好从头开始使用这些东西)。也就是说,许多警告是非常宝贵的。例子:
    1. 大多数编译器都内置了此功能的子集。如果您正在使用Visual Studio,请将/W4 /WX添加到C ++代码的编译标志中以强制发出最大警告,然后修复所有警告。对于gcc和clang,添加' -Wall -Wpedantic -Werror`以强制执行警告。
    2. PVS-Studio(商业)
    3. PC-Lint(商业)
  3. 如果您可以检测代码以编写日志消息,Debugview++之类的内容可能会有所帮助。
  4. 如果你正在进行多线程处理会变得越来越困难,看起来你会这么做,因为非确定性越来越难以跟踪,引入了新的可能错误类别,并且上面的一些工具赢得了#39 ; t工作得很好(例如,我认为rr只是单线程)。除了像Visual Studio这样的完整IDE之外,您还需要使用像英特尔Inspector(以前称为英特尔线程检查器)或Linux,Valgrind Helgrind这样的东西。和DRD和ThreadSanitizer(在上面的消毒剂中,但也只有Linux的AFAIK)。但希望这份清单能为您提供一个起点。