【翻译 windbg-3】高级WinDbg 使用教程

原文地址:

https://www.tessferrandez.com/blog/2008/01/23/windbg-advanced-commands.html

https://blog.csdn.net/AloneSword/article/details/3826332

 

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"
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 是一个可选项,而不是必选项。

 

原文:

Using WinDbg - Advanced commands

 January 23, 2008   5 minute read

Update 2021: This is a re-post of a post from Johan Straarup - I am posting it here as his blog has been decommissioned

Did you know you can build your own advanced commands using for each, if, etc? The complete list of control tokens are:

  • .if
  • .else
  • .elseif
  • .foreach
  • .for
  • .while
  • .do
  • .break
  • .continue
  • .catch
  • .leave
  • .printf
  • .block

Using these command tokes you can send quite advanced instructions to the debugger that not only will make your job a lot easier, but also impress your manager immensely. :)

.foreachPermalink

Let’s begin with an easy example. Imagine you want to investigate all strings on the heap that are 6500 bytes or more. To list them you’d simply type !dumpheap -type System.String -min 6500. This will give you the following information:

0:000> !dumpheap -type System.String -min 6500
------------------------------
Heap 0
Address       MT     Size
790da154 790f9244     9280
0264c4d0 790f9244    32788
total 2 objects
------------------------------
Heap 1
Address       MT     Size
total 0 objects
------------------------------
Heap 2
Address       MT     Size
0b62e790 790f9244    11284
total 1 objects
------------------------------
Heap 3
Address       MT     Size
0e6839d0 790f9244    32788
0e717904 790f9244    32788
0fb2a320 790f9244     6828
total 3 objects
------------------------------
total 6 objects
Statistics:
      MT    Count    TotalSize Class Name
790f9244        6       125756 System.String
Total 6 objects

So far, so good. The problem is that in order to investigate each string you’d have to run !dumpobject (!do) on every address. This might be acceptable now that we’re only dealing with 6 strings, but what if it were 25, or 100? I don’t know if you’re aware of this, but if you pass the -short argument to !dumpheap it will give you the minimum information (just the addresses of the objects in question):

0:000> !dumpheap -type System.String -min 6500 -short
790da154
0264c4d0
0b62e790
0e6839d0
0e717904
0fb2a320
------------------------------

Now, let’s use this information in a .foreach-clause:

0:000> .foreach(myVariable {!dumpheap -type System.String -min 6500 -short}){!do myVariable;.echo *************}
Name: System.String
MethodTable: 790f9244
EEClass: 790f91a4
Size: 9280(0x2440) bytes
(C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)
String:
WFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWGRkAiEPDxYCHwEFZFhYWFhYWFhYWFhYWFhYWFhYWFhYWF
hYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhY
WFhYWFhYWFhYWFhkZAInDw8WCh8CBQFFHwMFCjIyLzExLzIwMDcfBAUBVh8FBQFFHwYFASpkZAIpD2QWBGYPZBYEAg
...

Fields:
      MT    Field   Offset                 Type VT     Attr    Value Name
790fdb60  4000096        4         System.Int32  1 instance     4632 m_arrayLength
790fdb60  4000097        8         System.Int32  1 instance     4631 m_stringLength
790fad38  4000098        c          System.Char  1 instance       3c m_firstChar
790f9244  4000099       10        System.String  0   shared   static Empty
    >> Domain:Value  000d5eb8:790d57b4 000fb4c0:790d57b4 000ca848:790d57b4 1d8334d8:790d57b4 <<
79122994  400009a       14        System.Char[]  0   shared   static WhitespaceChars
    >> Domain:Value  000d5eb8:026203f0 000fb4c0:02624504 000ca848:026745f0 1d8334d8:026dcef4 <<
*************
Name: System.String
MethodTable: 790f9244
EEClass: 790f91a4
Size: 32786(0x8012) bytes
(C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)
String:
g8PFgIfAQUHYWFhYWFhYWRkAgMPDxYCHwEFCWFhYWFhYWFhYWRkAgQPDxYCHwEFCjI4LzEyLzIwMDdkZAIvD2QWAmY
PZBYCZg9kFgICAw8PFgIfAQUFWFhYWFhkZAIxDw8WAh8JZ2QWBGYPZBYEAgEPZBYCZg9kFgQCAQ8WAh8IBQMxcHgWA
gIBDw8WAh8JaGRkAgMPZBYEAgEPDxYCHwEFCkFkZCBSZWNvcmRkZAIDDw8WAh8ABRZ+L0ltYWdlcy9UaXRsZS9OZXc
...

