检查内存转储中所有实例的字段 [英] inspect field on all instances in memory dump

查看:209
本文介绍了检查内存转储中所有实例的字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个内存转储,我用来解决客户端问题。这是一个.NET(C#)应用程序。我的应用程序的问题是,正在创建太多的特定类的实例。当有类似20的时候,这个类有6300个实例。我想循环遍历所有这些实例,并调用这些实例的名称字段。在WinDbg / SOS中有什么简单的方法吗?



我知道我可以使用dumpheap-type {typename}来查找该类的所有实例,但是我不知道如何扩展他们,并查看我感兴趣的领域。

解决方案

你可以这样做



这是一个简单的例子

 使用系统; 
使用System.Collections.Generic;
使用System.Linq;
命名空间测试
{
类程序
{
静态列表<程序> list = new List< Program>();
int i;
字符串测试;
Foo f
static void Main(string [] args)
{
for(int i = 0; i< 10; i ++)
{
list.Add Program(){i = i,test =Test+ i.ToString(),f = new Foo(i)});
}
Console.Read();
}
}
class Foo
{
int j;
public Foo(int i)
{
j = i;
}
}
}

!dumpheap 有一个简短的选项,只返回对象地址。在这种情况下,我正在调试MT $ 程序是00293858

 !dumpheap -mt 00293858 -short 

这是一个转储所有对象的代码。使用foreach构造的foreach($ obj {!dumpheap -mt 00293858 -short}){!do $ obj} $ obj将被赋予对象的地址。这里是foreach循环的示例输出

 名称:Test.Program 
MethodTable:00293858
EEClass:00291440
大小:20(0x14)bytes
文件:c:\users\\\
srinivasan\documents\visual studio 2010 \Projects\Test\Test\bin\ Debug\Test.exe
字段:
MT字段偏移类型VT Attr值名称
5c2e2978 4000002 c System.Int32 1实例3 i
5c2df9ac 4000003 4 System.String 0实例0217c144 test
00293bfc 4000004 8 Test.Foo 0实例0217c15c f
002938b4 4000001 4 ... t.Program,Test]] 0 static 0217b97c list
名称:Test.Program
MethodTable:00293858
EEClass:00291440
大小:20(0x14)个字节
文件:c:\users\\\
srinivasan\documents\visual studio 2010 \Projects\Test\\ \\Test\bin \\ Debug\Test.exe
字段:
MT字段偏移类型VT Attr值名称
5c2e2978 4000002 c System.Int32 1实例4 i
5c2df9ac 4000003 4 System.String 0实例0217c18c测试
00293bfc 4000004 8 Test.Foo 0实例0217c1a4 f
002938b4 4000001 4 ... t.Program,Test]] 0 static 0217b97c list
/ pre>

现在我们有了这个,下一步是在程序的每个实例中获取字段test,这里是代码执行

  .foreach($ obj {!dumpheap -mt 00293858 -short}){!do poi($ {$ obj} + 0x4)} 

我在foreach中使用 poi 命令循环。从上述结果可以看出,$ code>测试变量在4个偏移量中,这就是使用 poi($ {$ obj} + 0x4)的原因)
这里是从上面的示例输出

  0:004> 。$($ obj {!dumpheap -mt 00293858 -short}){!do poi($ {$ obj} + 0x4)} 
名称:System.String
MethodTable:5c2df9ac
EEClass :5c018bb0
大小:24(0x18)bytes
文件:C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0__b77a5c561934e089\mscorlib .dll
字符串:Test0
字段:
MT字段偏移类型VT Attr值名称
5c2e2978 40000ed 4 System.Int32 1实例5 m_stringLength
5c2e1dc8 40000ee 8系统。 Char 1 instance 54 m_firstChar
5c2df9ac 40000ef 8 System.String 0 shared static Empty
>>域:值002f76c0:02171228<
名称:System.String
MethodTable:5c2df9ac
EEClass:5c018bb0
大小:24(0x18)bytes
文件:C:\Windows\Microsoft.Net \assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
字符串:Test1
字段:
MT字段偏移类型VT Attr值名称
5c2e2978 40000ed 4 System.Int32 1实例5 m_stringLength
5c2e1dc8 40000ee 8 System.Char 1实例54 m_firstChar
5c2df9ac 40000ef 8 System.String 0共享静态空
>>域:值002f76c0:02171228<

这里是获取每个 Foo 实例在程序中

  .foreach($ obj {!dumpheap  - mt 00293858 -short}){!do poi($ {$ obj} + 0x8)} 

Foo在第八个偏移量,这里是对上述输出的样本

 名称:Test.Foo 
MethodTable :00293bfc
EEClass:0029194c
大小:12(0xc)bytes
文件:c:\users\\\
srinivasan\documents\visual studio 2010 \Projects\Test\ Test\bin\Debug\Test.exe
字段:
MT字段偏移类型VT Attr值名称
5c2e2978 4000005 4 System.Int32 1实例0 j
名称: Test.Foo
MethodTable:00293bfc
EEClass:0029194c
大小:12(0xc)bytes
文件:c:\users\\\
srinivasan\documents\visual studio 201 0\Projects\Test\Test\bin\Debug\Test.exe
字段:
MT字段偏移类型VT Attr值名称
5c2e2978 4000005 4 System.Int32 1实例1 j

编辑: - 这里还有一个 post 内容



