【翻译 windbg - 1】Getting started with windbg - part I (第一部分 1)

最近在看相关内容,作者写的相当不错,自己随手学习了一下,非常棒,顺便也锻炼一下自己的翻译能力(好久没有处理相关内容了,能力直线下降啊)

原文地址:

 

Getting started with windbg - part I

Ok,在此之前随便写了一些帖子,关于“如何设置 windbg”和“如何查找OutOfMemoryException”。我的重新复习一些基础内容,为了更好的使用这些特殊的工具。

windbg基础配置:

1、 将sos.dll 从
framework 安装目录拷贝到 windbg 的安装目录。请确保 sos.dll 文件的版本和即将要分析的版本一致。如果正同时使用 1.1 和 2.0 版本,可以重新命名文件为 sos.dll 为 sos11.dll 和 sos20.dll ,或则将 sos.dll 单独放置到不同的目录;

2、 创建缓存符号文件夹。比如: c:/symbols

3、启动 windbg,打开配置对话框(File -> Open Symbol Path,快捷键 Ctrl + S)

4、输入符号文件夹位置。使用如下语法缓存缺失的符号文件(符号文件夹位置: c:/symbols public)
srv*[cache path]*[symbols path]
推荐输入如下内容:
Srv*c:/symbols public*http://msdl.microsoft.com/download/symbols

经过上述步骤后,即可打开已经存储的 dump 文件或附加进程,进行调试分析。  

 

常用命令

以下实例基于 IIS6 的dump文件【标记1】 。

首先做的就是加载 sos 扩展功能dll。使用的是 load 命令,命令比较简单,语法如下:

.load [extension filename]

 所以想加载未修改名称的sos.dll
文件,只需要简单的输入:

.load sos.dll

等加载成功后,即可使用sos 扩展的非常酷的命令,就像windbg 的默认命令一样。扩展命令通常都是以
“!” 开头。如果想运行 help 命令,只需要输入:

!help

即可显示当前扩展的帮助命令。

如果使用多个标识扩展命令,可使用 ![extension name].[command] 进行区分,例如:

!sos.help  【标记2】

Ok,到这里我们知道了如何运行扩展命令,尝试输入 !help 回车,可以看到如下结果:


0:000>
!help

*New* Use
!CLRUsage to see how much memory .NET is actually using, including reserved
memory. To see more tips, run !tip.

-------------------------------------------------------------------------------

SOS is a
debugger extension DLL designed to aid in the debugging of managed

programs.
Functions are listed by category, then roughly in order of

importance.
Shortcut names for popular functions are listed in parenthesis.

Type
"!help <functionname>" for detailed info on that function.

 

Object
Inspection                  Examining
code and stacks

-----------------------------      -----------------------------

DumpObj
(do)                       Threads (t)

DumpAllExceptions
(dae)            CLRStack

DumpStackObjects
(dso)             IP2MD

DumpHeap
(dh)                      U

DumpVC                             DumpStack

GCRoot                             EEStack

ObjSize                            GCInfo

FinalizeQueue                      COMState

DumpDynamicAssemblies
(dda)        X

DumpField
(df)                     SearchStack

TraverseHeap
(th)

GCRef

 

Examining CLR
data structures      Diagnostic
Utilities

-----------------------------      -----------------------------

DumpDomain                         VerifyHeap (vh)

EEHeap                             DumpLog

Name2EE                            FindAppDomain

SyncBlk                            SaveModule

DumpASPNETCache
(dac)              SaveAllModules (sam)

DumpMT                             GCHandles

DumpClass                          GCHandleLeaks

DumpMD                             FindDebugTrue

Token2EE                           FindDebugModules

EEVersion                          Bp

DumpSig                            ProcInfo

DumpModule                         StopOnException
(soe)

ThreadPool
(tp)                    TD

ConvertTicksToDate
(ctd)           Analysis

ConvertVTDateToDate
(cvtdd)        Bl

RWLock                             CheckCurrentException (cce)

DumpConfig                         CurrentExceptionName
(cen)

DumpHttpRuntime                    ExceptionBp

DumpSessionStateConfig             FindTable

DumpBuckets                        LoadCache

DumpHistoryTable                   SaveCache

DumpRequestTable                   ASPXPages

DumpCollection
(dc)                DumpGCNotInProgress

DumpDataTables                     CLRUsage

GetWorkItems                                                 

