If I have a System.Int32 at a known memory address of a 64-bit .Net process dump, how can I reference its data in a condition or expression in windbg? For example:
? poi(000000ba2e4de938) == 0n27
is displaying as 0 instead of 1, even though I know that the value at that address is 27 (dt int 000000ba2e4de938
displays 0n27). It is doing so, because it picks up 32 junk bits after the value I am attempting to access, since poi grabs pointer-sized data.
Is there a way to grab data of a certain size to use within expressions? I have so far only found ways to dump the data, but not use it within expressions or conditions.
Short answer: use dwo(...)
for 32 bits, qwo(...)
for 64 bits and poi(...)
for architecture dependent size.
Long answer:
Let's look at an Int32 with SOS first:
0:014> .symfix
0:014> .reload
0:014> .loadby sos clr
0:006> !name2ee *!System.Int32
Module: 000007feecab1000
Assembly: mscorlib.dll
Token: 00000000020000f0
MethodTable: 000007feed1603d0
EEClass: 000007feecb71810
Name: System.Int32
[...]
0:006> !dumpheap -mt 000007feed1603d0
Address MT Size
00000000028376d8 000007feed1603d0 24
0:006> !do 00000000028376d8
Name: System.Int32
MethodTable: 000007feed1603d0
EEClass: 000007feecb71810
Size: 24(0x18) bytes
File: C:\Windows\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
Fields:
MT Field Offset Type VT Attr Value Name
000007feed1603d0 400055f 8 System.Int32 1 instance 8868 m_value
From that output, you can see that the value (m_value
) of the Int32 is at the address of the object + an offset of 8.
The length of Int32 is 32 bit, so we need the dd
(dump DWORD) to look at the memory:
0:006> dd 00000000028376d8+8 L1
00000000`028376e0 000022a4
Convert that into decimal and it'll be what has been displayed by SOS before:
0:006> ? 22a4
Evaluate expression: 8868 = 00000000`000022a4
To use it in a condition, use dwo
(DWORD size) instead of poi
(pointer size, which is qwo
on 64 bits):
0:006> ? dwo(00000000028376d8+8)
Evaluate expression: 8868 = 00000000`000022a4