Alternative to Visual Leak Detector

In this article, you will discover the limitations of a popular open-source library for detecting memory leaks, called Visual Leak Detector. Additionally, you will learn about an alternative to Visual Leak Detector, known as Deleaker.

Contents

What is Visual Leak Detector and How to Use It?

Visual Leak Detector (VLD) is a library for C++ developers that helps detect memory leaks caused by operator new, malloc, and other C++ functions that allocate memory. It’s open-source, and you can download its source code from https://github.com/KindDragon/vld.

While you can find precompiled versions of VLD, it’s a good idea to build it yourself. To do this, open Visual Studio 2015, load the vld_vs14.sln solution, and build it for both x86 and x64 platforms.

Next, let’s create a sample project to demonstrate how both tools work. Open Visual Studio, create a new console project (name it “LeakTest”), and place the following code into LeakTest.cpp:

#include <iostream>
#include <windows.h>

int main()
{
    HeapAlloc(GetProcessHeap(), 0, 1024);

    new int;

    malloc(12345);

    CreateDCW(nullptr, nullptr, nullptr, nullptr);
}

As you can see, we introduced four leaks: three memory leaks and one GDI leak.

To use VLD in your project, you need to include “vld.h” in any of your source files:

#include <iostream>
#include <windows.h>
#include "vld.h"

int main()
{
    HeapAlloc(GetProcessHeap(), 0, 1024);

    new int;

    malloc(12345);

    CreateDCW(L"DISPLAY", nullptr, nullptr, nullptr);
}

Additionally, you need to add the directory containing the header files to your project settings. Do this by navigating to Configuration Properties -> VC++ Directories -> Include Directories -> Edit…, and then add the directory where “vld.h” is located, as shown below:

Add the VLD include directory

You also need to add the directory for libraries. To do this, navigate to Configuration Properties -> VC++ Directories -> Library Directories -> Edit…, as shown below:

Add the VLD library directory

Now, you should be able to build the project successfully. However, when you run the application, you will notice that it requires the VLD DLL (vld_x64.dll):

vld_x64.dll not found

The vld_x64.dll was built previously, so you can copy it to the application directory. However, even after doing this, the application will not run and will display the following error:

The application was unable to start correctly (0xc0150002)

This error can be resolved by copying two files: dbghelp.dll and Microsoft.DTfW.DHL.manifest. After doing this, the application should run fine. Run the debugger, and once the process quits, you will see the following in the Output Directory:

WARNING: Visual Leak Detector detected memory leaks!
---------- Block 2 at 0x00000000C98D8640: 4 bytes ----------
  CRT Alloc ID: 95
  Leak Hash: 0x7BCA5720, Count: 1, Total 4 bytes
  Call Stack (TID 109880):
    ucrtbased.dll!malloc()
    D:\a\_work\1\s\src\vctools\crt\vcstartup\src\heap\new_scalar.cpp (36): LeakTest.exe!operator new() + 0xA bytes
    E:\Projects\LeakTest\LeakTest.cpp (12): LeakTest.exe!main() + 0xA bytes
    D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl (79): LeakTest.exe!invoke_main()
    D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl (288): LeakTest.exe!__scrt_common_main_seh() + 0x5 bytes
    D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl (331): LeakTest.exe!__scrt_common_main()
    D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_main.cpp (17): LeakTest.exe!mainCRTStartup()
    KERNEL32.DLL!BaseThreadInitThunk() + 0x14 bytes
    ntdll.dll!RtlUserThreadStart() + 0x21 bytes
  Data:
    CD CD CD CD                                                  ........ ........


