Please enable JavaScript to view this site.

Memory Validator Help

Navigation: Native API

Callbacks for Leaks & Uninitialized Data

Scroll Prev Top Next More

 

API Function callbacks for leaks and uninitialized data

 

The API leak detection callback facility can call a function in your application if one of the following happens:

 

each time a leak is found before the program ends.
 

a leak is detected for an allocation made after or between specified watermarks
 

uninitialized memory is detected in the C runtime heap

 

You can setup each callback with an item of user data which will be passed back into the callback.

 

 

mvLeakDetect()

 

A specified callback in your program is called for each item of leaked memory.

 

Usually leaks are detected by monitoring the entire program execution, and are viewed once the target program ends.

 

Data not deallocated by the time the program ends is deemed to have been leaked, unless it is pointed to by a pointer in static memory, when it is regarded as 'potentially in use'.

 

note Use with caution. This function is not very efficient and can take a long time to execute if there are lots of allocations. However, it's useful if you really need to know about leaked items before the program has ended.

 

extern "C" 
int mvLeakDetect(API_LEAK_CALLBACK callback,  // The callback to call when leaked memory is found
                 void*             userData,  // User data you want to pass back into the callback

                 DWORD             flags);    // Flags used to control what memory is searched when checking for memory leaks

 

The callback needs to have the form:

 

void leakCallback(API_MEMORY_INFO *data,      // Information about the leaked memory. If NULL, the leaked memory detection is complete
                  void            *userData); // The value you supplied to mvLeakDetect()

 

The following values are available as flags that can be passed to mvLeakDetect(). These flags can be combined using the OR operator. These flags are defined in the allEnum.h header file.

 

LEAK_DETECT_NONE        0x00000000   // No leak detects are performed
 
LEAK_DETECT_CPP         0x00000001   // Scan CRT debug heap
LEAK_DETECT_C           0x00000002   // Scan C heap (see heapwalk())
LEAK_DETECT_WIN32_HEAPS 0x00000004   // Scan Win32 heaps (see HeapWalk())
LEAK_DETECT_GLOBAL      0x00000008   // Scan non-dynamic memory in DLLs (variables in non-stack memory that are not dynamically allocated)
LEAK_DETECT_STACK       0x00000010   // Scan the stack space of the current thread
LEAK_DETECT_ALL_STACKS  0x00000020   // Not implemented
LEAK_DETECT_ALL_TLS     0x00000040   // Not implemented

 

LEAK_DETECT_ALL_HEAPS          (LEAK_DETECT_CPP | LEAK_DETECT_C | LEAK_DETECT_WIN32_HEAPS)
LEAK_DETECT_ALL_EXCEPT_STACK   (LEAK_DETECT_CPP | LEAK_DETECT_C | LEAK_DETECT_WIN32_HEAPS | LEAK_DETECT_GLOBAL)
LEAK_DETECT_ALL                (LEAK_DETECT_CPP | LEAK_DETECT_C | LEAK_DETECT_WIN32_HEAPS | LEAK_DETECT_GLOBAL | LEAK_DETECT_STACK)

 

We recommend using the flag value LEAK_DETECT_ALL_EXCEPT_STACK.
 
We don't recommend scanning the stack space of the current thread for references to pointers in local variables. The reasons we don't recommend LEAK_DETECT_STACK are:

Identifying just the stack space used for local variables is slow. This is a serious performance overhead.

We can't identify the stack space used for local variables for any functions that don't have full debug information. This means any Microsoft code and any third party code (shell extensions etc).

Scanning all the stack space means we're scanning workspace that was previous used but is now just workspace for any functions on the stack. This space can contain old values from previous function calls leading to FALSE positive identifications of pointers which would be incorrectly reported as found (not leaked).

 

 

mvLeakDetectFromWatermark()

 

Here you specify a watermark, for which a callback is only called for leaks detected for memory allocated after the watermark was created.

 

The watermark can be created via the API using mvSetWatermark or interactively by the user.

 

extern "C" 
int mvLeakDetectFromWatermark(const TCHAR*           watermarkName, // The name of the watermark
                              API_WATERMARK_CALLBACK callback,      // The callback to call when leaked memory is found
                              void*                  userData);     // User data you want to pass back into the callback

 

The callback has the form:

 

void leakCallback(DWORD address,    // Address of the leaked memory
                  void  *userData); // The value you supplied to mvLeakDetectFromWatermark()

 

 

mvLeakDetectBetweenWatermarks()

 

Similar to mvLeakDetectFromWatermark, but the callback is only made for leaks where the memory allocation is between two named watermarks.

 
extern "C" 
int mvLeakDetectBetweenWatermarks(const TCHAR*           firstWatermarkName, // The name of the first watermark
                                  const TCHAR*           lastWatermarkName,  // The second watermark
                                  API_WATERMARK_CALLBACK callback,           // The callback to call when leaked memory is found
                                  void*                  userData);          // User data you want to pass back into the callback

 

The callback has the same form as mvLeakDetectFromWatermark above.

 

 

mvDetectUninitialised()

 

Sets a callback to be called once per item of data if uninitialized data is detected in the C runtime heap.

 

extern "C" 
int mvDetectUninitialised(API_UNINITIALISED_CALLBACK callback,  // The callback to call when uninitialized data is found
                          void*                      userData); // User data you want to pass back into the callback

 

The callback needs to have the same form as used with mvLeakDetect:

 

void leakCallback(API_MEMORY_INFO *data,      // Information about the uninitialized memory. If NULL, uninitialized data detection is complete
                  void            *userData); // The value you supplied to mvLeakDetect()