Fields:
      MT    Field   Offset                 Type VT     Attr    Value Name
790fdb60  4000096        4         System.Int32  1 instance    16385 m_arrayLength
790fdb60  4000097        8         System.Int32  1 instance    10960 m_stringLength
790fad38  4000098        c          System.Char  1 instance       3c m_firstChar
790f9244  4000099       10        System.String  0   shared   static Empty
    >> Domain:Value  000d5eb8:790d57b4 000fb4c0:790d57b4 000ca848:790d57b4 1d8334d8:790d57b4 <<
79122994  400009a       14        System.Char[]  0   shared   static WhitespaceChars
    >> Domain:Value  000d5eb8:026203f0 000fb4c0:02624504 000ca848:026745f0 1d8334d8:026dcef4 <<
*************
Name: System.String
MethodTable: 790f9244
EEClass: 790f91a4
Size: 11282(0x2c12) bytes
(C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)
String:
WFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWGRkAiEPDxYCHwEFZFhYWFhYWFhYWFhYWFhYWFhYWFhYWFa
YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWF
hYWFhYWFhYWFhYWFhYWFhkZAInDw8WCh8CBQFFHwMFCjIyLzExLzIwMDcfBAUBVh8FBQFFHwYFASpkZAIpD2QWBGYPZ
...

Fields:
      MT    Field   Offset                 Type VT     Attr    Value Name
790fdb60  4000096        4         System.Int32  1 instance     5633 m_arrayLength
790fdb60  4000097        8         System.Int32  1 instance     3092 m_stringLength
790fad38  4000098        c          System.Char  1 instance       5b m_firstChar
790f9244  4000099       10        System.String  0   shared   static Empty
    >> Domain:Value  000d5eb8:790d57b4 000fb4c0:790d57b4 000ca848:790d57b4 1d8334d8:790d57b4 <<
79122994  400009a       14        System.Char[]  0   shared   static WhitespaceChars
    >> Domain:Value  000d5eb8:026203f0 000fb4c0:02624504 000ca848:026745f0 1d8334d8:026dcef4 <<
*************
Name: System.String
MethodTable: 790f9244
EEClass: 790f91a4
Size: 32786(0x8012) bytes
(C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)
String:
SRU5UIFBBR0U6IDMgb2YgMTVkZAILD2QWAmYPZBYcAgcPDxYCHwEFZFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWF
hYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYW
FhYWFhkZAINDw8WCh4BRQUBRR4CVFQFCjIyLzExLzIwMDceAlRWBQFWHgJURQUBRR4CVFIFASpkZAITDw8WCh8CBQFF
...

Fields:
      MT    Field   Offset                 Type VT     Attr    Value Name
790fdb60  4000096        4         System.Int32  1 instance    16385 m_arrayLength
790fdb60  4000097        8         System.Int32  1 instance    10960 m_stringLength
790fad38  4000098        c          System.Char  1 instance       3c m_firstChar
790f9244  4000099       10        System.String  0   shared   static Empty
    >> Domain:Value  000d5eb8:790d57b4 000fb4c0:790d57b4 000ca848:790d57b4 1d8334d8:790d57b4 <<
79122994  400009a       14        System.Char[]  0   shared   static WhitespaceChars
    >> Domain:Value  000d5eb8:026203f0 000fb4c0:02624504 000ca848:026745f0 1d8334d8:026dcef4 <<
*************
Name: System.String
MethodTable: 790f9244
EEClass: 790f91a4
Size: 32786(0x8012) bytes
(C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)
String:
0b25Ib21lBR9BcHBsaWNhdGlvbk5hdmlnYXRpb246aWJ0TG9nb3V0BTdfY3RsMDpQZXJzb25BcHBsaWNhdGlvbkRlZ3J
lZUxpc3Q6U3lzdGVtVGl0bGU6RWRpdEltYWdlBT5fY3RsMDpQZXJzb25BcHBsaWNhdGlvbkRlZ3JlZURpcGxvbWFMaXN
0OlN5c3RlbVRpdGxlOkVkaXRJbWFnZQVDX2N0bDA6UGVyc29uQXBwbGljYXRpb25PdGhlclF1YWxpZmljYXRpb25MaXN
...

