定断点在方法ntdll!RtlEnterCriticalSection 上, 一旦执行到这个方法, 就写log, 记录callstack, 并且打印寄存器的值. 定断点在地址77f5b380 上, 动作同前一个.
<ADPlus>
<!--
Configuring ADPlus for breakpoints
-->
<!-- defining breakpoints -->
<Breakpoints>
<NewBP>
<Address> ntdll!RtlEnterCriticalSection </Address>
<Actions> Log;Stacks </Actions>
<CustomActions> r </CustomActions>
</NewBP>
<NewBP>
<Address> 77f5b380 </Address>
<Actions> Log;Stacks </Actions>
<CustomActions> r </CustomActions>
</NewBP>
</Breakpoints>
</ADPlus>
设置条件断点, 发生异常的时候, 对esp进行计算后判断, 条件不满足时, 如何如何, 满足时抓dump.
<ADPlus>
<!--
Configuring ADPlus to create a conditional breakpoint
When using j we need to include the "g" command into each branch due to its special syntax
with j everything after the two branches is ignored
For this reason we need to use VOID in ReturnAction
Note - when using j commands with breakpoints it may be more convenient to use gc instead of g
if you plan to do live debug; see documentation for gc in debugger.chm
-->
<!-- defining breakpoints -->
<Breakpoints>
<NewBP>
<Address> mscorsvr!RaiseTheException </Address>
<Type> BU </Type>
<Actions> VOID </Actions>
<CustomActions> j (poi(poi(poi(poi(esp+4))+8)+48) = 02000004) '.time;du poi((poi(esp+4)+10))+c;.dump /u /mfh d:\dumps\Insite.dmp;gc';'.time;du poi((poi(esp+4)+10))+c;gc'</CustomActions>
<ReturnAction> VOID </ReturnAction>
</NewBP>
</Breakpoints>
</ADPlus>
针对.net的某种特定类型的异常, 抓dump.
<ADPlus>
<!-- Configuring ADPlus for custom actions on a given CLR exception -->
<!-- First we load sos extension -->
<!-- Next we use the !cce command to check if the exception is the one we are looking for -->
<!-- Next we use a j command on $t1 to do what we want -->
<!-- Replace UnhandledException_Console.MyCustomException below with the name of the exception you are looking for -->
<!-- You need to put the GN in the two branches of the j command and use VOID in the ReturnACtion1 tag -->
<Exceptions>
<Config>
<!-- This is for the CLR exception -->
<Code> clr </Code>
<Actions1> Log </Actions1>
<CustomActions1> !cce UnhandledException_Console.MyCustomException 1; j ($t1 = 1) '.dump /ma /u c:\Dumps\MyCustom.dmp;gn' ; 'gn' </CustomActions1>
<ReturnAction1> VOID </ReturnAction1>
</Config>
</Exceptions>
</ADPlus>
先创建一个exception, 利用这个exception的exception code作为标识, 抓dump.
<ADPlus>
<!--Configuring ADPlus to monitor a custom exception -->
<Exceptions>
<!-- Creating the exception -->
<NewException>
<Code> c000008f </Code>
<Name> CustomExc_c000008f </Name>
</NewException>
<!-- Configuring the exception. Here we configure it to create a full dump and a log on first chance -->
<Config>
<Code> c000008f </Code>
<Actions1> FullDump;Log </Actions1>
</Config>
</Exceptions>
</ADPlus>
转在SPException异常抛出的时候抓取dump文件.
<ADPlus>
<PreCommands>
<Cmd> .loadby sos mscorwks </Cmd>
</PreCommands>
<PostCommands>
<Cmd> sxe -c "!soe Microsoft.SharePoint.SPException 1;.if(@$t1==0) {g} .else {.dump /u /ma d:\\dumps\\dump1.dmp;g}" clr </Cmd>
</PostCommands>
</ADPlus>
异常发生的时候, 打印异常, 和调用栈, 然后继续.
<ADPlus>
<PreCommands>
<Cmd> .loadby sos mscorwks </Cmd>
</PreCommands>
<PostCommands>
<Cmd> .logopen d:\dumps\debug.log;sxe -c "!pe;!clrstack;g" clr </Cmd>
</PostCommands>
</ADPlus>
非crash, 进程正常退出的时候抓取dump.
<ADPlus>
<Breakpoints>
<NewBP>
<Address> Kernel32!TerminateProcess;Kernel32!ExitProcess</Address>
<Type> BP </Type>
<Actions> FullDump;Stacks;Log </Actions>
<ReturnAction> G </ReturnAction>
</NewBP>
</Breakpoints>
</ADPlus>
抓First Chance的Access Violation的dump.
<ADPlus>
<Exceptions>
<Config>
<!-- Break on CLR exception type -->
<Code> AV </Code>
<Actions1> Log;Stack;FullDump </Actions1>
<Actions2> Log;Stack;FullDump </Actions2>
<ReturnAction1> gn </ReturnAction1>
</Config>
</Exceptions>
</ADPlus>
拿到System.Web.RequestTimeoutManager.CancelTimedOutRequests方法的执行地址, 断点之, 断点入则抓dump. 这里值得注意的是使用.foreach命令跳过一些字符串拿到执行地址的技巧.
<ADPlus Version='2'>
<!-- Configuring ADPlus to log all first chance exceptions -->
<!-- Will still create full dump for any type of second chance exceptions -->
<KeyWords>
<keyword Name="loadbysos"> .loadby sos mscorwks </keyword>
<keyword Name="GetJIT"> !name2ee System.web.dll System.Web.RequestTimeoutManager.CancelTimedOutRequests </keyword>
<keyword Name="JITAddress"> .foreach /pS 0n12 ( record {!name2ee System.web.dll System.Web.RequestTimeoutManager.CancelTimedOutRequests}) { r $t1= ${record}; bp $t1+0x172 ".dump /ma /u ${AdpDumpDirEsc}\\Full Request timed out ${AdpProcName}_.dmp;g"; .printf"*breakpoint list*\n"; bl} </keyword>
</KeyWords>
<Settings>
<Option> NoDumpOnFirst </Option>
<RunMode> CRASH </RunMode>
</Settings>
<PreCommands>
<DebugActions> loadbysos; GetJIT; JITAddress </DebugActions>
</PreCommands>
</ADPlus>
参照上面的例子, 我自己写了一个. 在System.Xml.Serialization.XmlSerializer..ctor 的众多版本中, 选出一个自己想要的, 断之, 抓dump. 注意这里的/ps 100, 用于跳过找到目标地址后面的输出, 100就是个较大的数, 只要大过name2ee命令输出的字符串数就可以了.
<ADPlus Version='2'>
<!-- Configuring ADPlus to log all first chance exceptions -->
<!-- Will still create full dump for any type of second chance exceptions --><KeyWords>
<keyword Name="loadbysos"> .loadby sos mscorwks </keyword>
<keyword Name="GetJIT"> !name2ee System.Xml.dll System.Xml.Serialization.XmlSerializer..ctor </keyword>
<keyword Name="JITAddress"> .foreach /pS 0n51 /ps 0n100 (record {!name2ee System.Xml.dll System.Xml.Serialization.XmlSerializer..ctor}) {r $t1= ${record}; bp $t1 ".dump /ma /u ${AdpDumpDirEsc}\\Full Request timed out ${AdpProcName}_.dmp;g"; .printf"*breakpoint list*\n"; bl} </keyword>
</KeyWords><Settings>
<Option> NoDumpOnFirst </Option>
<RunMode> CRASH </RunMode>
</Settings><PreCommands>
<DebugActions> loadbysos; GetJIT; JITAddress </DebugActions>
</PreCommands></ADPlus>
资料来源
======================
ADPlus Configuration File Samples
http://www.dbgtech.net/windbghelp/hh/debugger/adplus_20a03065-fe70-433e-bf90-a19c229205db.xml.htm
ADPlus Configuration File to the rescue
http://debuggingblog.com/wp/2008/11/15/adplus-configuration-file-to-the-rescue/
Ok, now how do I capture my dump?
http://blogs.msdn.com/b/carloc/archive/2007/10/08/ok-now-how-do-i-capture-my-dump.aspx
如何解决请求超时的HttpException异常 (ASP.NET 2.0 32-bit)