Bạn có thể làm điều này với lệnh .foreach
trong Windbg.
Đây là một ví dụ đơn giản
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;
}
}
}
Các !dumpheap
có một lựa chọn ngắn mà sẽ chỉ trả về địa chỉ đối tượng. Trong trường hợp tôi đang gỡ lỗi MT cho Program
là 00293858
!dumpheap -mt 00293858 -short
Đây là một mã số để đổ tất cả các đối tượng .foreach ($obj {!dumpheap -mt 00293858 -short}) {!do $obj}
bằng cách sử dụng cấu trúc foreach. $ Obj sẽ được gán với địa chỉ của đối tượng. Và đây là sản phẩm mẫu từ vòng lặp foreach
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
Bây giờ chúng ta đã này, bước tiếp theo là để có được những lĩnh vực "test" trong mỗi thể hiện của chương trình và đây là đoạn code để làm điều đó
.foreach ($obj {!dumpheap -mt 00293858 -short}) {!do poi(${$obj}+0x4)}
Tôi đang sử dụng lệnh poi
trong vòng lặp foreach. Từ kết quả trên chúng ta có thể tạo ra sự biến test
là trong 4 bù đắp và đó là lý do cho việc sử dụng poi(${$obj}+0x4)
Và đây là sản phẩm mẫu từ foreach trên
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 <<
Và đây là để nhận mỗi Foo
thẩm trong thời hạn lớp Program
.foreach ($obj {!dumpheap -mt 00293858 -short}) {!do poi(${$obj}+0x8)}
các Foo là trong 8 bù đắp và đây là mẫu đầu ra cho các foreach trên
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: - Còn đây là một post từ Tess về bán phá giá nội dung phiên
HTH
này là hoàn hảo !! Cảm ơn câu trả lời tuyệt vời. Bây giờ vào vấn đề thực sự của sửa chữa ứng dụng của tôi :) – Bryan
Vâng, tôi tìm thấy bài viết của Tess sau khi tôi hỏi câu hỏi. – Bryan
giải thích tuyệt vời! Cảm ơn bạn cho các chi tiết :) –