Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making sense of UMDH compare output

Background

I have set up a testing harness to test a set of functions from a DLL I am developing for a project.

I want to verify that the functions have zero memory leaks on a windows system.

I have properly set up UMDH and I am able to get a compare file between two Heap dumps. Even the stack traces are showing up fine.

Problem

The output from the diff puzzles me and I was hoping someone could help explain why I am getting the output I am getting.

The Output from the compare log:

+      56 (     56 -      0)      1 allocs  BackTrace9C160
+       1 (      1 -      0)    BackTrace9C160  allocations

I set up the log1 and log2 to be 1 integer allocation apart, just to verify my setup.

Indeed, it only shows 1 allocation, however, it is saying that there is a 56 byte change from the before and after. I would only expect sizeof(int) change in bytes. On my system, the sizeof an int allocation is 4 bytes, so I was expecting to see a +4, not a +56.

Again, the only line of code being ran in between the logs is

new int; //purposely leak memory

Any explanations?

Additional Info:

IDE/compiler: Visual Studio 2010

Application is 64 bit

A DLL is involved (but I did not even call to it in this simple int allocation example)

If I comment out the leak, I get zero allocations and +0 bytes. So I think that verifies that no extra bytes are coming from anywhere else in the application, simply from that 1 line shown above...

Solution

Please see SleuthEye's solution below. Also here is a comment I added as a comment to the solution that I believe is beneficial to people who end up using this question:

Additionally, if you run this program on a release build of your .exe and also include the program debug database in the running directory, umdh will pull the source file names and the line numbers of the memory leaks while maintaining an accurate byte count. This gives you the benefits of the debug and release builds as far as memory leak searching goes.

like image 304
Dean Knight Avatar asked Nov 11 '14 14:11

Dean Knight


People also ask

What is a user-mode memory leak?

UMDH locates which routine in a specific process is leaking memory. UMDH is included in Debugging Tools for Windows.

What is Umdh?

The User-Mode Dump Heap (UMDH) tool, Umdh.exe, analyzes the Microsoft Windows heap memory allocations for a given process. UMDH has the following modes. Analyze a running process ("Mode 1"). UMDH captures and analyzes the heap memory allocations for a process.

Where is Umdh EXE?

UMDH.exe is also installed by the Microsoft Windbg tool setup. Please open 2 elevated command prompts and navigate one to the install location of the UDMH.exe(default is C:\Program Files (x86)\Windows Kits\8.0\Debuggers\x64) and the other command prompt to Userdump.exe(default is C:\kktools\userdump8. 1\x64).


2 Answers

The 56 bytes result from the additional memory allocated by the C run-time library (CRT) when using the debug heap, as described on MSDN.

Looking at dbbint.h, where the _CrtMemBlockHeader structure is defined as:

#define nNoMansLandSize 4

typedef struct _CrtMemBlockHeader
{
        struct _CrtMemBlockHeader * pBlockHeaderNext;
        struct _CrtMemBlockHeader * pBlockHeaderPrev;
        char *                      szFileName;
        int                         nLine;
#ifdef _WIN64
        /* These items are reversed on Win64 to eliminate gaps in the struct
         * and ensure that sizeof(struct)%16 == 0, so 16-byte alignment is
         * maintained in the debug heap.
         */
        int                         nBlockUse;
        size_t                      nDataSize;
#else  /* _WIN64 */
        size_t                      nDataSize;
        int                         nBlockUse;
#endif  /* _WIN64 */
        long                        lRequest;
        unsigned char               gap[nNoMansLandSize];
        /* followed by:
         *  unsigned char           data[nDataSize];
         *  unsigned char           anotherGap[nNoMansLandSize];
         */
} _CrtMemBlockHeader;

which would be followed by the memory allocated for your int and further followed by an additional 4 bytes "NoMansLand" buffer. So, for a 64 bit application the total allocated memory for your test case of a single int comes up to sizeof(_CrtMemBlockHeader)+sizeof(int)+4 = 48+4+4 = 56.

Note that the same analysis ran on a release build (where the _CrtMemBlockHeader is not allocated) produces the following compare log output:

+       4 (      4 -      0)      1 allocs  BackTrace2
+       1 (      1 -      0)    BackTrace2  allocations
like image 83
SleuthEye Avatar answered Sep 29 '22 07:09

SleuthEye


You can read the compare output easily with UMDH Diff Viz tool.

screen shot

like image 42
Hyunjik Bae Avatar answered Sep 29 '22 08:09

Hyunjik Bae