DumpLargeObjectSegments
(dl)      

DumpModule

DumpAssembly                       Other

DumpMethodSig                     
-----------------------------

DumpRuntimeTypes                   FAQ

PrintIPAddress

DumpHttpContext

DumpXmlDocument
(dxd)

 

如果想查找某个命令更多详细的内容,输入 !help [command name] 即可,例如:


0:000>
!help eeversion

*New* Use
!DumpDataTables to see interesting information about System.Data.DataTables.
To see more tips, run !tip.

-------------------------------------------------------------------------------

!EEVersion

 

This prints
the Common Language Runtime Version. It also tells you if the code

is running in
"Workstation" or "Server" mode, a distinction which
affects the

garbage
collector. The most apparent difference in the debugger is that in

"Server"
mode there is one dedicated garbage collector thread per CPU.

 

A handy
supplement to this function is to also run "lm v m mscorwks". That

will provide
more details about the CLR, including where mscorwks.dll is

loaded from.

 

.time

这个不是 sos 命令。很明显该命令不是以 ! 开头。.time 命令显示与时间有关的信息,比如系统运行时间、处理器运行时间、内核总运行时间和用户模式处理时间。


0:000> .time

Debug session
time: Fri Jan  2 14:57:48.000 2009
(GMT+8)

System Uptime:
2 days 6:25:27.664

Process Uptime:
1 days 15:51:25.000

  Kernel time: 0 days 1:04:32.000

  User time: 0 days 16:55:49.000

如你所见,系统已运行2天,处理器运行 1天16小时左右,CPU累计运行18小时(kernel time + user time),根据这些信息,可以推测出CPU平均使用率为44%左右。

 

!threadpool

可以使用 !threadpool 命令精确的查找出,dump文件时cpu的使用情况。同时可以得到其他的有用的信息,例如:等待请求队列的数量,已完成的线程和时间【标注3】


0:000>
!threadpool
CPU utilization 100%
Worker Thread: Total: 5 Running: 4 Idle: 1 MaxLimit: 200 MinLimit: 2
Work Request in Queue: 16
Unknown Function: 6a2d945d  Context: 023ede30
Unknown Function: 6a2d945d  Context: 023ee1e8
AsyncTimerCallbackCompletion TimerInfo@11b53760
Unknown Function: 6a2d945d  Context: 023ee3a8
Unknown Function: 6a2d945d  Context: 023e3040
Unknown Function: 6a2d945d  Context: 023ee178
Unknown Function: 6a2d945d  Context: 023edfb0
AsyncTimerCallbackCompletion TimerInfo@11b36428
AsyncTimerCallbackCompletion TimerInfo@11b53868
Unknown Function: 6a2d945d  Context: 023ee060
Unknown Function: 6a2d945d  Context: 023ee290
Unknown Function: 6a2d945d  Context: 023eded0
Unknown Function: 6a2d945d  Context: 023edd88
Unknown Function: 6a2d945d  Context: 023ede98
Unknown Function: 6a2d945d  Context: 023ee258
Unknown Function: 6a2d945d  Context: 023edfe8
--------------------------------------
Number of Timers: 9
--------------------------------------
Completion Port Thread:Total: 3 Free: 3 MaxFree: 4 CurrentLimit: 2 MaxLimit:
200 MinLimit: 2

根据上述信息,可以看出cpu正100%的使用,下一个要运行的命令。

 

!runaway

这是一个非常棒的命令,可以列出当前正在运行的线程和cpu使用情况。如果正在检查cpu 高使用率的相关内容时,它更是你不可分离的好帮手。


