Nov 212013
 

Update (2017-04-02):
I have continued development of Heapy on GitHub.
The command line usage has been tweaked. Please see the github for more up to date usage docs.
This post remains the best/only documentation of Heapys inner workings which remain the same – but the code is now slightly out of date.

I’ve created a simple but hopefully effective heap profiler for windows C/C++ applications called Heapy.

Heapy requires no modifications to the program to be profiled. With a very quick setup it can profile 32 or 64 bit windows C/C++ applications. Heapy will list the top allocation sites of your application every few seconds – helping you track down memory leaks and giving you a better insight into what parts of you program are using memory.

Click here to download Heapy.

The readme in that zip should contain enough to get you started – there’s more information on the Github Page and in the rest of this blog post.

If you want to build Heapy yourself you just need to clone it on GitHub and build with Visual Studio 2012 (the express edition should work.)

Example

If we compile the following test application:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// Code for TestApplication.exe
 
#include <windows .h>
#include <iostream>
 
void LeakyFunction(){
    malloc(1024*1024*5); // leak 5Mb
}
 
void NonLeakyFunction(){
    auto p = malloc(1024*1024); // allocate 1Mb
    std::cout < < "TestApplication: Sleeping..." << std::endl;
    Sleep(15000);
    free(p); // free the Mb
}
 
int main()
{
    std::cout << "TestApplication: Creating some leaks..." << std::endl;
    for(int i = 0; i < 5; ++i){
        LeakyFunction();
    }
    NonLeakyFunction();
    std::cout << "TestApplication: Exiting..." << std::endl;
    return 0;
}

We can run Heapy with the command line:

> Heapy TestApplication.exe

Which will generate the following two reports in “Heapy_Profile.txt”

=======================================
 
Printing top allocation points.
 
< Trimmed out very small allocations from std::streams >
 
Alloc size 1Mb, stack trace: 
    NonLeakyFunction    e:\sourcedirectory\heapy\testapplication\main.cpp:9    (000000013FEC1D7E)
    main    e:\sourcedirectory\heapy\testapplication\main.cpp:22    (000000013FEC1E0D)
    __tmainCRTStartup    f:\dd\vctools\crt_bld\self_64_amd64\crt\src\crt0.c:241    (000000013FEC67FC)
    BaseThreadInitThunk    (00000000779A652D)
    RtlUserThreadStart    (0000000077ADC541)
 
Alloc size 25Mb, stack trace: 
    LeakyFunction    e:\sourcedirectory\heapy\testapplication\main.cpp:6    (000000013FEC1D5E)
    main    e:\sourcedirectory\heapy\testapplication\main.cpp:20    (000000013FEC1E06)
    __tmainCRTStartup    f:\dd\vctools\crt_bld\self_64_amd64\crt\src\crt0.c:241    (000000013FEC67FC)
    BaseThreadInitThunk    (00000000779A652D)
    RtlUserThreadStart    (0000000077ADC541)
 
Top 13 allocations: 26.005Mb
Total allocations: 26.005Mb (difference between total and top 13 allocations : 0Mb)
 
=======================================
 
Printing top allocation points.
 
< Trimmed out very small allocations from std::streams >
 
Alloc size 25Mb, stack trace: 
    LeakyFunction    e:\sourcedirectory\heapy\testapplication\main.cpp:6    (000000013FEC1D5E)
    main    e:\sourcedirectory\heapy\testapplication\main.cpp:20    (000000013FEC1E06)
    __tmainCRTStartup    f:\dd\vctools\crt_bld\self_64_amd64\crt\src\crt0.c:241    (000000013FEC67FC)
    BaseThreadInitThunk    (00000000779A652D)
    RtlUserThreadStart    (0000000077ADC541)
 
Top 5 allocations: 25.005Mb
Total allocations: 25.005Mb (difference between total and top 5 allocations : 0Mb)

The rest of this post is focused on why and how I constructed Heapy.
Continue reading »

 Posted by at 10:16 pm