Отладка утечки памяти с помощью windbg без трассировки пользовательского стека

У меня есть полный дамп памяти, но в этом случае у меня нет базы данных трассировки пользовательского стека, у меня есть обновленные символы и исходные двоичные файлы, которые идут с дампом, как правило, я мог использовать !heap -p -a address для просмотра стека вызовов в момент выделения, но это не будет работать без базы данных трассировки пользовательского стека.

Мой вопрос заключается в том, есть ли другой способ (хотя и менее прямой подход) добраться до источника этой утечки памяти.

        LFH Key                   : 0x0000005c2dc22701
Termination on corruption : ENABLED
          Heap     Flags   Reserv  Commit  Virt   Free  List   UCR  Virt  Lock  Fast 
                            (k)     (k)    (k)     (k) length      blocks cont. heap 
-------------------------------------------------------------------------------------
00000000002e0000 00000002 3125248 3122792 3125248    282   378   197    0      7   LFH
0000000000010000 00008000      64      4     64      1     1     1    0      0      
0000000000530000 00001002    1088    416   1088     51    10     2    0      0   LFH
0000000000490000 00001002     512    284    512      5     5     1    0      0   LFH
0000000000af0000 00001002    1088    248   1088      2     2     2    0      0   LFH
0000000000c00000 00001002      64      8     64      3     1     1    0      0      
0000000000de0000 00001002     512      8    512      3     1     1    0      0      
0000000000ac0000 00001002   31616  30356  31616   1810    42     6    0      0   LFH
00000000012c0000 00001002     512      8    512      2     1     1    0      0      
0000000002140000 00001003     512     88    512     49     7     1    0    N/A   
0000000001ab0000 00001003     512      8    512      5     1     1    0    N/A   
00000000022f0000 00001003     512      8    512      5     1     1    0    N/A   
0000000002490000 00001003     512      8    512      5     1     1    0    N/A   
0000000000d40000 00001003     512      8    512      5     1     1    0    N/A   
0000000002690000 00001003     512      8    512      5     1     1    0    N/A   
0000000002860000 00001003     512      8    512      5     1     1    0    N/A   
0000000002e90000 00001002     512      8    512      2     2     1    0      0      
0000000002e10000 00001002    1536    556   1536     40     6     2    0      0   LFH
0000000001b90000 00011002     512      8    512      3     2     1    0      0      
00000000033e0000 00001002     512      8    512      3     2     1    0      0      
-------------------------------------------------------------------------------------

Как видно из этой сводки кучи (!heap -s), куча 00000000002e0000 стала довольно большой, при ближайшем рассмотрении можно увидеть, что 70% данных размещены в блоках размером 0x4058, 0x23d1 и 0x10d1 (что определенно является своего рода шаблоном). ), так что я уверен, что хочу исследовать это дальше.

heap @ 00000000002e0000
group-by: TOTSIZE max-display: 20
    size     #blocks     total     ( %) (percent of total busy bytes)
    4058 1ea - 7b2870  (39.56)
    23d1 1dc - 42989c  (21.39)
    10d1 1ed - 20627d  (10.40)
    c51 1f4 - 180e34  (7.73)
    307 25b - 7217d  (2.29)
    378 1f9 - 6d7b8  (2.20)
    188 40e - 63570  (1.99)
    c0 59f - 43740  (1.35)
    30 12c7 - 38550  (1.13)
    28 147e - 333b0  (1.03)
    140 22a - 2b480  (0.87)
    138 231 - 2abb8  (0.86)
    2340 11 - 25740  (0.75)
    100 244 - 24400  (0.73)
    120 1ea - 22740  (0.69)
    78 456 - 20850  (0.65)
    1010 12 - 12120  (0.36)
    10188 1 - 10188  (0.32)
    10008 1 - 10008  (0.32)
    4000 4 - 10000  (0.32)