0:000> !runaway
User Mode Time
  Thread       Time
  25:1a94      0 days 0:00:39.937
  16:1bc0      0 days 0:00:38.390
  50:1e8c      0 days 0:00:08.859
  52:1e40      0 days 0:00:08.687
  20:1c2c      0 days 0:00:08.234
  51:1340      0 days 0:00:08.171
  21:1bcc      0 days 0:00:06.953
  26:13ec      0 days 0:00:06.671
  44:131c      0 days 0:00:03.906
  22:d8c       0 days 0:00:03.375
  33:78c       0 days 0:00:02.656
  34:1a8c      0 days 0:00:00.906
  29:1f5c      0 days 0:00:00.828
   6:e28       0 days 0:00:00.625
   5:1c78      0 days 0:00:00.546
  23:14a4      0 days 0:00:00.484
   4:5ac       0 days 0:00:00.437
  45:5dc       0 days 0:00:00.421
   3:13b4      0 days 0:00:00.421
  47:19c8      0 days 0:00:00.375
  28:1b6c      0 days 0:00:00.250
  46:1dac      0 days 0:00:00.156
   7:1dd8      0 days 0:00:00.109
  48:cdc       0 days 0:00:00.093
  49:1eac      0 days 0:00:00.062
  15:1a64      0 days 0:00:00.062
   0:1804      0 days 0:00:00.046
  36:4a4       0 days 0:00:00.031
  11:1eb4      0 days 0:00:00.031
   1:10b4      0 days 0:00:00.031
  31:16ac      0 days 0:00:00.015
  14:4ac       0 days 0:00:00.015
   2:186c      0 days 0:00:00.015
  59:590       0 days 0:00:00.000
  58:294       0 days 0:00:00.000
  57:16d0      0 days 0:00:00.000
  56:1578      0 days 0:00:00.000
  55:1428      0 days 0:00:00.000
  54:16d8      0 days 0:00:00.000
  53:fd8       0 days 0:00:00.000
  43:1b8c      0 days 0:00:00.000
  42:1c24      0 days 0:00:00.000
  41:1e2c      0 days 0:00:00.000
  40:11b0      0 days 0:00:00.000
  39:edc       0 days 0:00:00.000
  38:1a08      0 days 0:00:00.000
  37:171c      0 days 0:00:00.000
  35:1254      0 days 0:00:00.000
  32:1f9c      0 days 0:00:00.000
  30:1ae8      0 days 0:00:00.000
  27:190c      0 days 0:00:00.000
  24:1d2c      0 days 0:00:00.000
  19:1e38      0 days 0:00:00.000
  18:ee4       0 days 0:00:00.000
  17:fb8       0 days 0:00:00.000
  13:1b54      0 days 0:00:00.000
  12:1a48      0 days 0:00:00.000
  10:f64       0 days 0:00:00.000
   9:1024      0 days 0:00:00.000
   8:1b78      0 days 0:00:00.000

如你所见,时间总和和前面通过.time 命令获得的cpu时间不一致。是因为线程可以被反复使用和回收,即:一个线程使用cpu总量可以分开为多个页请求。【标注4】

!threads

为了获取更多的关于线程的信息,可以使用 !threads 命令。该命令将列表显示出应用程序所有正在运行的线程,当前应用程序域中后台正在运行的程序,等等线程相关内容。输出如下:


0:000> !threads

ThreadCount: 8

UnstartedThread: 0

BackgroundThread: 2

PendingThread: 0

DeadThread: 5

                                 
PreEmptive   GC Alloc                     Lock    

       
ID  ThreadOBJ       State     GC      
Context           Domain     Count APT Exception

 
0  0xfc4 0x00143348        0x20 Enabled  0x00000000:0x00000000 0x0015c3b8     0 Ukn

 
2  0xff8 0x001619c0      0xb220 Enabled  0x00000000:0x00000000 0x0015c3b8     0 MTA (Finalizer)

XXX     
0 0x001887b0      0x1820
Enabled  0x00000000:0x00000000
0x0015c3b8     0 Ukn

XXX     
0 0x00188b28      0x1820
Enabled  0x00000000:0x00000000
0x0015c3b8     0 Ukn

XXX     
0 0x001ac540      0x1820
Enabled  0x00000000:0x00000000
0x0015c3b8     0 MTA

 10
0x13b4 0x00186df8   0x1800220
Enabled  0x00000000:0x00000000
0x0015c3b8     0 MTA (Threadpool Worker)

XXX     
0 0x00187c48   0x1800820
Enabled  0x00000000:0x00000000
0x0015c3b8     0 Ukn (Threadpool
Worker)

XXX     
0 0x0785b490   0x1800820
Enabled  0x00000000:0x00000000
0x0015c3b8     0 Ukn (Threadpool Worker)

如果线程ID列值为 XXXX ,则表示该线程已经终止,正等待被回收。终止线程Finalizer thread 的ID为2。如果在2号线程上有不正常的活动,运行 !threads 命令就可以知道终止线程相关的事件。

 

线程间的切换

为了切换到特定的线程上查看相关内容,可以使用
~[thread id]s 命令。譬如,想切换到finalizer
thread ,可以使用如下命令:

0:002> ~2s

