• [翻译][windbg]查看数组中各个元素(.net 1.x)



    上篇随笔提出“如何查看数组中各个元素”的问题,没解决,今天继续搜索,看到有人介绍用dd命令查看,原文是英文,现翻译如下。

    原文: Arrays and SOS

    注意:这是在X86上调试的,如果是在IA64/AMD64上调试,数组的格式会有些许区别(比如内存地址将会是64位而不是文章中的32位)。

    预备工作:创建三个数组

    string[] strs = new string[] { "String 1", "String 2", "String 3" };

    int[] ints = new int[] { 21, 22, 23, 24, 25, 26, 27 };

    double[] fps = new double[] { 3.14 };

    首先,用 !sos.dso命令获取这些数组的地址

    0:000> !sos.dso
    ESP/REG Object Name
    0012ec94 00ac2ad8 System.Double[]
    0012eca8 00ac2a88 System.Object[]
    0012ecac 00ac2aa4 System.Int32[]

    (自语:数组元素是值类型(自定义的结构体)的场合,输出的都是该类型的数组形式,如System.Double[];元素是引用类型的场合,则以 System.Object[]形式出现。)

    接着,用!do命令获取该数组的类型信息

    0:000> !do 00ac2aa4
    Name: System.Int32[]
    MethodTable: 5b9ca974
    EEClass: 5ba4d4ec
    Size: 40(0x28) bytes
    Array: Rank 1, Type Int32
    Element Type: System.Int32
    Fields:
    None

    OK,这是Int32型的数组,每个子元素占4字节。由于!do只能查看数组对象本身的信息,不能深入到其子元素,所以这里用到dd命令

    0:000> dd 00ac2aa4
    00ac2aa4  5b9ca974 00000007 00000015 00000016
    00ac2ab4  00000017 00000018 00000019 0000001a
    00ac2ac4  0000001b 00010000 5b9938b0 00000000
    00ac2ad4  00010000 5b9c9b18 00000001 51eb851f
    00ac2ae4  40091eb8 00010000 5b9b2be0 00000006
    00ac2af4  00000000 00000080 00010000 5b9c6614
    00ac2b04  00000001 5b9938b0 00ac2aec 00010000
    00ac2b14  5b9b2c8c 00000080 00010000 5b9b413c

    首列是序号,显示的是该行起始的内存地址,可以看出,每行16字节,一列4字节。

    着重说下高亮显示的那几条数据。绿色的那条是该数组的方法表,如果之前没用!do命令查看数组信息的话,可以用!dumpmt命令查看一下

     0:000> !dumpmt 5b9ca974
    EEClass: 5ba4d4ec
    Module: 5b918000
    Name: System.Int32[]
    mdToken: 02000000 (C:"WINNT"Microsoft.NET"Framework"v2.0.40428"assembly"GAC_32"mscorlib"2.0.3600.0__b77a5c561934e089"mscorlib.dll)
    BaseSize: 0xc
    ComponentSize: 0x4
    Number of IFaces in IFaceMap: 4
    Slots in VTable: 25

     黄色的这条告诉我们这个数组有多少子元素,这里显示的是7个,Int32是4字节(一个Int32用一列表示),黄条后面的7个红条条保存的就是该数组7个子元素的值(21-27)。

    *这里的数值是用16进制表示,所以15对应的是十进制的21。

    然后,我们分析double[]型的。一个double占8字节(一个Double需要二列表示)。

    0:000> dd 00ac2ad8
    00ac2ad8  5b9c9b18 00000001 40091eb8 51eb851f
    00ac2ae8  00010000 5b9b2be0 00000006 00000000
    00ac2af8  00000080 00010000 5b9c6614 00000001
    00ac2b08  5b9938b0 00ac2aec 00010000 5b9b2c8c
    00ac2b18  00000080 00010000 5b9b413c 00ac2b80
    00ac2b28  00010100 00000000 00010000 5b9b4668
    00ac2b38  00000000 00000009 0000000a 00010000
    00ac2b48  5b9c6614 0000000a 5b9938b0 00000000

    老样子,绿条条是该数组的方法表,黄条条表示该数组只有1个子元素。前面也说了,是double型的,要8字节,需要2列合起来表示一个double。

    0X40091eb851eb851f,反正我是看不出这个值是多少,借助命令.formats

     0:000> .formats 40091eb851eb851f Evaluate expression:
      Hex:     40091eb8`51eb851f
      Decimal: 4614253070214989087
      Octal:   0400110753412172702437
      Binary:  01000000 00001001 00011110 10111000 01010001 11101011 10000101 00011111
      Chars:   @...Q...
      Time:    Fri Dec 27 09:23:41.498 16222 (GMT-7)
      Float:   low 1.26444e+011 high 2.1425
      Double:  3.14

    结果出来了,3.14。

    最后,分析object[]。老样子,dd

    0:000> dd 00ac2a88
    00ac2a88  5b9c6614 00000003 5b99452c 00ac2a1c
    00ac2a98  00ac2a40 00ac2a64 00010000 5b9ca974

    00ac2aa8  00000007 00000015 00000016 00000017
    00ac2ab8  00000018 00000019 0000001a 0000001b
    00ac2ac8  00010000 5b9938b0 00000000 00010000
    00ac2ad8  5b9c9b18 00000001 51eb851f 40091eb8
    00ac2ae8  00010000 5b9b2be0 00000006 00000000
    00ac2af8  00000080 00010000 5b9c6614 00000001

     这个数组有3个子元素。这里有个问题,到目前为止只知道这是个object,具体什么类型一无所知,天无绝人之路,紫条条的就是元素的方法表(与绿条条object的方法表不同)。接着就用!dumpmt查看该元素的类型。

    0:000> !dumpmt 5b99452c
    EEClass: 5b9d7f10
    Module: 5b918000
    Name: System.String
    mdToken: 02000027 (C:"WINNT"Microsoft.NET"Framework"v2.0.40428"assembly"GAC_32"mscorlib"2.0.3600.0__b77a5c561934e089"mscorlib.dll)
    BaseSize: 0x10
    ComponentSize: 0x2
    Number of IFaces in IFaceMap: 5
    Slots in VTable: 190

     很明显,这是String型的。由于是string型的,后面3个红条条保存的是内存地址,这里要用 !do命令查看具体的值了。

     0:000> !do 00ac2a1c
    Name: System.String
    MethodTable: 5b99452c
    EEClass: 5b9d7f10
    Size: 34(0x22) bytes
    (C:"WINNT"Microsoft.NET"Framework"v2.0.40428"assembly"GAC_32"mscorlib"2.0.3600.0__b77a5c561934e089"mscorlib.dll)
    String: String 1

    0:000> !do 00ac2a40
    Name: System.String
    MethodTable: 5b99452c
    EEClass: 5b9d7f10
    Size: 34(0x22) bytes
    (C:"WINNT"Microsoft.NET"Framework"v2.0.40428"assembly"GAC_32"mscorlib"2.0.3600.0__b77a5c561934e089"mscorlib.dll)
    String: String 2

    0:000> !do 00ac2a64
    Name: System.String
    MethodTable: 5b99452c
    EEClass: 5b9d7f10
    Size: 34(0x22) bytes
    (C:"WINNT"Microsoft.NET"Framework"v2.0.40428"assembly"GAC_32"mscorlib"2.0.3600.0__b77a5c561934e089"mscorlib.dll)
    String: String 3

     如上所示,分别是String 1,String 2,String 3。

     分析完毕,收工!

  • 相关阅读:
    三伏天,华为路由器 AX3 PRO 发热严重,网络断流,改装散热清凉一夏
    MVC扩展(ControllerFactory VS DependencyResolver)
    MVC扩展(Templated Razor Delegates)
    RouteDebugger分析
    MVC扩展(ModelBinder)
    ORACLE 创建多个游标并嵌套循环
    java final初解
    oracle partition by 与 partition by ... order by 分组
    JS实现函数重载2
    使用XslCompiledTransform将XML 转HTML
  • 原文地址:https://www.cnblogs.com/wordmy/p/1397144.html
Copyright © 2020-2023  润新知