Моя проблема в том, что я не знаю, куда идти отсюда, ранее я следовал инструкциям, найденным здесь с большим успехом, но на этот раз у меня нет базы данных трассировки пользовательского стека, и я не могу легко воспроизвести этот шаблон, но я знаю, что дамп памяти содержит много полезного информация Я просто не уверен, как получить что-то значимое отсюда. Специалисты Windbg? Аналитики дампа памяти? Пожалуйста посоветуй.

Несколько блоков, первые пару байт

0:000> dc 0000000005254b80    
00000000`05254b80  52474d45 00000000 050f1c40 00000000  EMGR....@.......
00000000`05254b90  00000000 00000000 00000001 00000001  ................
00000000`05254ba0  00000400 000003ff 0001d4c0 00000001  ................
00000000`05254bb0  524d4954 00000000 051fcd10 00000000  TIMR............
00000000`05254bc0  f7b315d0 000007fe 05254b80 00000000  .........K%.....
00000000`05254bd0  00000000 00000000 05254bd8 00000000  .........K%.....
00000000`05254be0  05254bd8 00000000 05254be8 00000000  .K%......K%.....
00000000`05254bf0  05254be8 00000000 05254bf8 00000000  .K%......K%.....
0:000> dc 00000000051ce640    
00000000`051ce640  52474d45 00000000 04f1ab00 00000000  EMGR............
00000000`051ce650  00000000 00000000 00000001 00000001  ................
00000000`051ce660  00000400 000003ff 0001d4c0 00000001  ................
00000000`051ce670  524d4954 00000000 05037070 00000000  TIMR....pp......
00000000`051ce680  f7b315d0 000007fe 051ce640 00000000  ........@.......
00000000`051ce690  00000000 00000000 051ce698 00000000  ................
00000000`051ce6a0  051ce698 00000000 051ce6a8 00000000  ................
00000000`051ce6b0  051ce6a8 00000000 051ce6b8 00000000  ................
0:000> dc 0000000004fdb1f0    
00000000`04fdb1f0  52474d45 00000000 04f1b570 00000000  EMGR....p.......
00000000`04fdb200  00000000 00000000 00000001 00000001  ................
00000000`04fdb210  00000400 000003ff 0001d4c0 00000001  ................
00000000`04fdb220  524d4954 00000000 04ed6ba0 00000000  TIMR.....k......
00000000`04fdb230  f7b315d0 000007fe 04fdb1f0 00000000  ................
00000000`04fdb240  00000000 00000000 04fdb248 00000000  ........H.......
00000000`04fdb250  04fdb248 00000000 04fdb258 00000000  H.......X.......
00000000`04fdb260  04fdb258 00000000 04fdb268 00000000  X.......h.......
0:000> dc 0000000001e649b0    
00000000`01e649b0  52474d45 00000000 00351270 00000000  EMGR....p.5.....
00000000`01e649c0  00000000 00000000 00000001 00000001  ................
00000000`01e649d0  00000400 000003ff 0001d4c0 00000001  ................
00000000`01e649e0  524d4954 00000000 01e64130 00000000  TIMR....0A......
00000000`01e649f0  f7b315d0 000007fe 01e649b0 00000000  .........I......
00000000`01e64a00  00000000 00000000 01e64a08 00000000  .........J......
00000000`01e64a10  01e64a08 00000000 01e64a18 00000000  .J.......J......
00000000`01e64a20  01e64a18 00000000 01e64a28 00000000  .J......(J......

person John Leidegren    schedule 11.09.2013    source источник
comment
В этом случае подходящим подходом является правило отладки диагностики утечки памяти, iis.net/learn/troubleshoot/performance-issues/   -  person Lex Li    schedule 11.09.2013
comment
Ожидание такого длительного времени для создания минидампа гарантирует, что вы полностью утонете в данных.   -  person Hans Passant    schedule 11.09.2013
comment
@HansPassant Не уверен, что это направлено на Лекса или на меня, но обстоятельства, связанные со свалкой, - это не то, с чем я могу позволить себе роскошь что-либо делать, я просто пытаюсь определить, насколько серьезна эта проблема, если вообще серьезна. Насколько мне известно, это может быть единичный случай.   -  person John Leidegren    schedule 11.09.2013


Ответы (1)


Используйте !heap -flt s для размера (ов) нарушения (с записью в файл)

Затем вручную сбросьте содержимое на некоторые из них и попытайтесь угадать, какие данные они содержат. Если вам повезет, это объекты C++ с адресом vtable в первом DWORD, что делает их «легко» распознаваемыми. Если нет, используйте команды dc , dds и попытайтесь выяснить, что это за содержимое.

Другой подход состоит в том, чтобы найти типы, которые имеют размер, соответствующий тем, которые, как вы подозреваете, имеют утечку.

============================Find symbols of spesific size===================================
0:011> dt -v -s a4 <MyDll>!*
Enumerating symbols matching <MyDll>!*, Size = 0xa4
Address   Size Symbol
           0a4 <MyDll>!NMDATETIMEFORMATW
           0a4 <MyDll>!CWinApp
           0a4 <MyDll>!CWinApp
==> Check all modules
!for_each_module ".echo @#ModuleName;dt -v -s a4  ${@#ModuleName}!*"

Вы также можете попытаться найти блоки кучи, в которых есть указатель на подозреваемого в утечке.

0:008> !heap -srch 09C07058
_HEAP @ 02C90000
in HEAP_ENTRY: Size : Prev Flags - UserPtr UserSize - state
    0B7DA920: 002c : 002c [01] - 0B7DA928 (00000158) - (busy)
      diasymreader!Mod1::`vftable'
person Kjell Gunnar    schedule 11.09.2013
comment
Я попытался сбросить некоторые из больших блоков, нашел некоторые закономерности, не знаю данных, вы узнаете что-нибудь из них? - person John Leidegren; 11.09.2013
comment
попробуйте: ln 00000000`52474d45 - person Kjell Gunnar; 11.09.2013
comment
Поскольку ваши блоки начинаются с одного и того же 64-битного указателя, проверьте это. Команда ln выведет список ближайших символов. попробуйте: ln 00000000`05254b80 - person Kjell Gunnar; 11.09.2013
comment
Ничего не происходит :( Я трижды проверил, что символы успешно загружены. - person John Leidegren; 11.09.2013
comment
Как насчет: !address 00000000`05254b80 Он покажет, является ли это указателем на другой блок кучи. Однако я думаю, что у вас здесь сложный случай! - person Kjell Gunnar; 11.09.2013
comment
Это указатель на адрес в той же куче. Интересно то, что в этих блоках есть действительно уникальные магические числа, но я понятия не имею, откуда они берутся. EMGR и TIMR должны что-то для кого-то означать... также не может быть совпадением, что они выровнены, ровно 48 байт. - person John Leidegren; 11.09.2013
comment
Хм... Я проверяю блоки, следующие за самыми большими, и теперь я вижу следующее, winhttp!HTTP_USER_REQUEST::`vftable', 0000000003e70530 0241 0241 [00] 0000000003e70540 023d1 - (busy), многие из них тоже, это может быть связано с моим клиентским кодом WinHttp... - person John Leidegren; 11.09.2013
comment
Я отследил проблему. В паре интерфейсов отсутствовали виртуальные деконструкторы, из-за чего они удерживали дескрипторы winhttp на неопределенный срок. - person John Leidegren; 20.09.2013
comment
Как определить, какие блоки кучи самые большие? Из вопроса ОП зарезервированный размер составляет около 3 ГБ (!). Но сумма «общего» столбца вывода !heap -stat составляет всего около 16 МБ. Где все остальные блоки, которые потребляют все остальное? - person mistika; 15.12.2015