现在我们就切换到了2号线程中了,在此基础上就可以继续使用其他的有用命令。

 

!clrstack

这个超强的命令可以列出当前线程中的调用栈信息。如果想查看额外的信息,添加
“-p”选项,该选项将同时显示相关参数和本地变量。

如下是在线程 10 上运行 clrstack 的清单表:


0:010> !clrstack

Thread 10

ESP         EIP      

0x0d0ff5f8  0x7c90e4f4 [FRAME:
NDirectMethodFrameStandalone] [DEFAULT] I4
System.Data.OracleClient.UnsafeNativeMethods.OCIStmtFetch(ValueClass
System.Runtime.InteropServices.HandleRef,ValueClass System.Runtime.InteropServices.HandleRef,I4,ValueClass
FETCH,ValueClass MODE)

0x0d0ff608  0x05081deb [DEFAULT] I4
System.Data.OracleClient.TracedNativeMethods.OCIStmtFetch(Class
System.Data.OracleClient.OciHandle,Class
System.Data.OracleClient.OciHandle,I4,ValueClass FETCH,ValueClass MODE)

0x0d0ff644  0x050817c9 [DEFAULT] [hasThis] Boolean
System.Data.OracleClient.OracleDataReader.ReadInternal()

0x0d0ff664  0x05081673 [DEFAULT] [hasThis] Boolean
System.Data.OracleClient.OracleDataReader.Read()

0x0d0ff66c  0x05081618 [DEFAULT] [hasThis] I4
System.Data.Common.DbDataAdapter.FillLoadDataRow(Class
System.Data.Common.SchemaMapping)

0x0d0ff6a4  0x00c1ecb0 [DEFAULT] [hasThis] I4
System.Data.Common.DbDataAdapter.FillFromReader(Object,String,Class
System.Data.IDataReader,I4,I4,Class System.Data.DataColumn,Object)

0x0d0ff6f8  0x00c1eb2a [DEFAULT] [hasThis] I4
System.Data.Common.DbDataAdapter.Fill(Class System.Data.DataSet,String,Class
System.Data.IDataReader,I4,I4)

0x0d0ff71c  0x00c1b51a [DEFAULT] [hasThis] I4
System.Data.Common.DbDataAdapter.FillFromCommand(Object,I4,I4,String,Class
System.Data.IDbCommand,ValueClass System.Data.CommandBehavior)

0x0d0ff76c  0x00c1b3ce [DEFAULT] [hasThis] I4
System.Data.Common.DbDataAdapter.Fill(Class
System.Data.DataSet,I4,I4,String,Class System.Data.IDbCommand,ValueClass
System.Data.CommandBehavior)

0x0d0ff794  0x00c1b1ff [DEFAULT] [hasThis] I4
System.Data.Common.DbDataAdapter.Fill(Class System.Data.DataSet)

0x0d0ff7a0  0x00c1a54c [DEFAULT] [hasThis] Class
System.Data.DataSet Dba.Wrapper.OracleWrapper.QueryDataSet(String,SZArray
Class Dba.Parameter)

 
at [+0x7c] [+0x29]

0x0d0ff7b4  0x00c170b0 [DEFAULT] Class
System.Data.DataTable
Sample.Access.Base.DataAccess.DbUtil.QueryDataTable(Class
Dba.IDBWrapper,String)

 
at [+0xc0] [+0x2b]

0x0d0ff804  0x0093660e [DEFAULT] Class
System.Data.DataTable Sample.Access.Dao.ConConfigQuery.GetAllCalItemsInfo(Class
Dba.IDBWrapper,I8,String,Boolean,Boolean)

 
at [+0x176] [+0x8d]

0x0d0ff858  0x00935814 [DEFAULT] [hasThis] Void
Sample.Business.Contract.Template.EvaluatorParameter.LoadEvaluatorParameter(String,Boolean,Boolean)

 
at [+0x74] [+0x29]

0x0d0ff8a4  0x009351c5 [DEFAULT] [hasThis] Void
Sample.Business.Contract.Template.TemplateEvaluator.StartAllCalTread()

 
at [+0x15d] [+0xa5]

0x0d0ff8f0  0x05086a13 [DEFAULT] [hasThis] Boolean
Sample.Business.Contract.MaterialConf.GenerateMaterialMng.RefreshMaterial(Class
Dba.IDBWrapper,String,Boolean,String,String,Boolean)

 
at [+0xe3] [+0x46]