Fields:
      MT    Field   Offset                 Type VT     Attr    Value Name
790fdb60  4000096        4         System.Int32  1 instance    16385 m_arrayLength
790fdb60  4000097        8         System.Int32  1 instance    10960 m_stringLength
790fad38  4000098        c          System.Char  1 instance       3c m_firstChar
790f9244  4000099       10        System.String  0   shared   static Empty
    >> Domain:Value  000d5eb8:790d57b4 000fb4c0:790d57b4 000ca848:790d57b4 1d8334d8:790d57b4 <<
79122994  400009a       14        System.Char[]  0   shared   static WhitespaceChars
    >> Domain:Value  000d5eb8:026203f0 000fb4c0:02624504 000ca848:026745f0 1d8334d8:026dcef4 <<
*************
Name: System.String
MethodTable: 790f9244
EEClass: 790f91a4
Size: 6826(0x1aaa) bytes
(C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)
String:
/wEPDwULLTEyMTQ5MDkyMjgPZBYCAgEPZBYGAgcPZBYEAgEPDxYCHghJbWFnZVVybAUrfi9pbWFnZXMvbmF2ZAILD2QW
aWdhdGlvbi9wYWdlcy9QYWdlMlByb2dyZXNzLmdpZmRkAgIPDxYCHgRUZXh0BRVDVVJSRU5UIFBBR0U6IDMgb2YgMTVk
ZAILD2QWAmYPZBYcAgcPDxYCHwEFZFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhY
...

Fields:
      MT    Field   Offset                 Type VT     Attr    Value Name
790fdb60  4000096        4         System.Int32  1 instance     3405 m_arrayLength
790fdb60  4000097        8         System.Int32  1 instance     3404 m_stringLength
790fad38  4000098        c          System.Char  1 instance       2f m_firstChar
790f9244  4000099       10        System.String  0   shared   static Empty
    >> Domain:Value  000d5eb8:790d57b4 000fb4c0:790d57b4 000ca848:790d57b4 1d8334d8:790d57b4 <<
79122994  400009a       14        System.Char[]  0   shared   static WhitespaceChars
    >> Domain:Value  000d5eb8:026203f0 000fb4c0:02624504 000ca848:026745f0 1d8334d8:026dcef4 <<
*************
Unknown option: ------------------------------
*************

Let’s analyze the exact syntax. Here’s the command

.foreach(myVariable {!dumpheap -type System.String -min 6500 -short}){!do myVariable;.echo *************}

“myVariable” is, as the name implies, the name of the variable that I wish to use for the data generated by the first set of commands. The second set of commands is what I wish to execute for each token. First I run !do on the variable, and then I use the .echo-command to print a separator in order to make it a bit easier on the eyes.

There are additional parameters you can use. For example you can choose to skip every n number of variables, or specify a text file to be parsed and used as tokens instead. Take a look at the windbg documentation if you’re interested.

.shellPermalink

I first saw this being used by my colleague Doug Stewart, who is a genius with these things.

0:000> .shell -i - -ci "!iisinfo.clientconns" FIND /c "Request active"
40
.shell: Process exited

What it does is, it runs !iisinfo.clientonns and uses the MS-DOS FIND-command to count the number of times the string “Request active” appears. Off course you could use it to search for certain strings from any type of output, like ".shell -i - -ci "!do 0b62e790" FIND /c /i "<table"" or whatever suits your needs.

Let’s take a quick look at the syntax.

When it comes to .shell the -i option is mandatory. It specifies the file we want to use for input. In this scenario we don’t want to use a file, so we add another hyphen, resulting in the following syntax: .shell -i -

We then add the -ci option, which states that we should treat the following commands as an input file instead. .shell -i - -ci "!iisinfo.clientconns"

Finally we state what shell command we wish to run using this input. .shell -i - -ci "!iisinfo.clientconns" FIND /c "Request active".

Naturally we can use any complicated command we wish in the statement, so instead of !iisinfo.clientconns we could run one of our .foreach-loops instead.

/ Johan

posted @ 2021-05-28 16:50  特洛伊-Micro  阅读(350)  评论(0编辑  收藏  举报