【发布时间】:2026-01-15 07:25:01
【问题描述】:
我们有一个托管 C# 应用程序(MS Visual Studio 2010,目标框架:.Net 4 Client Profile),它通过互操作使用非托管 COM 对象,还利用 P/Invoke 调用我们自己的 DLL (C++) 中的函数。 P/Invoke 调用是从System.Threading.Task 过程发出的,因此可以同时进行。我们将同时执行的任务总数限制为 10 个。
应用程序可以运行相当长的一段时间,不断地创建任务和调用非托管函数。有时会弹出一个对话框 - Microsoft Visual C++ 运行时库/运行时错误! / 应用程序请求运行时以不寻常的方式终止它...
没有由于该对话框而创建的事件日志条目。
显示对话框时,应用程序继续运行,但其内存使用率继续攀升。正如在 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++ 运行时错误的实际调用顺序,我们将不胜感激任何建设性的建议。
【问题讨论】:
-
由于您看到内存使用量增加,这可能是审查非托管 PInvoke 调用以及如何编组数据的开始。这是一个深奥的主题,但未能固定内存,允许在未镜像的代码仍在使用它时对内存进行垃圾收集,包括可能来自线程处理此数据的竞争条件,都可能导致异常崩溃。祝你好运,这是一块很难破解的饼干。
-
你需要调试这个。仪器和检查。不是真正的主题,因为它更窄。
-
@CaptainObvlious 我不认为询问方法会使这个话题离题。
标签: c# c++ visual-studio-2010 dll pinvoke