0x0d0ff944  0x00c11a48 [DEFAULT] [hasThis] Void
Sample.UI.Win.Service.MaterialManager.RefreshMaterial()

 
at [+0x2c0] [+0x132]

0x0d0ff9d0  0x00c1175d [DEFAULT] [hasThis] Void
Sample.UI.Win.Service.MaterialManager.tm_Elapsed(Object,Class
System.Timers.ElapsedEventArgs)

 
at [+0x1d] [+0xd]

0x0d0ff9e8  0x7b29984d [DEFAULT] [hasThis] Void
System.Timers.Timer.MyTimerCallback(Object)

 

如果运行 !clrstack –p将得到如下结果:


0:010> !clrstack -p

Thread 10

ESP         EIP      

0x0d0ff5f8  0x7c90e4f4 [FRAME:
NDirectMethodFrameStandalone] [DEFAULT] I4
System.Data.OracleClient.UnsafeNativeMethods.OCIStmtFetch(ValueClass
System.Runtime.InteropServices.HandleRef,ValueClass
System.Runtime.InteropServices.HandleRef,I4,ValueClass FETCH,ValueClass MODE)

0x0d0ff608  0x05081deb [DEFAULT] I4
System.Data.OracleClient.TracedNativeMethods.OCIStmtFetch(Class
System.Data.OracleClient.OciHandle,Class System.Data.OracleClient.OciHandle,I4,ValueClass
FETCH,ValueClass MODE)

0x0d0ff644  0x050817c9 [DEFAULT] [hasThis] Boolean
System.Data.OracleClient.OracleDataReader.ReadInternal()

0x0d0ff664  0x05081673 [DEFAULT] [hasThis] Boolean
System.Data.OracleClient.OracleDataReader.Read()

0x0d0ff66c  0x05081618 [DEFAULT] [hasThis] I4
System.Data.Common.DbDataAdapter.FillLoadDataRow(Class
System.Data.Common.SchemaMapping)

0x0d0ff6a4  0x00c1ecb0 [DEFAULT] [hasThis] I4
System.Data.Common.DbDataAdapter.FillFromReader(Object,String,Class System.Data.IDataReader,I4,I4,Class
System.Data.DataColumn,Object)

0x0d0ff6f8  0x00c1eb2a [DEFAULT] [hasThis] I4
System.Data.Common.DbDataAdapter.Fill(Class System.Data.DataSet,String,Class
System.Data.IDataReader,I4,I4)

0x0d0ff71c  0x00c1b51a [DEFAULT] [hasThis] I4
System.Data.Common.DbDataAdapter.FillFromCommand(Object,I4,I4,String,Class
System.Data.IDbCommand,ValueClass System.Data.CommandBehavior)

0x0d0ff76c  0x00c1b3ce [DEFAULT] [hasThis] I4
System.Data.Common.DbDataAdapter.Fill(Class System.Data.DataSet,I4,I4,String,Class
System.Data.IDbCommand,ValueClass System.Data.CommandBehavior)

0x0d0ff794  0x00c1b1ff [DEFAULT] [hasThis] I4
System.Data.Common.DbDataAdapter.Fill(Class System.Data.DataSet)

0x0d0ff7a0  0x00c1a54c [DEFAULT] [hasThis] Class
System.Data.DataSet Dba.Wrapper.OracleWrapper.QueryDataSet(String,SZArray
Class Dba.Parameter)

 
at [+0x7c] [+0x29]

0x0d0ff7b4  0x00c170b0 [DEFAULT] Class
System.Data.DataTable
Sample.Access.Base.DataAccess.DbUtil.QueryDataTable(Class
Dba.IDBWrapper,String)

 
at [+0xc0] [+0x2b]

   
PARAM: class Dba.IDBWrapper wrapper: 0x3b9599e8

   
PARAM: class System.String sql: 0x1d004690 (System.String)

0x0d0ff804  0x0093660e [DEFAULT] Class
System.Data.DataTable
Sample.Access.Dao.ConConfigQuery.GetAllCalItemsInfo(Class Dba.IDBWrapper,I8,String,Boolean,Boolean)

 
at [+0x176] [+0x8d]

   
PARAM: class Dba.IDBWrapper dbWrapper: 0x3b9599e8

   
PARAM: int64 contract_header_id: 3052226

   
PARAM: class System.String RegionCode: 0x00f67850 (System.String)

   
PARAM: bool isDiff: false

   
PARAM: bool genMaterial: true

