noc*_*ura 1 .net debugging windbg sos
假设我正在 WinDbg 中查找托管 exe 的 dmp。Sos 已加载。我有 30 个 Car 类型的对象的地址。汽车“have-a”发动机其中“have-a”序列号。有没有一种简单的方法来编写/编写一个函数,例如:
long GetSerialNumber(Car car)
{
return car.Engine.SerialNumber;
}
Run Code Online (Sandbox Code Playgroud)
现在我只是单独浏览每个对象,感觉非常低效!
0:004> .loadby sos clr
0:004> !dumpheap -stat -type Car
Statistics:
MT Count TotalSize Class Name
001c4e08 1 24 System.Collections.Generic.List`1[[DebugCarsSerialNumber.Car, DebugCarsSerialNumber]]
001c51fc 5 300 DebugCarsSerialNumber.Car[]
001c52ec 30 360 DebugCarsSerialNumber.Engine
001c4db8 30 360 DebugCarsSerialNumber.Car
Total 66 objects
0:004> !do 02213228
Name: DebugCarsSerialNumber.Car
MethodTable: 001c4db8
EEClass: 001c1820
Size: 12(0xc) bytes
File: C:\Users\For example John\Documents\Visual Studio 2015\Projects\DebugCarsSerialNumber\DebugCarsSerialNumber\bin\Debug\DebugCarsSerialNumber.exe
Fields:
MT Field Offset Type VT Attr Value Name
001c52ec 4000001 4 ...rialNumber.Engine 0 instance 02213234 Engine
Run Code Online (Sandbox Code Playgroud)
所以在我的例子中,一辆汽车的发动机在偏移量 4 处。 有了poi()指针大小的数据,让我们将它应用到汽车上:
0:004> !do poi(02213228+4)
Name: DebugCarsSerialNumber.Engine
MethodTable: 001c52ec
EEClass: 001c19b4
Size: 12(0xc) bytes
File: C:\Users\For example John\Documents\Visual Studio 2015\Projects\DebugCarsSerialNumber\DebugCarsSerialNumber\bin\Debug\DebugCarsSerialNumber.exe
Fields:
MT Field Offset Type VT Attr Value Name
71ce1638 4000003 4 System.Int32 1 instance 213550972 SerialNumber
71cf10f0 4000002 4 System.Random 0 static 02213240 rnd
Run Code Online (Sandbox Code Playgroud)
发动机的序列号也位于偏移量 4 处。您将再次使用poi()and!do对象,但由于序列号是原始的,请dp L1在此处使用:
0:004> dp poi(02213228+4)+4 L1
02213238 0cba877c
0:004> ? 0cba877c
Evaluate expression: 213550972 = 0cba877c
Run Code Online (Sandbox Code Playgroud)
等等:序列号。
既然您知道如何为一辆车执行此操作,让我们遍历所有汽车:
0:004> .foreach (addr {!dumpheap -short -mt 001c4db8}) {dp poi(${addr}+4)+4 L1}
02213238 0cba877c
0221336c 215ac5aa
02213384 28c17829
[...]
Run Code Online (Sandbox Code Playgroud)
如果您想要没有地址,请使用.printf:
0:004> .foreach (addr {!dumpheap -short -mt 001c4db8}) {.printf "%N\n", dwo(poi(${addr}+4)+4)}
0CBA877C
215AC5AA
28C17829
[...]
Run Code Online (Sandbox Code Playgroud)
或十进制:
0:004> .foreach (addr {!dumpheap -short -mt 001c4db8}) {.printf "%i\n", dwo(poi(${addr}+4)+4)}
213550972
559596970
683767849
[...]
Run Code Online (Sandbox Code Playgroud)
既然您知道如何手动执行此操作,请使用NetExt的简单快捷方式:
0:004> .load c:\debug\exts\NetExt.dll
NetExt version 2.0.1.5580 Aug 3 2015
License and usage can be seen here: !whelp license
Check Latest version: !wupdate
For help, type !whelp (or in WinDBG run: '.browse !whelp')
Questions and Feedback: http://netext.codeplex.com/discussions
Copyright (c) 2014-2015 Rodney Viana (http://blogs.msdn.com/b/rodneyviana)
Type: !windex -tree or ~*e!wstack to get started
0:004> !windex
Starting indexing at 21:24:48
Indexing finished at 21:24:48
36,204 Bytes in 486 Objects
Index took 00:00:00
0:004> !wfrom -type *.Car select Engine.SerialNumber
Engine.SerialNumber: 0n213550972
Engine.SerialNumber: 0n559596970
Engine.SerialNumber: 0n683767849
Run Code Online (Sandbox Code Playgroud)
SOSEX '!mdt命令也可以按名称访问字段。结合 WinDbg 循环,您将得到:
0:000> .foreach (addr {!dumpheap -short -mt 00144db8}) {!mdt -e:2 ${addr}.Engine.SerialNumber}
025e3238 (System.Int32)
m_value:0x2d17efdf (System.Int32)
025e336c (System.Int32)
m_value:0x45022ea6 (System.Int32)
025e3384 (System.Int32)
m_value:0x346c6237 (System.Int32)
025e339c (System.Int32)
[...]
Run Code Online (Sandbox Code Playgroud)
(这些值是在新的调试会话中收到的,这就是值不同的原因)