Как отобразить управляемые объекты с определенным значением в одном из полей WinDbg с помощью SOS (или SOSEX)?
Моя проблема такова:
0:000> !DumpHeap -type Microsoft.Internal.ReadLock -stat
------------------------------
Heap 0
total 0 objects
------------------------------
Heap 1
total 0 objects
------------------------------
Heap 2
total 0 objects
------------------------------
Heap 3
total 0 objects
------------------------------
total 0 objects
Statistics:
MT Count TotalSize Class Name
000007fef3d14088 74247 2375904 Microsoft.Internal.ReadLock
Total 74247 objects
Способ, которым я читаю этот вывод, заключается в том, что у меня есть 74 247 экземпляров Microsoft.Internal.ReadLock
в моей куче. Однако некоторые из них, вероятно, еще не собраны.
Я хочу отобразить только те, которые не ожидают сбора.
Например, 0000000080f88e90
- это адрес одного из этих объектов, и это мусор. Я знаю это, потому что:
0:000> !mroot 0000000080f88e90
No root paths were found.
0:000> !refs 0000000080f88e90 -target
Objects referencing 0000000080f88e90 (Microsoft.Internal.ReadLock):
NONE
0:000> !do 0000000080f88e90
Name: Microsoft.Internal.ReadLock
MethodTable: 000007fef3d14088
EEClass: 000007fef3c63410
Size: 32(0x20) bytes
File: C:WindowsMicrosoft.NetassemblyGAC_MSILSystem.ComponentModel.Compositionv4.0_4.0.0.0__b77a5c561934e089System.ComponentModel.Composition.dll
Fields:
MT Field Offset Type VT Attr Value Name
000007fef3d13fb0 400001e 8 ...oft.Internal.Lock 0 instance 0000000080001010 _lock
000007fef0a8c7d8 400001f 10 System.Int32 1 instance 1 _isDisposed
Как можно видеть, и sosex.mroot
, и sosex.refs
указывают на то, что никто не ссылается на него, плюс сброс его полей показывает, что он был удален через IDisposable
, поэтому имеет смысл, что объект является мусором (я знаю, что удаление не означает, что объект является мусором, но это в данном случае).
.foreach
. Что-то вроде этого:
.foreach(entry {!dumpheap -type Microsoft.Internal.ReadLock -short}){.if (???) {.printf "%pn", entry} }
Моя проблема в том, что я понятия не имею, что входит в условие .if
.
Я могу исследовать поле _isDisposed следующим образом:
0:000> dd 0000000080f88e90+10 L1
00000000`80f88ea0 00000001
Но .if
ожидает выражения, и все, что у меня есть-это вывод команды. Если бы я знал, как извлечь информацию из вывода команды и организовать ее в виде выражения, то я мог бы использовать ее как условие .if
и быть хорошим.
.if
? Кроме того, можно ли проанализировать выходные данные команды таким образом, чтобы использовать результат в качестве условия .if
?1 ответ:
У меня не было примера, который использует объекты ReadLock, но я попробовал со строками, и вот мой результат:
.foreach (entry {!dumpheap -short -type Microsoft.Internal.ReadLock}) { .if (poi(${entry}+10) == 1) { .printf "%p\n", ${entry} } }
Я использую poi() для получения данных о размере указателя из адреса. Также обратите внимание, что я использую ${entry} Не entry в обоих, poi() и .printf. Вам тоже может понравиться !сделайте ${вход} внутри .если.
В одной строке для копирования / вставки:
.foreach (entry {!dumpheap -short -type Microsoft.Internal.ReadLock}) {.if (poi(${entry}+10) == 1) {.printf "%p\n", ${entry}}}