2016-10-19 15 views
1

В одном из классов есть много объектов, присутствующих в .NET heap, как обнаружено с помощью следующей команды sos.поиск объектов с размером больше порога

!dumpheap -stat -type MyClass 
Statistics: 
       MT Count TotalSize Class Name 
00007ff8e6253494  1700  164123 MyNameSpace.MyClass 

мне нужно найти экземпляры этих объектов, которые имеют ObjSize больше чем 5 МБ. Я знаю, что могу перечислить objsize всех 1700 экземпляров MyClass, используя следующие.

.foreach (res {!DumpHeap -short -MT 00007ff8e6253494 }) {.if ((!objsize res) > 41943040) {.echo res; !objsize res}} 

С сценарием выше, я не получаю никаких результатов, хотя есть экземпляры объектов больше 5 МБ. Я думаю, что проблема может быть, что выход objsize является следующим

20288 (0x4f40) bytes 

Сво строки, которые делают его более трудным для сравнения с любым порогом. Как я могу заставить этот скрипт отображать только объекты с объективом размером более 5 МБ?

+0

Я удалил свой ответ, так как я не был достаточно осторожен, чтобы опубликовать аналогичное решение для! objsize. –

ответ

1

Создание сложных скриптов в WinDbg довольно подвержено ошибкам. В таких ситуациях я переключаюсь на PyKd, который является расширением WinDbg, которое использует Python.

В дальнейшем, я буду только покрыть недостающую часть в вашей головоломки, что те части, которые не работают:

.if ((!objsize res) > 41943040) {.echo res; !objsize res} 

Вот моя отправная точка:

0:009> !dumpheap -min 2000 
     Address    MT  Size 
00000087c6041fe8 000007f81ea5f058 10158  
00000087d6021018 000007f81ea3f1b8  8736  
00000087d6023658 000007f81ea3f1b8  8192  
00000087d6025658 000007f81ea3f1b8 16352  
00000087d6029638 000007f81ea3f1b8 32672 

Вы можете написать сценарий, как это

from pykd import * 
import re 
import sys 
objsizeStr = dbgCommand("!objsize "+sys.argv[1]) 
number = re.search("= (.*)\(0x", objsizeStr) 
size = int(number.group(1)) 
if size > 10000: 
    print sys.argv[1], size 

и использовать его в своем цикле (без обработки ошибок!):

0:009> .foreach (res {!dumpheap -short -min 2000}) { !py c:\tmp\size.py ${res}} 
00000087c6041fe8 10160 
00000087d6021018 37248 
00000087d6023658 27360 
00000087d6025658 54488 
00000087d6029638 53680 

Обратите внимание, как размер !objsize отличается от !dumpheap. Только для перекрестной проверки:

0:009> !objsize 00000087d6023658 
sizeof(00000087d6023658) = 27360 (0x6ae0) bytes (System.Object[]) 

Смотрите также this answer о том, как улучшить сценарий, используя expr() так что вы можете передать выражения и т.д. То, как я сделал это в настоящее время выводит размер в десятичной системе, но это не явная. Возможно, вы хотите вывести префикс 0n, чтобы он дал понять. !

+0

Хорошая точка. Я включу его, однако, я спрашиваю здесь, как сравнить возвращаемое значение objsize, содержащее размер в десятичном, шестнадцатеричном и единичном (байтах), с порогом. –

+1

@pauldeter: я обновил ответ –

0

также Стив комментируемые dumpeap занимает минимальный и максимальный параметр и с теми, должно быть возможно сделать это изначально

0: 004> DumpHeap тип System.String -stat

Statistics: 
     MT Count TotalSize Class Name 
6588199c  1   12 System.Collectionsxxxxx 
65454aec  1   48 System.Collectionsxxxxx 
65881aa8  1   60 System.Collectionsxxxxx 
6587e388  17   596 System.String[] 
6587d834  168   5300 System.String 
Total 188 objects 
!

0: 004> DumpHeap типа System.String -stat -min 0n64 -max 0n100

Statistics: 
     MT Count TotalSize Class Name 
6587e388  3   212 System.String[] 
6587d834  9   684 System.String 
Total 12 objects 

0: 004>! Система типа DumpHeap.Строка -min 0n64 -max 0n100

Address  MT  Size 
01781280 6587d834  76  
01781354 6587d834  78  
01781478 6587e388  84  
017816d8 6587d834  64  
01781998 6587d834  78  
017819e8 6587d834  70  
01781a30 6587d834  82  
01782974 6587d834  78  
01782a6c 6587d834  90  
01782c7c 6587d834  68  
01783720 6587e388  64  
01783760 6587e388  64  

Statistics: 
     MT Count TotalSize Class Name 
6587e388  3   212 System.String[] 
6587d834  9   684 System.String 
Total 12 objects 

манипулируя макс, мин, мы можем точно настроить на одну или два объекта
пример, где мы имеем 1 объект дополнительно на верхней стороне и 2 объектов дополнительно на нижней стороне
с выхода предшествующего этого (15 объектов против 12 объектов)

0: 004> DumpHeap типа System.String -min 0n62 -max 0n106

Address  MT  Size 
01781280 6587d834  76  
01781354 6587d834  78  
017813e8 6587d834  62  
01781478 6587e388  84  
017816d8 6587d834  64  
01781898 6587d834  106  
01781998 6587d834  78  
017819e8 6587d834  70  
01781a30 6587d834  82  
01782974 6587d834  78  
01782a6c 6587d834  90  
01782c7c 6587d834  68  
01783720 6587e388  64  
01783760 6587e388  64  
01783e4c 6587d834  62  

Statistics: 
     MT Count TotalSize Class Name 
6587e388  3   212 System.String[] 
6587d834  12   914 System.String 
Total 15 objects 

если нужно адрес и размер как по некоторым причинам, всегда можно AWK это

0: "DumpHeap типа System.String -min 0n62 -max 0n106" 004> .shell -ci AWK «{печать $ 1, $ 3}»

Address Size 
01781280 76 
01781354 78 
017813e8 62 
01781478 84 
017816d8 64 
01781898 106 
01781998 78 
017819e8 70 
01781a30 82 
01782974 78 
01782a6c 90 
01782c7c 68 
01783720 64 
01783760 64 
01783e4c 62 
+1

Стив позже удалил свой ответ, потому что dumpheap не предоставляет инклюзивный размер, тогда как на основе вопроса включается размер объекта. – BKS

+0

Я не уверен, буду ли я называть 'awk' * изначально * –

+0

Уверен, что расширение клон awk iirc mex – blabb