<!-- /* Font Definitions */ @font-face {font-family:宋体; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:SimSun; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:"Cambria Math"; panose-1:2 4 5 3 5 4 6 3 2 4; mso-font-charset:1; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:0 0 0 0 0 0;} @font-face {font-family:Calibri; panose-1:2 15 5 2 2 2 4 3 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:-1610611985 1073750139 0 0 159 0;} @font-face {font-family:"/@宋体"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-unhide:no; mso-style-qformat:yes; mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; font-size:10.5pt; mso-bidi-font-size:11.0pt; font-family:"Calibri","sans-serif"; mso-ascii-font-family:Calibri; mso-ascii-theme-font:minor-latin; mso-fareast-font-family:宋体; mso-fareast-theme-font:minor-fareast; mso-hansi-font-family:Calibri; mso-hansi-theme-font:minor-latin; mso-bidi-font-family:"Times New Roman"; mso-bidi-theme-font:minor-bidi; mso-font-kerning:1.0pt;} a:link, span.MsoHyperlink {mso-style-priority:99; color:blue; mso-themecolor:hyperlink; text-decoration:underline; text-underline:single;} a:visited, span.MsoHyperlinkFollowed {mso-style-noshow:yes; mso-style-priority:99; color:purple; mso-themecolor:followedhyperlink; text-decoration:underline; text-underline:single;} .MsoChpDefault {mso-style-type:export-only; mso-default-props:yes; mso-bidi-font-family:"Times New Roman"; mso-bidi-theme-font:minor-bidi;} /* Page Definitions */ @page {mso-page-border-surround-header:no; mso-page-border-surround-footer:no;} @page Section1 {size:595.3pt 841.9pt; margin:72.0pt 90.0pt 72.0pt 90.0pt; mso-header-margin:42.55pt; mso-footer-margin:49.6pt; mso-paper-source:0; layout-grid:15.6pt;} div.Section1 {page:Section1;} -->
原文地址:
http://blogs.msdn.com/johan/archive/2008/01/23/using-windbg-advanced-commands.aspx
作者:Johan
翻译:AloneSword
网文:http://blog.csdn.net/alonesword/
高级WinDbg 使用
是否知道在windbg中使用像foreach, if 等等的高级命令,如下是完整的列表:
.if
.else
.elseif
.foreach
.for
.while
.do
.break
.continue
.catch
.leave
.printf
.block
使用这些命令,不仅能使用调试器的高级指令让工作更容易,更能极大的改进你的管理能力。
.foreach
让我们从一个简单的实例开始。假设你想查看当前堆栈上所有大于6500字节的字符串内容,只需要简单的键入: !dumpheap –type System.String –min 6500 即可,可以得到类似如下的信息:
0:000> !dumpheap -type System.String -min 6500 Using our cache to search the heap. Address MT Size Gen 0x00f68f34 0x79b946b0 7,152 2 System.String SELECT b4.contract_config_id, 0x3b7d8bd0 0x79b946b0 14,708 2 System.String
private double GetZTEDZBLo 0x3b7dc544 0x79b946b0 18,836 2 System.String using System; using System.Da 0x3b89e394 0x79b946b0 73,748 2 System.String public Object FormulaComp1 0x1d004690 0x79b946b0 14,416 2 System.String SELECT b4.contract_config_id, 0x1d01101c 0x79b946b0 8,376 2 System.String SELECT bom.system_bom_id,
0x023462c0 0x79b946b0 145,916 3 System.String using System; using System.Da 0x02373d50 0x79b946b0 145,916 3 System.String using System; using System.Da Statistics: MT Count TotalSize Class Name 0x79b946b0 8 429,068 System.String Total 8 objects, Total size: 429,068 |
到目前为止,我们认为这个内容还不错,问题是如果我想查看每个字符串的内容,就不得在每个字符串地址上运行 !dumpobj。在只有8个字符串地址的情况下,这么做还是能接受的,如果数量达到25 或100个呢?不知道大家是否注意到,传递-short 参数到 !dumpheap的话,它将给出最少的信息(仅仅是查询出对象的地址信息)
0:000> !dumpheap -type System.String -min 6500 -short 0x00f68f34 0x3b7d8bd0 0x3b7dc544 0x3b89e394 0x1d004690 0x1d01101c 0x023462c0 0x02373d50 |
现在,就可以在 .foreach 语句中使用这些信息了:
0:000> .foreach (myAddr {!dumpheap -type System.String -min 6500 -short}){!dumpobj myAddr;.echo **************************} String: SELECT b4.contract_config_id,
************************** String:
private double GetZTEDZBLookUP(string tableName,string rowName,string colName) { return SpecialFormula.GetZTEDZBLookUP(tableName, rowName, colName); }
************************** String: using System; using System.Data; using System.Data.OleDb; using System.Collections; using ZTE.CCG.Business.Template; using ZTE.CCG.Business.Contract.Template;
using ZTE.CCG.Common.Tool;
namespace MyNamespace{ public class MyNewClass{
private double GetZTEDZBLookUP(string tableName,string rowName,string colName) { return SpecialFormula.GetZTEDZBLookUP(tableName, rowName, colName); }
************************** String: public Object FormulaComp148169817_264981(Object[] _Param){
************************** String: SELECT b4.contract_config_id,
************************** String: SELECT bom.system_bom_id,
************************** String: using System; using System.Data; using System.Data.OleDb; using System.Collections; using ZTE.CCG.Business.Template; using ZTE.CCG.Business.Contract.Template;
using ZTE.CCG.Common.Tool;
namespace MyNamespace{ public class MyNewClass{ public Object FormulaComp148169817_264981(Object[] _Param){ return((Convert.ToString(_Param[0])!="1/4")?Convert.ToDouble(_Param[1])*2:0); }
************************** String: using System; using System.Data; using System.Data.OleDb; using System.Collections; using ZTE.CCG.Business.Template; using ZTE.CCG.Business.Contract.Template;
using ZTE.CCG.Common.Tool;
namespace MyNamespace{ public class MyNewClass{ public Object FormulaComp148170092_264981(Object[] _Param){ return((Convert.ToString(_Param[0])!="1/4")?Convert.ToDouble(_Param[1])*2:0); } ************************** |
“myobj” 是一个中间变量,为在随后的命令中使用。第二个命令就是想循环执行的语句。首先,对变量运行 !dumpobj ,同时使用 .echo 命令打印分割符,以便更好的阅读分析。
还有一些其他的参数可以使用,例如:可以选择跳过n行变量;指定一个文本文件作为命令的替代品。若对这些命令感兴趣,请查看windbg的文档。
.shell
我第一个看到这个命令使用的是我的大学同学 Doug Stewart,他在这方面完全就是一个天才。
0:000> .shell -i - -ci
"!iisinfo.clientconns" FIND /c "Request active" |
这个是什么意思呢?先运行 !iisinfo.clientonns 并使用 MS-DOS 的 Find 命令查”Request active”出现次数。当然,也可以使用这个命令来搜索任何输出的字符内容,比如”.shell –i - -ci “!do 0b62e790” FIND /c /i “<table””,也可以是其他的任何能满足要求的内容。
我们浏览一下相关语法:
当使用”.shell”命令时,-I 参数是必须的【标注1】,主要是输入文件选项。在上述情况中,我们没有使用输入文件,所以使用了连字符”-”,结果就是类似的语法:”.shell -i -”
当我们使用 –ci 选项时,就表示接下来的命令将代替文件输入,”.shell -I - -ci “!iisinfo.clientconns””
最后,我们指定运行指定的命令,在shell命令之后。”.shell –I - -ci “!iisinfo.clientconns” FIND /c “Request active””
自然的我们可以使用任何复杂的命令来替换 !iisinfo.clientconns ,也可以运行任何一个 .foreach 循环语句
Johan.
【标注1】:更正,在 windbg 的文档关于 .shell 描述,-I 是一个可选项,而不是必选项。