Windbg入门:如何使用Windbg调试得到ArrayList的值

简介:
在.NET下开发时,最基本的调试方法就是使用Visual Studio的单步调试。但是对于一些特殊情况,特别是涉及到CLR内部的时候使用这种方式就达不到目的了。
如果要查看运行时内存使用情况,IL代码,CLR信息等可以使用以下两种方式:
1、使用VS2005 + sos.dll
2、使用Windbg + sos.dll
第二种方式功能更加强大,下面我就通过实际操作展示一下怎么使用这种方法得到运行时ArrayList内部的值。
有人可能会说:我直接用Visual Studio的单步调试岂不是更快?当然,这个只是一个演示,通过这个演示是为以后的高级调试打下基础

在操作之前,先熟悉一下基本知识:
A、使用VS2005 + sos.dll调试
1、需要在项目->属性->调试-〉 启用非托管代码调试
2、打开调试-〉窗口-〉即时
3、在即时窗口中输入  !load sos  加载调试模块
4、输入其它调试语句

B、使用Windbg + sos.dll
1、去微软的网站下载最新的Windbg
2、打开Windbg在File-〉Symbol File Path ...窗口中输入  srv*c:\symbols*http://msdl.microsoft.com/download/symbols 
3、运行需要调试的程序,然后在Windbg中File-〉Attach to Process中选择刚才运行的程序
4、在出现的Command窗口中就可以输入调试语句
5、常用调试语句:
 lm //查看加载了哪些模块
 .load C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\sos.dll  //加载调试模块
 ld TestClass //加载调试符号
 !name2ee TestClass.exe TestClass.Program.test  //显示test方法相关的地址
 !dumpmt -md 00976d48         //得到类的成员函数详细信息
 !dumpil 00973028    // 显示这个方法被编译器编译之后的IL代码
 !dumpheap -stat  //该命令显示程序中所有对象的统计信息,显示的大小是对象本身的大小,不包括对象里面值的大小
 !dumpheap -mt 790fcb30  //该命令显示MethodTable 790fcb30的详细信息
 !gcroot 012919b8  //来显示一个实例的所属关系
 !dumpobj(do) 012a3904 //显示一个对象的具体内容,看对象里面有什么,值是什么
 !ObjSize 012a1ba4 //对象实际在内存中的大小
 !eeheap -gc   //查看托管堆的情况(包括大小)
 !DumpArray   //查看数组信息

 下面就来看看具体的调试步骤:
1、我们的测试代码

namespace  TestClass
{
    
class Program
    
{
        [STAThread]
        
static void Main(string[] args)
        
{
            ArrayList list 
= new ArrayList();
            list.Add(
"aaaa");
            list.Add(
"bbbb");
            Console.ReadLine();
        }

    }

}
很简单,就是一个ArrayList

运行这个程序(开始执行,不调试),然后进入Windbg,Attach到这个进程

2、查看所有堆栈信息
0:004> !dumpheap -stat
      MT    Count    TotalSize Class Name
7910062c        1           12 System.Security.Permissions.SecurityPermission
7918e284        1           16 System.IO.TextReader+SyncTextReader
79102d10        1           20 Microsoft.Win32.SafeHandles.SafeFileMappingHandle
79102cb4        1           20 Microsoft.Win32.SafeHandles.SafeViewOfFileHandle
79101d30        1           20 System.Text.InternalEncoderBestFitFallback
79100a7c        1           20 Microsoft.Win32.SafeHandles.SafeFileHandle
79105cd4        1           24 System.Collections.ArrayList
......
7912ad90       11         9036 System.Object[]
790fcb30     2083       131492 System.String
Total 2202 objects

除了我们的ArrayList外,还有很多其它的系统信息,先不用管它

3、查看我们的ArrayList的信息
0:004> !dumpheap -mt 79105cd4
 Address       MT     Size
012a1b88 79105cd4       24     
total 1 objects
Statistics:
      MT    Count    TotalSize Class Name
79105cd4        1           24 System.Collections.ArrayList
Total 1 objects


4、查看对应地址内部实际的值
0:004> !do 012a1b88
Name: System.Collections.ArrayList
MethodTable: 79105cd4
EEClass: 79105c28
Size: 24(0x18) bytes
 (C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)
Fields:
      MT    Field   Offset                 Type VT     Attr    Value Name
7912ad90  40008df        4      System.Object[]  0 instance 012a1bb0 _items
791018e0  40008e0        c         System.Int32  1 instance        2 _size
791018e0  40008e1       10         System.Int32  1 instance        2 _version
790fc35c  40008e2        8        System.Object  0 instance 00000000 _syncRoot
7912ad90  40008e3      1c0      System.Object[]  0   shared   static emptyArray
    >> Domain:Value  00149c58:012a1ba0 <<
可以看到ArrayList的大小为2,具体的值保存在地址012a1bb0中,是一个System.Object[]类型的数组

5、查看数组信息
0:004> !DumpArray 012a1bb0
Name: System.Object[]
MethodTable: 7912ad90
EEClass: 7912b304
Size: 32(0x20) bytes
Array: Rank 1, Number of elements 4, Type CLASS
Element Methodtable: 790fc35c
[0] 012a1b50
[1] 012a1b6c
[2] null
[3] null

6、查看数组内对象的值
0:004> !do 012a1b50
Name: System.String
MethodTable: 790fcb30
EEClass: 790fca90
Size: 26(0x1a) bytes
 (C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)
String: aaaa
Fields:
      MT    Field   Offset                 Type VT     Attr    Value Name
791018e0  4000096        4         System.Int32  1 instance        5 m_arrayLength
791018e0  4000097        8         System.Int32  1 instance        4 m_stringLength
790fe534  4000098        c          System.Char  1 instance       61 m_firstChar
790fcb30  4000099       10        System.String  0   shared   static Empty
    >> Domain:Value  00149c58:790d81bc <<
7912b1d8  400009a       14        System.Char[]  0   shared   static WhitespaceChars
    >> Domain:Value  00149c58:012a16f0 <<

这样我们就通过Windbg得到了ArrayList运行时的值了




    本文转自永春博客园博客,原文链接:http://www.cnblogs.com/firstyi/archive/2007/12/29/1020229.html,如需转载请自行联系原作者

相关文章
|
30天前
|
NoSQL Shell 程序员
【C/C++ 调试 GDB指南 】GDB调试工具介绍:从基础到高级
【C/C++ 调试 GDB指南 】GDB调试工具介绍:从基础到高级
60 0
|
5月前
|
NoSQL 编译器 Linux
如何使用GDB工具来调试程序
如何使用GDB工具来调试程序
|
7月前
|
Windows
|
7月前
|
Windows
调试实战——使用windbg调试DLL卸载时的死锁
dll 卸载时死锁了,不怕,windbg 来解决
|
10月前
|
运维 监控 数据可视化
JVM调试命令与调试工具
JVM调试命令与调试工具
177 0
|
NoSQL IDE 开发工具
GDB技巧分享,让你的调试变得更方便
GDB是我们在嵌入式程序调试时最常使用到的调试工具,有关GDB的文章,网上早已经层出不穷。这边会分享一些GDB调试上的小技巧,也许会让大家再重新认识一下这个很熟悉的工具,也希望能让大家的调试能够更加方便。
GDB技巧分享,让你的调试变得更方便