Какие полезные вещи я могу сделать с перехватчиками выделения Visual C ++ Debug CRT, кроме обнаружения утечек воспроизводимой памяти? - PullRequest
3 голосов
/ 11 ноября 2010

Библиотека среды отладки Visual C ++ имеет так называемые хуки выделения . Работает так: вы определяете обратный вызов и вызываете _CrtSetAllocHook(), чтобы установить этот обратный вызов. Теперь каждый раз, когда выполняется выделение / освобождение / перераспределение памяти, CRT вызывает этот обратный вызов и передает несколько параметров.

Я успешно использовал ловушку выделения, чтобы найти утечку воспроизводимой памяти - в основном CRT сообщил, что при завершении программы имел место несвободный блок с номером выделения N (N был одинаковым при каждом запуске программы), поэтому Я написал следующее в моем крючке:

int MyAllocHook( int allocType, void* userData, size_t size, int blockType, 
    long requestNumber, const unsigned char* filename, int lineNumber)
{
     if( requestNumber == TheNumberReported ) {
         Sleep( 0 );// a line to put breakpoint on
     }
     return TRUE;
}

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

Какие еще полезные вещи я могу сделать, используя перехватчики выделения?

Ответы [ 3 ]

5 голосов
/ 11 ноября 2010

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

  • Создание структуры данных, в которой вы сопоставляете выделенный указатель с дополнительной информацией
  • В хуке выделения можно запросить текущий стек вызовов (функция StackWalk) и сохранить стек вызовов в структуре данных
  • В ловушке отмены выделения удалите информацию стека вызовов для этого распределения
  • В конце приложения переберите структуру данных и сообщите все стеки вызовов. Это места, где память была выделена, но не освобождена.
4 голосов
/ 13 мая 2011

Значение «requestNumber» не передается функции при освобождении (MS VS 2008).Без этого номера вы не сможете отслеживать свое распределение.Однако вы можете заглянуть в заголовок кучи и извлечь из него это значение:

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

<code>
// This struct is a copy of the heap header used by MS VS 2008.
// This information is prepending each allocated memory object in debug mode.
struct MsVS_CrtMemBlockHeader {
    MsVS_CrtMemBlockHeader * _next;
    MsVS_CrtMemBlockHeader * _prev;
    char * _szFilename;
    int _nLine;
    int _nDataSize;
    int _nBlockUse;
    long _lRequest;
    char _gap[4];
};</p>

<p>int MyAllocHook(..) { // same as in question
    if(nAllocType == _HOOK_FREE) {
        // requestNumber isn't passed on to the Hook on free. 
        // However in the heap header this value is stored.
        size_t headerSize = sizeof(MsVS_CrtMemBlockHeader);
        MsVS_CrtMemBlockHeader* pHead;
        size_t ptr = (size_t) pvData - headerSize;
        pHead = (MsVS_CrtMemBlockHeader*) (ptr);
        long requestNumber = pHead->_lRequest;
        // Do what you like to keep track of this allocation.
    }
}
2 голосов
/ 11 ноября 2010

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

Просто первая мысль, которая приходит мне в голову ...

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