0x0d0ff858  0x00935814 [DEFAULT] [hasThis] Void
Sample.Business.Contract.Template.EvaluatorParameter.LoadEvaluatorParameter(String,Boolean,Boolean)

 
at [+0x74] [+0x29]

   
PARAM: this: 0x1cfff894 (Sample.Business.Contract.Template.EvaluatorParameter)

   
PARAM: class System.String contractID: 0x3b95be28 (System.String)

   
PARAM: bool isDiff: false

   
PARAM: bool genMaterial: true

0x0d0ff8a4  0x009351c5 [DEFAULT] [hasThis] Void
Sample.Business.Contract.Template.TemplateEvaluator.StartAllCalTread()

 
at [+0x15d] [+0xa5]

   
PARAM: this: 0x1cfff848
(Sample.Business.Contract.Template.TemplateEvaluator)

0x0d0ff8f0  0x05086a13 [DEFAULT] [hasThis] Boolean
Sample.Business.Contract.MaterialConf.GenerateMaterialMng.RefreshMaterial(Class
Dba.IDBWrapper,String,Boolean,String,String,Boolean)

 
at [+0xe3] [+0x46]

   
PARAM: this: 0x3b959a8c
(Sample.Business.Contract.MaterialConf.GenerateMaterialMng)

   
PARAM: class Dba.IDBWrapper dbWrappe: 0x3b9599e8

   
PARAM: class System.String contractID: 0x3b95be28 (System.String)

   
PARAM: bool isDiff: false

   
PARAM: class System.String contractNumber: 0x3b95a7cc (System.String)

   
PARAM: class System.String email: 0x00f311f4 (System.String)

   
PARAM: bool isOld: false

0x0d0ff944  0x00c11a48 [DEFAULT] [hasThis] Void
Sample.UI.Win.Service.MaterialManager.RefreshMaterial()

 
at [+0x2c0] [+0x132]

   
PARAM: this: 0x00f569f8 (Sample.UI.Win.Service.MaterialManager)

0x0d0ff9d0  0x00c1175d [DEFAULT] [hasThis] Void Sample.UI.Win.Service.MaterialManager.tm_Elapsed(Object,Class
System.Timers.ElapsedEventArgs)

 
at [+0x1d] [+0xd]

   
PARAM: this: 0x00f569f8 (Sample.UI.Win.Service.MaterialManager)

   
PARAM: class System.Object sender: 0x00f56b8c (System.Timers.Timer)

    PARAM:

0x0d0ff9e8  0x7b29984d [DEFAULT] [hasThis] Void
System.Timers.Timer.MyTimerCallback(Object)

使用该命令我们可以查看相关参数。如上所述,将Sample.UI.Win.Service.MaterialManager作为 Sample.UI.Win.Service.MaterialManager.tm_Elapsed的参数Object 进行传递,如果想得到更多的内容,就需要继续往下使用下个命令.

 

!dumpobject【标注5】  (!do 为简写)

这是另一个至关重要的命令。Dumpobj 显示指定地址对象的内容,只需要指定需要观察对象的地址即可,如下:


0:000> !dumpobj 0xf32fcc

Name:
System.Collections.Hashtable/bucket[]

MethodTable 0x00822c28

EEClass 0x00822ba4

Size 144(0x90) bytes

GC Generation: 2

Array: Rank 1, Type VALUETYPE

Element Type:
System.Collections.Hashtable/bucket

Content: 11 items

Ok,看到了什么?是的,0xf32fcc 是一个 System.Collections.Hashtable/bucket[]
对象,该对象有11个对象或属性,如果想继续查看对象的值,只需要继续使用 !dumpobj 或查询 MSDN 关于 Hashtable 类的说明即可,一下是该对象的更详细的内容:


0:000> !dumpobj -v 0xf32fcc

Name:
System.Collections.Hashtable/bucket[]

MethodTable 0x00822c28

EEClass 0x00822ba4

Size 144(0x90) bytes

GC Generation: 2

Array: Rank 1, Type VALUETYPE

Element Type:
System.Collections.Hashtable/bucket

Content: 11 items    【标注6 ???】

       
Address           MT   Class
Name

key: 0x00f6709c       0x00f6709c      0x79b946b0     System.String

val: 0x00f670b8        0x00f670b8      0x79baaff0       System.Int32

 

