windbg диагностирует утечки в 64-битных дампах -! куча не показывает рост памяти - PullRequest
0 голосов
/ 05 ноября 2018

Я пытаюсь отладить утечку памяти в 64-битном собственном приложении C ++. Приложение пропускает 1300 байт 7-10 раз в секунду - через обычный malloc ().

Если я присоединяюсь к процессу с помощью WinDBG и перерываюсь на него каждые 60 секунд,! Heap не показывает никакого увеличения выделенной памяти.

Я включил базу данных трассировки стека режима пользователя в процессе:

gflags /i <process>.exe +ust

В WinDBG (со всеми успешно загруженными символами) я использую:

!heap -stat -h

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

Я понимаю, что когда выделения малы, они идут в HeapAlloc (), когда они больше, они идут в VirtualAlloc. Не работает ли куча для HeapAlloc?

Эта запись , кажется, подразумевает, что, возможно, использование DebugDiag сработает, но все же сводится к использованию команд WinDBG для обработки дампа. Пытался безрезультатно.

Эта запись также говорит, что!! Heap команда не работает для 64-битных приложений. Может ли это быть так?

Существует ли альтернативная процедура диагностики утечек в 64-битных приложениях?

1 Ответ

0 голосов
/ 06 ноября 2018

! Heap не показывает увеличения выделенной памяти.

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

например. Вполне возможно, что ваше приложение имеет кучу 100 МБ, из которых только некоторые блоки по 64 КБ перемещаются из столбца «зарезервировано» в столбец «зафиксировано». Если память выделяется с самого начала, вы ничего не увидите с простой командой !heap.

Я включил базу данных трассировки стека режима пользователя в процессе

Это поможет вам получить трассировку стека выделения, но не повлияет на утечку в целом.

Я понимаю, что когда выделения малы, они идут в HeapAlloc (), когда они больше, они идут в VirtualAlloc.

Да, для ассигнований> 512k .

Не работает ли куча для HeapAlloc?

Должен. И поскольку C ++ malloc() и new оба используют диспетчер кучи Windows, они должны рано или поздно привести к HeapAlloc().

следующий код

#include <iostream>
#include <chrono>
#include <thread>

int main()
{
    // /10409151/windbg-diagnostiruet-utechki-v-64-bitnyh-dampah-kucha-ne-pokazyvaet-rost-pamyati
    //
    // I am trying to debug a memory leak in a 64-bit C++ native application.
    // The app leaks 1300 bytes 7-10 times a second - via plain malloc().

    for(int seconds=0; seconds < 60; seconds++)
    {
        for (int leakspersecond=0; leakspersecond<8;leakspersecond++)
        {
            if (malloc(1300)==nullptr)
            {
                std::cout << "Out of memory. That was unexpected in this simple demo." << std::endl;
            }
            std::this_thread::sleep_for(std::chrono::milliseconds(125));
        }
    }
}

скомпилировано как сборка 64-битного выпуска и запущено в WinDbg 10.0.15063.400 x64 показывает

0:001> !heap -stat -h

Allocations statistics for
 heap @ 00000000000d0000
group-by: TOTSIZE max-display: 20
    size     #blocks     total     ( %) (percent of total busy bytes)
    514 1a - 8408  (32.24)
    521 c - 3d8c  (15.03)
[...]

и позже

0:001> !heap -stat -h

Allocations statistics for
 heap @ 00000000000d0000
group-by: TOTSIZE max-display: 20
    size     #blocks     total     ( %) (percent of total busy bytes)
    514 30 - f3c0  (41.83)
    521 18 - 7b18  (21.12)

даже без +ust набора.

Это 4,5 миллиона строк кода.

Откуда вы тогда знаете, что он пропускает 1300 байт через обычную функцию malloc ()?

...