如何在C#程序中使用SOS.dll进行自动调试?

Cha*_*ski 3 .net c# debugging memory-leaks sos

为了追踪内存泄漏,我一直在使用Visual Studio和SOS.dll来提供对象堆的转储,并查看GCR射击特定对象的原因.

我开始使用AutoIt自动执行此过程来控制我的鼠标和键盘.这是我脚本第一部分的近似值:

在Visual Studio中,按F5开始执行
让程序完全加载
切换到Visual Studio并中断执行

将焦点切换到即时窗口
加载SOS.dll
调用!dumpheap -stat
将转储结果复制到剪贴板
粘贴到记事本中并另存为dump1.txt

恢复执行
多次执行漏洞操作
切换到Visual Studio并中断执行

将焦点切换到即时窗口
清除输出
调用!dumpheap -stat
将转储结果复制到剪贴板
粘贴到记事本中并另存为dump2.txt

运行Python脚本,比较两个转储并找到泄漏的对象

不过,我对目前的方法有些担忧.我不仅依赖于Visual Studio的安装,而且在脚本运行时,我不能使用鼠标或键盘而不会使自动化失序.

有没有办法在C#程序而不是Visual Studio中使用SOS.dll?理想情况下,此解决方案将附加到指定的进程并将结果输出!dumpheap -stat到文本文件,而无需自动化Visual Studio.

Col*_*ith 9

下面我将介绍一些可用于查找泄漏的不同方法.

(如果您不希望遵循DIY方法,可以使用商业"泄漏"探测器).

链接到我的回答详细说明了许多调试工具/资源

将SOS.DLL加载到WinDBG中

实际上你不需要Visual Studio来使用SOS.DLL ....它是一个调试器扩展,所以也可以在WinDBG中使用.

您可以免费获得WinDBG调试器作为Windows调试工具的一部分.

然后,您可以编写WinDBG脚本来自动执行"转储".

另外请注意,SOS.DLL的增强版本可用...寻找SOSEX,PSSCOR2(针对NET 2)和PSSCOR4(针对NET 4).

CLR性能分析API

您可以使用CLR Profiling API.

有一个名为CLRProfiler的应用程序,它是一个实际的.NET分析器,它使用它....所以有很多代码可以看看它是如何使用的.

CLR Profiler可以做的事情之一是允许进行堆转储,然后比较在不同时间段进行的转储,以找出差异......从而帮助发现泄漏.

在"测试"模式下(嵌入在应用程序中,或作为监视它的配套实用程序),您可以为应用程序提供类似的功能.

流程转储

您可以使用的另一种技术是定期对您的进程进行"转储",然后您可以通过WinDBG使用SOS/SOSEX(或任何其他WinDBG插件)离线分析.

您可以使用DebugDiag(您可以设置规则和操作来控制何时创建.dmp文件)以自动创建.dmp文件....或者名为ProcDump.exe的工具(来自SysInternals).

ProcDump特别有用,因为它能够非常快速地获取"过程快照",因为它使用了一种称为"过程反射"的技术....这使得您的过程可以不那么积极地中断,例如

(创建3个转储,每个转储间隔5秒)

procdump -s 5 -n 3 notepad.exe notepad.dmp 
Run Code Online (Sandbox Code Playgroud)

死后分析

拥有一组.dmp文件后,您可以分析它们以查找泄漏,监视句柄使用情况等.

您可以在WinDBG中手动加载.dmp文件然后发出调试器命令,或者您可以编写一个WinDBG扩展或者一个脚本来获取转储文件并依次处理它们(即对它们运行!dumpheap stat命令) .

Debug Analyzer .NET

这是一个旨在分析.dmp文件和进行事后分析的工具.

它允许您在.NET中编写脚本,因此可能比WinDBG更容易访问.

如果你想扩展它,它还有一个插件模型.

它允许您编写/使用展示台以独特的方式查看数据.

(目前仅支持CLR 2.0内存转储......不支持CLR 4.0)