<!--
/* 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. 0x00f68f34 0x79b946b0 7,152 0x3b7d8bd0 0x79b946b0 14,708
private double GetZTEDZBLo 0x3b7dc544 0x79b946b0 18,836 using System.Da 0x3b89e394 0x79b946b0 73,748 0x1d004690 0x79b946b0 14,416 0x1d01101c 0x79b946b0 8,376
0x023462c0 0x79b946b0 145,916 using System.Da 0x02373d50 0x79b946b0 145,916 using System.Da Statistics: 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 { }
************************** 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 { }
************************** String: public Object FormulaComp148169817_264981(Object[]
************************** 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{ 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{ 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" 40 .shell: Process exited |
这个是什么意思呢?先运行 !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 是一个可选项,而不是必选项。