我们有一个托管的C#应用程序(MS Visual Studio 2010,目标框架:.Net 4 Client Profile),它通过Interop使用非托管COM对象,并且还利用P / Invoke调用我们自己的DLL(C ++)中的函数。 P / Invoke调用是从System.Threading.Task
程序进行的,因此可以同时进行。我们将同时任务的总数限制为10个。
应用程序可以运行很长时间,不断创建任务并调用非托管函数。在某些时候弹出一个对话框 - Microsoft Visual C ++运行时库/运行时错误! /应用程序已请求Runtime以不寻常的方式终止它 ...
对话框未创建任何事件日志条目。
显示对话框时,应用程序继续运行,但其内存利用率继续攀升。在TaskManager和VMMap(Sysinternals)中监视时,内存使用会再增加5-10分钟,然后应用程序崩溃。
问题是 - 为什么即使出现错误对话框,应用程序仍会继续运行?
在崩溃之前,即当内存耗尽时,任何尝试分配内存的代码都会抛出System.OutOfMemoryException
,并被C#捕获。
所以此时应用程序事件日志有一个新条目表示以下内容:
Faulting module name: KERNELBASE.dll, version: 6.1.7601.18798
Exception code: 0xe0434352
Fault offset: 0x0000c42d
Description: The process was terminated due to an unhandled exception.
Exception Info: System.AccessViolationException
没有进一步的信息;不生成转储文件。 我们的非托管组件(COM DLL,DLL)不会显示为错误模块。
以下是我们目前使用的工具列表:
DbgView查看相关组件的ATL跟踪。
VMMap调查碎片,堆等。
DebugDiag检查内存泄漏,分析托管和非托管内存,调用堆栈等。
如果有任何其他技术或方法可用于确定导致MS C ++运行时错误的实际调用顺序,那么任何建设性建议都将受到赞赏。
答案 0 :(得分:1)
在大量尝试隔离崩溃原因之后,Microsoft的调试诊断工具(v2 Update 1)提供了所需的信息。
我们使用Debug Diag的Crash / Hang Analyzer来处理我们正在处理的过程。 在工具/选项&设置/符号搜索路径对于Analaysis,我们为所有组件(.Net应用程序,C ++ DLL等)指定了.PDB文件的位置。
一旦崩溃,Debug Diag的调用堆栈就完全针对对我们正在利用的非托管第三方DLL的调用进行了精确定位,导致访问冲突异常/崩溃。