简洁版本
我想要一个 ADPlus 脚本,它会在第一次出现 StackOverflowException 时执行完整的内存转储,然后再清理任何内容,并忽略所有其他异常类型。
日志版本
在发布新的 ASP.NET 代码后,我们开始出现间歇性 StackOverflowExceptions。我们已经在自上次已知良好安装后添加的修订版中寻找无限递归和所有常见的嫌疑人,但找不到任何东西。该网站将运行长达一个小时,然后崩溃。
我们使用了 WinDbg 和 SOS 并尝试使用 ADPlus 获取崩溃日志,使用以下命令:
adplus -crash -o D:\Crash -NoDumpOnFirst -iis
-NoDumpOnFirst 的原因是我们只能在繁忙的服务器上在生产中重现此错误。为了对每个第一次机会异常(嘿,它发生)进行小型转储,调试器必须暂停 IIS 工作进程足够长的时间以写出 16 meg 文件,因此请求排队并且应用程序变得不稳定。因为错误可能需要长达一个小时才能抬起它丑陋的脑袋,所以这是有问题的。
因此,使用 -NoDumpOnFirst,我得到了一个转储文件,WinDbg 输出这些线程用于:
PDB symbol for mscorwks.dll not loaded
ThreadCount: 69
UnstartedThread: 0
BackgroundThread: 69
PendingThread: 0
DeadThread: 0
Hosted Runtime: no
PreEmptive GC Alloc Lock
ID OSID ThreadOBJ State GC Context Domain Count APT Exception
XXXX 1 c6c 000fa758 11808221 Disabled 3b49ee4c:3b49efe8 00120888 1 Ukn (Threadpool Worker)
XXXX 2 1294 000fd258 b220 Enabled 00000000:00000000 000df4e0 0 Ukn (Finalizer)
XXXX 3 1eb0 0011cdd0 80a220 Enabled 00000000:00000000 000df4e0 0 Ukn (Threadpool Completion Port)
XXXX 4 1b3c 00120198 1220 Enabled 00000000:00000000 000df4e0 0 Ukn
XXXX 5 1280 00138118 880a220 Enabled 2633de9c:2633ee08 000df4e0 0 Ukn (Threadpool Completion Port)
XXXX 6 1db8 00158a48 1180a221 Disabled 4b5a7e2c:4b5a82e8 00120888 1 Ukn (Threadpool Worker)
XXXX 9 141c 00162008 180a220 Enabled 00000000:00000000 000df4e0 0 Ukn (Threadpool Worker)
XXXX 7 1574 00174008 180a220 Enabled 4d46b6a8:4d46c158 00120888 2 Ukn (Threadpool Worker)
XXXX c 16c8 0016b7a8 180a220 Enabled 00000000:00000000 000df4e0 0 Ukn (Threadpool Worker)
XXXX 8 1384 00162878 180a220 Enabled 284e26a4:284e45d8 000df4e0 0 Ukn (Threadpool Worker)
XXXX b 1c10 0016b3d8 180a220 Enabled 3ed2dae0:3ed2dfe8 00120888 2 Ukn (Threadpool Worker)
XXXX a 1814 0016b008 180a220 Disabled 28816384:28816638 00120888 1 Ukn (Threadpool Worker)
XXXX d 1fc 1b4d1ff0 220 Enabled 319f89a4:319fa41c 000df4e0 0 Ukn
XXXX e 1864 1b4e3d20 180b220 Enabled 4b2c5be0:4b2c6150 000df4e0 0 Ukn (Threadpool Worker)
XXXX f 13bc 1b57caf8 200b220 Enabled 4cc71584:4cc73414 00120888 1 Ukn
XXXX 10 72c 1f5124a8 180b220 Enabled 3b4b3414:3b4b4fe8 00120888 2 Ukn (Threadpool Worker)
XXXX 11 1fd0 1f526398 180b220 Disabled 4d46f41c:4d470158 00120888 1 Ukn (Threadpool Worker)
XXXX 12 1f10 1f52f1c8 180b220 Enabled 28812c14:28814638 00120888 2 Ukn (Threadpool Worker)
XXXX 13 1b84 1f53a420 220 Enabled 00000000:00000000 000df4e0 0 Ukn
XXXX 14 18a4 1f570978 180b220 Enabled 263e18b4:263e2e28 000df4e0 0 Ukn (Threadpool Worker)
XXXX 15 1a98 1f57f0a0 180b220 Enabled 00000000:00000000 000df4e0 0 Ukn (Threadpool Worker)
XXXX 16 1b4 1f583628 180b220 Enabled 495781ec:4957914c 00120888 2 Ukn (Threadpool Worker)
XXXX 17 b90 1f585dc8 180b220 Enabled 265cbe48:265ccba4 000df4e0 0 Ukn (Threadpool Worker)
XXXX 18 1590 1f613c60 220 Enabled 00000000:00000000 000df4e0 0 Ukn
XXXX 19 1850 1f5fad90 220 Enabled 00000000:00000000 000df4e0 0 Ukn
XXXX 1a c78 1f60d3f0 220 Enabled 00000000:00000000 000df4e0 0 Ukn
XXXX 1c 1bd8 2121f1b0 220 Enabled 00000000:00000000 000df4e0 0 Ukn
XXXX 1d 494 1b4a8c10 220 Enabled 00000000:00000000 000df4e0 0 Ukn
XXXX 1e 898 2120f120 220 Enabled 00000000:00000000 000df4e0 0 Ukn
XXXX 1f 1820 21355ff8 220 Enabled 00000000:00000000 000df4e0 0 Ukn
XXXX 20 15b0 3570e120 220 Enabled 00000000:00000000 000df4e0 0 Ukn
XXXX 21 18b0 359ca008 220 Enabled 00000000:00000000 000df4e0 0 Ukn
XXXX 22 75c 35a58948 220 Enabled 00000000:00000000 000df4e0 0 Ukn
XXXX 25 1a18 213ac8f8 880b220 Disabled 3219a830:3219b450 00120888 1 Ukn (Threadpool Completion Port) System.StackOverflowException (0e3200a4)
XXXX 29 1b74 3598e620 180b220 Enabled 00000000:00000000 000df4e0 0 Ukn (Threadpool Worker)
XXXX 2a 9b8 3598dbe0 180b220 Enabled 2880ef2c:28810638 000df4e0 0 Ukn (Threadpool Worker)
XXXX 2b 1eac 1f6f6288 180b220 Enabled 00000000:00000000 000df4e0 0 Ukn (Threadpool Worker)
XXXX 2d 2f4 211759e8 180b220 Disabled 2634eacc:2634ee08 00120888 1 Ukn (Threadpool Worker)
XXXX 2e 1e3c 35c2eb60 880b220 Enabled 4b5a5758:4b5a62e8 000df4e0 0 Ukn (Threadpool Completion Port)
XXXX 30 394 35c394f8 180b220 Enabled 4cef7930:4cef90d4 000df4e0 0 Ukn (Threadpool Worker)
XXXX 31 1e64 35c39128 180b220 Disabled 288110b0:28812638 00120888 1 Ukn (Threadpool Worker)
XXXX 32 1af8 35a58578 180b220 Enabled 3b48e7cc:3b48efe8 000df4e0 0 Ukn (Threadpool Worker)
XXXX 34 1d44 1f6a6c88 180b220 Enabled 00000000:00000000 000df4e0 0 Ukn (Threadpool Worker)
XXXX 35 197c 212088e0 180b220 Enabled 49389ba8:4938af40 000df4e0 0 Ukn (Threadpool Worker)
XXXX 36 1e2c 35c1d980 220 Enabled 00000000:00000000 000df4e0 0 Ukn
XXXX 38 1ddc 212d03d8 220 Enabled 00000000:00000000 000df4e0 0 Ukn
XXXX 39 288 212d0008 220 Enabled 00000000:00000000 000df4e0 0 Ukn
XXXX 3a 1694 212bf958 220 Enabled 00000000:00000000 000df4e0 0 Ukn
XXXX 3b be4 212ccc40 220 Enabled 00000000:00000000 000df4e0 0 Ukn
XXXX 37 ccc 35c4d6d0 220 Enabled 00000000:00000000 000df4e0 0 Ukn
XXXX 3c 14ec 35c55af0 220 Enabled 00000000:00000000 000df4e0 0 Ukn
XXXX 41 1d94 35c38c08 180b220 Enabled 00000000:00000000 000df4e0 0 Ukn (Threadpool Worker)
XXXX 24 130 35746a50 180b220 Enabled 2670ae48:2670cc00 000df4e0 0 Ukn (Threadpool Worker)
XXXX 2f 1404 35c1d350 180b220 Enabled 00000000:00000000 000df4e0 0 Ukn (Threadpool Worker)
XXXX 43 1ae8 35c25cb8 180b220 Disabled 3b4c28e0:3b4c2fe8 00120888 1 Ukn (Threadpool Worker)
XXXX 44 18ac 212cc870 180b220 Disabled 4957e728:4957f14c 00120888 1 Ukn (Threadpool Worker)
XXXX 45 18b4 212bf588 180b220 Disabled 3b4c05dc:3b4c0fe8 00120888 1 Ukn (Threadpool Worker)
XXXX 46 1c0c 21239858 220 Enabled 00000000:00000000 000df4e0 0 Ukn
XXXX 47 4fc 21188b68 220 Enabled 00000000:00000000 000df4e0 0 Ukn
XXXX 48 1198 35caa2a8 220 Enabled 00000000:00000000 000df4e0 0 Ukn
XXXX 49 1f9c 21147af8 220 Enabled 00000000:00000000 000df4e0 0 Ukn
XXXX 4a 1adc 35cc6908 220 Enabled 00000000:00000000 000df4e0 0 Ukn
XXXX 4b ce8 35c60e30 220 Enabled 00000000:00000000 000df4e0 0 Ukn
XXXX 4d 6f0 35d05aa0 220 Enabled 00000000:00000000 000df4e0 0 Ukn
XXXX 4e 1ee8 35c1b6b0 220 Enabled 00000000:00000000 000df4e0 0 Ukn
XXXX 42 1d7c 35d9a230 220 Enabled 00000000:00000000 000df4e0 0 Ukn
XXXX 3d 7d8 212e1b28 220 Enabled 00000000:00000000 000df4e0 0 Ukn
XXXX 23 c0c 503ea010 220 Enabled 00000000:00000000 000df4e0 0 Ukn
XXXX 27 1f44 503cdf08 220 Enabled 00000000:00000000 000df4e0 0 Ukn
尝试打印异常表明没有堆栈跟踪,并且其他方法抱怨它是非托管代码。我的猜测是,由于转储是在进程死亡时创建的,因此所有线程都已被垃圾收集,并且没有信息可以获取。
我真的很想让调试器在 StackOverflowException 的第一次机会上执行完全转储并忽略所有其他异常类型。我知道 ADPlus 可以使用配置文件 - http://msdn.microsoft.com/en-us/library/cc409304.aspx - 但格式对我来说都是希腊语。谁能告诉我如何制作一个可以做到这一点的 ADPlus 脚本?
...当然,如果您查看上面的线程列表并且您确切地知道出了什么问题,或者如果我给您更多信息就可以弄清楚,您也可以告诉我。
解决尝试 1
谢谢 deemok 的回答,虽然不太正确,但这将我推向了正确的方向。Stack Overflow 的异常代码不正确(它是 sbo 不是 sov),(或者我当时认为,请参阅下面的 deemok 编辑)所以我尝试使用以下配置进行调试:
<ADPlus>
<!-- Add log entry, log faulting thread stack and dump full on first chance StackOverflow -->
<Exceptions>
<Config>
<!-- This is for the StackOverflow exception -->
<Code> sbo </Code>
<Actions1> Log;Stack;FullDump </Actions1>
<!-- Depending on what you intend - either stop the debugger (Q or QQ) or continue unhandled (GN) -->
<ReturnAction1> GN </ReturnAction1>
</Config>
</Exceptions>
</ADPlus>
并使用以下命令:
adplus -crash -o D:\Crash -NoDumpOnFirst -c D:\Crash\stackoverflow.cfg -iis
我验证了输出的日志文件指示了正确的配置。诀窍是 adplus 的命令行参数按顺序执行,因此如果您从捕获第一次机会异常的配置开始,然后应用 -NoDumpOnFirst,则配置设置将被覆盖。如果最后使用 -c 应用配置,则其设置将胜出。
然而,最后,堆栈溢出被证明是无法捕获的。发生堆栈溢出,无法接收内存转储,然后在第二次机会进程结束事件上发生转储,再次所有内容都被垃圾收集,我无法获得任何有用的信息。
我试图短路进程结束异常,以防它参与并覆盖堆栈溢出,但随后发生了异常,我只是没有内存转储。
幸运的是,我通过检查代码偶然发现了答案。当然,这是一个循环方法调用的例子。
实际分辨率
这个问题早就解决了,但我很快就制作了一个会导致堆栈溢出的 ASP.NET 页面。(毕竟这并不难)并在下面尝试了 Axl 的回应。
XML 有点偏离 - Axl 只是忘记关闭</ADPlus>
标签(或者可能在复制粘贴中丢失了它),但这很容易修复,adplus 很友好地告诉我到底出了什么问题。
我将该脚本设置为针对我的测试堆栈溢出引发程序,将结果加载到 windbg 中,当我调用 !clrstack 时,我得到了一个非常清晰(而且很长)的循环调用彼此的方法列表。这一下子就发现问题了!下次堆栈溢出来敲我的门时,我会保留此页面的书签。