开发者

What useful things can I do with Visual C++ Debug CRT allocation hooks except finding reproduceable memory leaks?

开发者 https://www.devze.com 2023-01-24 19:32 出处:网络
Visual C++ debug runtime library features so-called allocation hooks. Works this way: you define a callback and call _CrtSetAllocHook() to set that callback. Now every time a memory allocation/dealloc

Visual C++ debug runtime library features so-called allocation hooks. Works this way: you define a callback and call _CrtSetAllocHook() to set that callback. Now every time a memory allocation/deallocation/reallocation is done CRT calls that callback and passes a handful of parameters.

I successfully used an allocation hook to find a reproduceable memory leak - basically CRT reported that there was an unfreed block with allocation number N (N was the same on every program run) at program termination and so I wrote the following in my hook:

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;
}

since the leak was reported with the very same allocation number every time I could just put a breakpoint inside the if-statement and wait until it was hit and then inspect the call stack.

Wha开发者_JAVA技巧t other useful things can I do using allocation hooks?


You could also use it to find unreproducible memory leaks:

  • Make a data structure where you map the allocated pointer to additional information
  • In the allocation hook you could query the current call stack (StackWalk function) and store the call stack in the data structure
  • In the de-allocation hook, remove the call stack information for that allocation
  • At the end of your application, loop over the data structure and report all call stacks. These are the places where memory was allocated but not freed.


The value "requestNumber" is not passed on to the function when deallocating (MS VS 2008). Without this number you cannot keep track of your allocation. However, you can peek into the heap header and extract that value from there:

Note: This is compiler dependent and may change without notice/ warning by the compiler.


// 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];
};

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. } }


You could keep record of every allocation request then remove it once the deallocation is invoked, for instance: This could help you tracking memory leak problems that are way much worse than this to track down.

Just the first idea that comes to my mind...

0

精彩评论

暂无评论...
验证码 换一张
取 消