Как отобразить управляемые объекты с определенным значением в одном из полей 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}}}