HTH


I have a memory dump that I'm using to troubleshoot a client issue. This is a .NET (C#) application. The problem with my application is that too many instances of a particular class are being created. There are 6300 instances of this class when there should be something like 20. I want to loop through all of those instances and call the name field of each of those instances. Is there any easy way to do this in WinDbg/SOS?

I know I can use !dumpheap -type {typename} to find all the instances of that class, but I'm not sure how I can expand them all and view the field I am interested in.

解决方案

You can do this with .foreach command within Windbg.

Here is a simple example

using System;
using System.Collections.Generic;
using System.Linq;
namespace Test
{
    class Program
    {
        static List<Program> list = new List<Program>();
        int i;
        string test;
        Foo f;
        static void Main(string[] args)
        {
            for (int i = 0; i < 10; i++)
            {
                list.Add(new Program() { i = i, test = "Test" + i.ToString(), f = new Foo(i) });
            }
            Console.Read();
        }
    }
    class Foo
    {
        int j;
        public Foo(int i)
        {
            j = i;
        }
    }
}

The !dumpheap has a short option which would just return the object address. In the instance i am debugging MT for Program is 00293858

!dumpheap -mt 00293858 -short

Here is a code to dump all the objects .foreach ($obj {!dumpheap -mt 00293858 -short}) {!do $obj} using the foreach construct. The $obj would get assigned with the address of the object. And here is the sample output from the foreach loop

Name:        Test.Program
MethodTable: 00293858
EEClass:     00291440
Size:        20(0x14) bytes
File:        c:\users\nsrinivasan\documents\visual studio 2010\Projects\Test\Test\bin\Debug\Test.exe
Fields:
      MT    Field   Offset                 Type VT     Attr    Value Name
5c2e2978  4000002        c         System.Int32  1 instance        3 i
5c2df9ac  4000003        4        System.String  0 instance 0217c144 test
00293bfc  4000004        8             Test.Foo  0 instance 0217c15c f
002938b4  4000001        4 ...t.Program, Test]]  0   static 0217b97c list
Name:        Test.Program
MethodTable: 00293858
EEClass:     00291440
Size:        20(0x14) bytes
File:        c:\users\nsrinivasan\documents\visual studio 2010\Projects\Test\Test\bin\Debug\Test.exe
Fields:
      MT    Field   Offset                 Type VT     Attr    Value Name
5c2e2978  4000002        c         System.Int32  1 instance        4 i
5c2df9ac  4000003        4        System.String  0 instance 0217c18c test
00293bfc  4000004        8             Test.Foo  0 instance 0217c1a4 f
002938b4  4000001        4 ...t.Program, Test]]  0   static 0217b97c list

Now that we have this , the next step is to get the field "test" within each instance of program and here is the code to do that

 .foreach ($obj {!dumpheap -mt 00293858 -short}) {!do poi(${$obj}+0x4)} 

I am using poi command within the foreach loop. From the above result we can make out the test variable is in the 4 offset and that's the reason for using poi(${$obj}+0x4) And here is the sample output from the above foreach

0:004> .foreach ($obj {!dumpheap -mt 00293858       -short}) {!do poi(${$obj}+0x4)}
Name:        System.String
MethodTable: 5c2df9ac
EEClass:     5c018bb0
Size:        24(0x18) bytes
File:        C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
String:      Test0
Fields:
      MT    Field   Offset                 Type VT     Attr    Value Name
5c2e2978  40000ed        4         System.Int32  1 instance        5 m_stringLength
5c2e1dc8  40000ee        8          System.Char  1 instance       54 m_firstChar
5c2df9ac  40000ef        8        System.String  0   shared   static Empty
    >> Domain:Value  002f76c0:02171228 <<
Name:        System.String
MethodTable: 5c2df9ac
EEClass:     5c018bb0
Size:        24(0x18) bytes
File:        C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
String:      Test1
Fields:
      MT    Field   Offset                 Type VT     Attr    Value Name
5c2e2978  40000ed        4         System.Int32  1 instance        5 m_stringLength
5c2e1dc8  40000ee        8          System.Char  1 instance       54 m_firstChar
5c2df9ac  40000ef        8        System.String  0   shared   static Empty
    >> Domain:Value  002f76c0:02171228 <<

And here is for getting each Foo instance within the Program class

.foreach ($obj {!dumpheap -mt 00293858  -short}) {!do poi(${$obj}+0x8)}

The Foo is in the 8th offset and here is sample the output for the above foreach

Name:        Test.Foo
MethodTable: 00293bfc
EEClass:     0029194c
Size:        12(0xc) bytes
File:        c:\users\nsrinivasan\documents\visual studio 2010\Projects\Test\Test\bin\Debug\Test.exe
Fields:
      MT    Field   Offset                 Type VT     Attr    Value Name
5c2e2978  4000005        4         System.Int32  1 instance        0 j
Name:        Test.Foo
MethodTable: 00293bfc
EEClass:     0029194c
Size:        12(0xc) bytes
File:        c:\users\nsrinivasan\documents\visual studio 2010\Projects\Test\Test\bin\Debug\Test.exe
Fields:
      MT    Field   Offset                 Type VT     Attr    Value Name
5c2e2978  4000005        4         System.Int32  1 instance        1 j

EDIT:- Also here is a post from Tess on dumping session contents

HTH

这篇关于检查内存转储中所有实例的字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