Справочная информация:
Иногда я получаю утечки в моих программах MFC dApp , находящихся в стадии разработки.MFC красиво выводит обнаруженные блоки утечки на панель вывода в Visual Studio, показывая их {номер блока} и шестнадцатеричный адрес.Некоторые утечки не имеют путей к исходным файлам и номеров строк, кроме fx strcore.cpp и т. Д. Эти источники утечек трудно найти и нуждаются в лучшем решении.
Изучая WinDbg Preview с его отладкой во времени (TTD), я могу понять, как это будет правильным инструментом для быстрого поиска утечек MFC.
Тест поиска утечек:
Я создал небольшую программу MFC и добавил в нее утечку:
void LeakInThread()
{
int* intLeak = new int[ 500 ];
}
wchar* leak = new wchar[ 100 ];
std::thread t1( LeakInThread ); // added leak in thread
t1.join();
Программа произвела: {274698} normal block at 0x000001AFA34D9790, 200 bytes long.
Используя WinDbg, я создал файл трассировки, время, пройденное доконец, чтобы убедиться, что утечка была создана, и использовал WinDbg commnd !heap -i x000001AFA34D9790
, чтобы найти блок TTD, где произошла ошибка.Вот вывод:
0:000> !heap -i 0x00000180F42E3790
Detailed information for block entry 00000180f42e3790
Assumed heap : 0x0000000000000000 (Use !heap -i NewHeapHandle to change)
Header content : 0xCDCDCDCD 0xCDCDCDCD
Block flags : 0x1 LFH (busy )
Total block size : 0x0 units (0x0 bytes)
Requested size : 0xffffec00 bytes (unused 0x1400 bytes)
Subsegment : 0x25dac2f1e46abc2eUser blocks not available
Вопрос: Существуют ли команды WinDbg, которые показывают мне файл и номер строки в исходной панели WinDbg?
Edit1:
Экспериментировал с этой командой запроса:
dx -g @$MemRes = @$cursession.TTD.Resources.HeapMemory
и получил:
======================================================================================================================================
= = ResourceId = ResourceIdNew = Size = Function = ThreadId = UniqueThreadId = Position =
======================================================================================================================================
= [0x0] - 0x180f4282870 - 0x0 - 0x4c - ntdll!RtlAllocateHeap - 0x59e4 - 0x2 - C819:58 =
= [0x1] - 0x180f42b79d0 - 0x0 - 0x48 - ntdll!RtlAllocateHeap - 0x59e4 - 0x2 - 5545:62 =
= [0x2] - 0x180f4282870 - 0x0 - 0x0 - ntdll!RtlFreeHeap - 0x59e4 - 0x2 - C827:13F =
= [0x3] - 0x180f42b32a0 - 0x0 - 0x6a - ntdll!RtlAllocateHeap - 0x59e4 - 0x2 - 2E1C:58 =
= [0x4] - 0x180f744d330 - 0x0 - 0x24 - ntdll!RtlAllocateHeap - 0x59e4 - 0x2 - 9609:4C =
= [0x5] - 0x180f74572e0 - 0x0 - 0x48 - ntdll!RtlAllocateHeap - 0x59e4 - 0x2 - 960C:20D =
= [0x6] - 0x180f42b32a0 - 0x0 - 0x0 - ntdll!RtlFreeHeap - 0x59e4 - 0x2 - 2E23:147 =
= [0x7] - 0x180f42c1990 - 0x0 - 0x6a - ntdll!RtlAllocateHeap - 0x59e4 - 0x2 - FB23:58 =
= [0x8] - 0x180f42d9fd0 - 0x0 - 0x0 - ntdll!RtlFreeHeap - 0x59e4 - 0x2 - 12D1B:13F =
= [0x9] - 0x180f42c1990 - 0x0 - 0x0 - ntdll!RtlFreeHeap - 0x59e4 - 0x2 - FB2A:147 =
= [0xa] - 0x180f7453160 - 0x0 - 0x30 - ntdll!RtlAllocateHeap - 0x59e4 - 0x2 - 9625:4C =
= [0xb] - 0x180f42c0810 - 0x0 - 0x6a - ntdll!RtlAllocateHeap - 0x59e4 - 0x2 - FB2E:58 =
= [0xc] - 0x180f42b9160 - 0x0 - 0x0 - ntdll!RtlFreeHeap - 0x59e4 - 0x2 - 2E25:4B =
= [0xd] - 0x180f42e9bd0 - 0x0 - 0x0 - ntdll!RtlFreeHeap - 0x59e4 - 0x2 - 15481:13F =
= [0xe] - 0x180f42d9fd0 - 0x0 - 0x4c - ntdll!RtlAllocateHeap - 0x59e4 - 0x2 - 12D0D:58 =
= [...]
С ResourceID
выглядит как выходной адрес MFC, я сузил вывод с помощью этого запроса выбора:
dx -g @$MemRes.Where(x => x.ResourceId == 0x00000180F42E3790)
, но сетка вывода не имеет результатов.
Edit2:
"Если утечка произошла в потоке MainFrame, также отображаются исходный файл и номер строки. Нет, если утечка произошла в другом порожденном потоке."неправда.Но происходят утечки, которые не указывают на их источник и номера строк.Все еще существует вероятность того, что в программе отладчика MFC отсутствует какой-либо исходный путь, позволяющий найти исходный код.Требуются дополнительные исследования.
Edit3:
При дальнейшем рассмотрении утечки, вызванные моей программой MFC, даже без нажатия клавиш после запуска, имеют разные адреса данных каждыйВремя бежит.(Утечки были введены много раз назад, незаметно до сих пор).Это означает, что я не могу использовать команду WinDbg TTD dx ...
для итерации по кадрам трассировки, сравнивая адреса данных с кадром LocalVariables
Values
просто потому, что адреса данных утечек будут отличаться при каждом запуске программы, в том числе когдаТрассировка записывается.Но, тем не менее, команды могут использоваться для определения того, будет ли выделение кучи незавершенным при закрытии программы.