key: 0x00f54720       0x00f54720      0x79b946b0     System.String

val: 0x00f5473c        0x00f5473c      0x79baaff0       System.Int32

根据上述内容,为了更加了解key中存储的是何内容,只需要继续使用 !dumpobj 即可。


0:000> !dumpobj 0x00f6709c

String: zh-cn

Ok,这样我们就找到了,上述hastable的一个key为 zh-CN ,value 为 23


0:000> !dumpobj 0x00f670b8

Name: System.Int32

MethodTable 0x79baaff0

EEClass 0x79bab17c

Size 12(0xc) bytes

GC Generation: 2

mdToken: 0x0200009a 
(c:/windows/microsoft.net/framework/v1.1.4322/mscorlib.dll)

FieldDesc*: 0x79bab1f4

       
MT      Field     Offset                 Type       Attr      Value
Name

0x79baaff0 0x40001e9      0x4         System.Int32   instance 23 m_value

对于其他的托管堆中的对象,只要不停的使用 !dumpobj 即可找到最终的数据。

 

在接下来的文章中,我将继续使用 !dumpobj 命令来查找 w3wp 进程的内容,并介绍一下其他的非常棒的命令,敬请期待。

 

(未完待续)

 

原文:johan

翻译:AloneSword (部分内容在原有文章基础上做了修改)

 

 

【标记1】:由于没有拿到 iis6 下的 dmp 文件,翻译时是使用的xp sp3 中的一个应用程序的dmp 文件进行;

【标记2】:
在做这个命令时,一开始老是不正确。当输入 !sos.help 时,提示如下:


0:000> !sos.help

The call to LoadLibrary(sos) failed,
Win32 error 0n2

   
"The system cannot find the file specified."

Please check your debugger configuration
and/or network access.

不知道为啥,最后再看 load 命令的帮助(命令行下输入: .hh load)时,才知道需要输入sos.dll 的绝对路径(或相对路径)才可以,而我将 sos.dll 放到了 windbg/clr10 目录下,所以需要输入 !clr10/sos.help ,终于见到了熟悉的面孔了。

【标注3】:由于是app 的dump 没有多线程的实例,所以当输入 !threadpool 时,显示如下:


0:000> !threadpool

Loaded Son of Strike data table Version 5
from "C:/WINDOWS/Microsoft.NET/Framework/v1.1.4322/mscorwks.dll"

CPU utilization 80%

Worker Thread: Total: 1 Running: 1 Idle:
0 MaxLimit: 25 MinLimit: 1

Work Request in Queue: 0

--------------------------------------

Number of Timers: 0

--------------------------------------

Completion Port Thread: Total: 0 Free: 0
MaxFree: 2 CurrentLimit: 0 MaxLimit: 1000 MinLimit: 1

【标注4】:大脑在此处转不过来玩了,搞不明白了。被分配为多个了,咋时间还少了呢?

【标注5】:原文档中说是 !dumpobject 命令,但是使用 !help 找到的命令为 !dumpobj ,没有 !dumpobject ,相信是作者的笔误。

【标注6】:为啥这里显示的条目内容只有2条 Key-value ,但!dumpobj 时显示11,为啥呢?

 

时间: 2024-10-31 09:06:52