---------- Block 1 at 0x00000000C98E8ED0: 1024 bytes ----------
  Leak Hash: 0x13245EA2, Count: 1, Total 1024 bytes
  Call Stack (TID 109880):
    ntdll.dll!RtlAllocateHeap()
    E:\Projects\LeakTest\LeakTest.cpp (12): LeakTest.exe!main()
    D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl (79): LeakTest.exe!invoke_main()
    D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl (288): LeakTest.exe!__scrt_common_main_seh() + 0x5 bytes
    D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl (331): LeakTest.exe!__scrt_common_main()
    D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_main.cpp (17): LeakTest.exe!mainCRTStartup()
    KERNEL32.DLL!BaseThreadInitThunk() + 0x14 bytes
    ntdll.dll!RtlUserThreadStart() + 0x21 bytes
  Data:
    50 01 8C C9    25 02 00 00    D0 6A 8E C9    25 02 00 00     P...%... .j..%...

---------- Block 3 at 0x00000000C98E9310: 12345 bytes ----------
  CRT Alloc ID: 96
  Leak Hash: 0x33D86AC4, Count: 1, Total 12345 bytes
  Call Stack (TID 109880):
    ucrtbased.dll!malloc()
    E:\Projects\LeakTest\LeakTest.cpp (16): LeakTest.exe!main()
    D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl (79): LeakTest.exe!invoke_main()
    D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl (288): LeakTest.exe!__scrt_common_main_seh() + 0x5 bytes
    D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl (331): LeakTest.exe!__scrt_common_main()
    D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_main.cpp (17): LeakTest.exe!mainCRTStartup()
    KERNEL32.DLL!BaseThreadInitThunk() + 0x14 bytes
    ntdll.dll!RtlUserThreadStart() + 0x21 bytes
  Data:
    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........

Visual Leak Detector detected 3 memory leaks (13477 bytes).
Largest number used: 13477 bytes.
Total allocations: 13477 bytes.
Visual Leak Detector is now exiting.

As you can see, VLD detected 3 out of the 4 leaks. Unfortunately, the line number is incorrect for one of the leaks.

What are the Known Limitations of Visual Leak Detector?

As demonstrated, using VLD can be a challenge. You need to modify compiler and linker settings, and you also need to rebuild your project to use Visual Leak Detector. Additionally, you must distribute not only the VLD DLL but also additional DLLs. I believe this will give customers the impression that they are using a debug build of your application, which means you may need to maintain two versions of the software.

Visual Leak Detector is limited to detecting memory leaks in Visual C++. It doesn’t catch leaks of GDI resources, handles, and other types of leaks. Additionally, it does not support other compilers like MinGW, C++Builder, or GCC.

When you use Visual Leak Detector, the results are presented as a large amount of information in text format. This makes it difficult to sort the leaks by size or filter them based on specific criteria.

It’s time to explore an alternative to Visual Leak Detector!

What is an Alternative to Visual Leak Detector?

One of the most well-known alternatives to Visual Leak Detector is Deleaker. Deleaker can function as a standalone tool as well as a plugin for Visual Studio and other IDEs. You can download it from the download page at: https://www.deleaker.com/download.html

Once installed, you can find the Deleaker menu item in the main menu of Visual Studio:

Deleaker menu in Visual Studio

Click on Extensions, then Deleaker, and then Deleaker Windows. Ensure that it is enabled as shown below:

Enable Deleaker

oad the same project, remove ‘vld.h’, rebuild the project, and start debugging. When the process quits, Deleaker will take a snapshot, allowing you to see all four leaks:

Deleaker displays leaks

For each allocation, you can review the entire call stack, size, and module path. You can take snapshots while a process is running and after it has exited. You can compare snapshots to identify new allocations, which can be useful if you notice that your process is using more and more memory. Additionally, snapshots can be exported for later analysis.

Conclusion

While Visual Leak Detector is free and open-source, it may take time to integrate it with your project, and it doesn’t detect GDI leaks or handle leaks. Additionally, Visual Leak Detector becomes a part of your application. In contrast, Deleaker works with the Visual Studio debugger, so you don’t need to recompile your project; Deleaker supports all kinds of leaks, including GDI leaks and others. Visual Leak Detector lacks a user interface, whereas Deleaker provides a rich UI that allows you to sort and filter allocations, export and import snapshots, and generate reports in XML format. All these features make Deleaker an indispensable tool for developers looking to fix memory leaks in their applications.