Sos.dll 和 windbg Get 抛出异常

Sos.dll and windbg Get exceptions thrown

我正在使用 sos.dll 和 windbg 来分析 w3wp.exe 转储。 perfmon 中显示抛出大量 .Net CLR 异常 per/sec,我正在尝试对此进行调查。我尝试做一个 !dumpheap -stat 类型的异常。但这是否显示了在我进行转储的实例中抛出的异常,或者这是否显示了创建的所有异常对象实例?可以在不抛出异常的情况下创建异常对象实例。

有没有办法只获取抛出的异常?

你用错了工具。安装 Windows Performance Toolkit,它是 Windows 10 SDK 的一部分。 The 1607 SDK can be used for Win8/10 systems, the older 1511 SDK 可用于 Windows 7/2008R2。

现在使用 以管理员身份打开 cmd.exe 以捕获应用程序的 activity

"C:\Program Files (x86)\Windows Kits\Windows Performance Toolkit\wpr.exe" -start C:\DotNetRuntime.wprp

捕获了一些 activity 您的工具后,运行 此命令停止捕获:

"C:\Program Files (x86)\Windows Kits\Windows Performance Toolkit\wpr.exe" -stop C:\Result.etl

现在双击 Result.etl 以在 Windows 性能分析器和 load debug symbols 中打开它。

现在将 Generic Event 图表拖放到分析窗格中,对 ProviderprocessTasknameField 1TimeOpcode NameStack。现在过滤 Microsoft-Windows-DotNETRuntime 提供程序并展开您的进程名称条目,然后展开任务名称 Exception:

的条目

在此演示中,VS Addon Resharper 导致了 JetBrains.Application.Progress.ProcessCancelledException。检查您看到的进程有哪些异常,并检查引发异常的堆栈。

抛出的异常是第一次机会异常。由于您的程序没有崩溃,这意味着它们已被捕获和处理。

除了@magicandre1981 的,我看到另外两个选项:

ProcDump

ProcDump 可以使用 -e 1 命令行开关在第一次出现异常时创建故障转储。还要定义 -n 以指定要进行的最大转储次数。一旦您发现异常并且不想再报告它,请使用 -f 过滤它。

优点:你不仅有异常,还有调用堆栈和所有堆信息,你可以稍后分析。

缺点:这会显着减慢您的进程并占用大量磁盘 space。

WinDbg 异常命令

您可以将 WinDbg 附加到进程并使用 sxe 命令和 -c 开关来分析第一次机会异常。在命令中包含 g 以继续执行。将所有输出写入日志文件很有帮助(使用 .logopen)。

示例:

.symfix
.reload
.logopen c:\debug\logs\firstchance.log
.loadby sos clr
ld * 
sxe -c "!pe;!clrstack;g" clr
g

.symfix.reload 可能不是必需的。只要确保你的,否则所有的分析可能都是无用的。 ld * 只会预加载一些东西,以便稍后进行更快的分析。

优点:您可以捕获任意数量的信息,而无需创建大量故障转储。

缺点:执行命令可能会显着减慢进程。当您执行此操作并出现数百个异常时,WinDbg 可能会变得不稳定。 (我很久没这样做了,这个警告是根据我在 2010 年某个时候使用 WinDbg 6.12 的经验给出的)