【翻译 windbg - 1】Getting started with windbg - part I (第一部分 1)的相关文章

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

    <!-- /* 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 {fon

第二章排错的工具:调试器Windbg(上)

感谢博主 http://book.51cto.com/art/200711/59731.htm <Windows用户态程序高效排错>第二章主要介绍用户态调试相关的知识和工具.本文主要讲了排错的工具调试器Windbg.     第二章 汇编.异常.内存.同步和调试器--重要的知识点和神兵利器 这一部分主要介绍用户态调试相关的知识和工具.包括汇编.异常exception.内存布局.堆heap.栈stack.CRTC Runtime.handle/Criticalsection/thread con

xp+WinDBG+VMware调试内核

呵呵,搞点突兀的标题而已.其实说的还是如何使用WinDBG和VMware来搭建调试内核的环境而已,这些网上已经有数不清的教程了,不过我喜欢自己亲手写一下.第一,把这个过程写一遍能加深印象,就算以后忘记了也可以有笔记查找,快速想起来.第二.网上的教程很多都是互相抄来抄去,连错误也抄过去了.很典型一个错误就是Baud Rate,前面还写115200,后面就写成了11520了,狂汗! 按照我这篇笔记写的步骤去做,绝对能够成功,并且还能大略地了解到为什么要这样做的原因.第1部分是步骤,如果不想看原因的,

Windbg抓取程序崩溃的dmp文件的方法

Windbg抓取程序崩溃的dmp文件的方法   一.        简介 windbg是在windows平台下,强大的用户态和内核态调试工具.相比较于Visual Studio,它是一个轻量级的调试工具,所谓轻量级指的是它的安装文件大小较小,但是其调试功能,却比VS更为强大.它的另外一个用途是可以用来分析dump数据. 我们使用windbg的主要用途是来抓取IE崩溃产生的dmp文件,然后可以查看是哪个模块导致崩溃,从而协助开发判断分析问题所在.   二.        使用方法 设置WinDbg

windbg 问题,64位dump文件在32位机的调试

问题描述 windbg 问题,64位dump文件在32位机的调试 服务器是64位机器,产生了dump文件,但是程序是本机32位上生成的,取下dump文件,用VS2008打不开堆栈信息,网上说用windbg来调试,不太会用: STACK_TEXT: WARNING: Stack unwind information not available. Following frames may be wrong. 036ee400 00c97d88 00c98ed0 013e7152 00000000 S

360浏览器如何翻译英文网页

  整个网页翻译: 1.打开360浏览器,在浏览器中打开你想浏览的英文网站,选择浏览器上面的翻译三角符号. 2.选择第一项,翻译当前网页,就会开始翻译了. 3.翻译完后,就可以看到全部是中文了. 单个句子翻译: 1.同样选择浏览器上面的翻译,选择第二项翻译文字. 2.在弹出的翻译对话框中,将要翻译的英文复制到文本框中,点击下面的翻译. 3.翻译完后,翻译的结果就在下面了,很方便的.

360浏览器怎么翻译英文网页

  整个网页翻译: 1.打开360浏览器,在浏览器中打开你想浏览的英文网站,选择浏览器上面的翻译三角符号. 2.选择第一项,翻译当前网页,就会开始翻译了. 3.翻译完后,就可以看到全部是中文了. 单个句子翻译: 1.同样选择浏览器上面的翻译,选择第二项翻译文字. 2.在弹出的翻译对话框中,将要翻译的英文复制到文本框中,点击下面的翻译. 3.翻译完后,翻译的结果就在下面了,很方便的  

.NET应用程序调试—原理、工具、方法

阅读目录: 1.背景介绍 2.基本原理(Windows调试工具箱..NET调试扩展SOS.DLL.SOSEX.DLL) 2.1.Windows调试工具箱 2.2..NET调试扩展包,SOS.DLL.SOSEX.DLL 2.3.调试系统的基本流程及架构(.NETDAC概念.mscordacwks.dll) 2.4.VisualStudio中集成扩展调试(更加细粒度的调试程序) 3.调试程序类型(客户端程序.服务端程序) 4.调试方式及场景 4.1.本机调试(Attach Process,调试器启动

一次挂死(hang)的处理过程及经验

前言: CPU占用率低,内存还有许多空余,但网站无法响应,这就是网站挂死,通常也叫做hang.这种情况对于我这样既是CEO,又是CTO,还兼职扫地洗碗的个人站长来说根本就是家常便饭.以下是一次处理hang的经验及总结,前后用了一个月,不仅涉及程序排查,数据库优化,还有硬件升级的苦恼.其中辛酸苦辣只有经历过的站长才能体会,希望此文能对各位有所帮助!        首先介绍一下网站基本情况,是一个在线小说阅读网站,每天有一定页面访问量,在优化开始前由两台服务器运行,均为Dell PowerEdge

艾伟_转载:一次挂死(hang)的处理过程及经验

 前言:        CPU占用率低,内存还有许多空余,但网站无法响应,这就是网站挂死,通常也叫做hang.这种情况对于我这样既是CEO,又是CTO,还兼职扫地洗碗的个人站长来说根本就是家常便饭.以下是一次处理hang的经验及总结,前后用了一个月,不仅涉及程序排查,数据库优化,还有硬件升级的苦恼.其中辛酸苦辣只有经历过的站长才能体会,希望此文能对各位有所帮助!        首先介绍一下网站基本情况,是一个在线小说阅读网站,每天有一定页面访问量,在优化开始前由两台服务器运行,均为Dell Po