What keeps a C++ developer awake at night?
A nagging question at the back of his subconsciousness is “Does my application have a memory leak?”. Continual memory leaks can be detrimental to long-running programs and eventually, the system runs out of memory and is stopped in its operation. Detection and elimination of memory leak should be of the highest priority to every application developer.
- The macros have to be manually added at the top of every C++ source file. The application code has to be instrumented with _CrtXxx family of functions to assist and fine-tune the detection. This is needless and disruptive development work where time could have been spent fixing more issues.
- There has to be a way to hide those Microsoft-specific macros when compiling on a non-Microsoft platform.
- The macros are incompatible with a library that overloads their ‘new’ operator. For instance, Microsoft’s GDI+.
- The report, those macros enables, often identifies false positives or memory leak that occurred in official Microsoft or third-party libraries that the developer is either not interested in or helpless to fix. Needless to say, the reliability of the report leaves much to be desired.
If a C++ developer is anyone like me, looking for a hassle-free solution that just works, period. In this review, we shall put the Deleaker profiler to the test and see if it delivers on its goal. Deleaker is a memory leak detection tool that can be used as a standalone tool or as an IDE extension. Deleaker uses hooks and does not modify the code of a program: code execution speed remains almost the same. Deleaker doesn’t require a program to be rebuilt. All that Deleaker needs is debug information to locate the source of leaks. It supports both 32-bit and 64-bit code. Its full feature list is below.
- Deleaker is a standalone proprietary memory leak detection tool and is often used as the Visual C++ extension.
- Detects memory, GDI and WinAPI handle leaks and easily integrates with IDE. Supported IDEs include
- All versions of Visual Studio since 2005
- Qt Creator
- C++ Builder
- RAD Studio
- The standalone version debugs the application to show the current allocation of objects.
- Detect leaks in .NET languages such as C# and C++/CLI.
- Supports all 32 – bit as well as 64 – bit system and fully integrated with Visual Studio.
- Generates rich reports and exports the final outcome to XML.
C++ Application Profiling
A C++ MFC Direct3D slideshow application is the first profiling test. This application takes photos and songs to make into a slideshow. Before Deleaker can be used as a profiler in a debugging session, it has to be enabled beforehand from the extension menu because not in every debugging session, the developer is interested in finding out the memory leaks.
Before the debugging begins, a dialog prompt shows up to select the allocation types to be monitored.
The MFC slideshow application screenshot is shown.
After the testing is done and the application is closed, Deleaker shall collect all the allocation information including their call-stack. Even if the application being debugged is terminated via the debugger stop command, Deleaker prompts the user whether to collect the allocation information. The hit count (in red rectangle) column shows the number of times the exact source code line has been responsible for allocation. As the reader can see from the Deleaker screenshot, many leaks are from the Microsoft Parallel Patterns Library (PPL). Prior to this test, I ran a Text Rendering application on Deleaker whose test result shows no leaks. That result was, unfortunately, a false negative because the testing is not thorough enough: the Gaussian Blur Text Shadow feature that utilizes PPL, is not activated. That shows profiling is only as good as the test coverage.
Double-clicking on any line shall highlight the exact line in the source code editor where the allocation is done. The application is found to have memory leaks through some raw pointer which is resolved by using a smart pointer to do the lifetime management. The lesson here to the C++ developers is raw pointer use is to be avoided at all costs.
C# and C++ Hybrid Application Profiling
For the second test, a .NET WPF application is used. As everyone knows .NET is an automatic garbage collection based platform and all memory allocations are managed by the GC. So what constitutes a memory leak? How does Deleaker define a memory leak on .NET? This question is put to Deleaker developer, Artem Razin. His reply is as follows.
Artem: There is a special profiler mode in Deleaker for .NET. A snapshot contains live objects in such case. Leaks in .NET can happen if object count is growing again and again unexpectedly.
The Deleaker tutorial mentioned There is one important thing related to debugging .NET code. Deleaker is able to find both managed and unmanaged leaks in .NET code: if .NET code calls DLLs written in C++, Deleaker is able to find such leaks. Nevertheless, don’t forget to enable unmanaged code debugging in project settings. Without that, Deleaker can’t attach to started processes. Cool, now .NET developer can kill two birds with one stone. To test the .NET memory leak detection capabilities of Deleaker, C# version of the same slideshow is used. The UI is implemented in Windows Presentation Foundation (WPF) this time instead of MFC, the bulk of the slideshow work is in the same engine now encapsulated in one C DLL for C# to call via Platform-Invoke. The results show no .NET leaks, only C++ memory leaks were found through the use of raw pointers in the C dll. The lesson is reinforced that raw pointer use must be totally discouraged and the smart pointer should be the preferred way to do resource management. In the slideshow source code, almost all allocations are tracked and managed by smart pointers like STL’s shared_ptr/unique_ptr and WRL ComPtr but as all best efforts go, use of some raw pointer regrettably slipped through.
The WPF slideshow application screenshot is shown.
Deleaker provides the feature of taking snapshots and comparing them to track the source of growing allocation. One complaint is that when there are many allocations, it can take quite awhile for a snapshot to complete meanwhile the slideshow came to a complete halt. This might not be acceptable to time-critical/time-sensitive software (like communication-based or low-latency). The pros and cons of Deleaker are summarized below.
- No instrumenting or modifying of code to enable memory detection. In other words, it just works!
- Real-time memory usage graph to help visualize memory growth over time.
- Snapshots comparison to find growing memory leaks.
- Easily find the exact line of source code that allocates (leaked) memory with one double click.
- Entire callstack is available for every memory leak to see who are its callers and how it happens.
- Tight integration with the IDEs.
- Works on other popular IDEs such as Qt Creator and C++ Builder
- Supports Delphi and .NET languages such as C# and C++/CLI
- Can detect memory leaks in managed and unmanaged code simultaneously from the same application.
- Taking a snapshot can take some time when there are many allocations.
- It only works on the Microsoft Windows platform.
Regarding the last con, it can be overcome: rather then debugging memory issue on MacOSX/Unix/Linux, that is if the C++ code is truly cross-platform, it can always be run and profiled under Deleaker on Windows. An added bonus is Deleaker does not hold up the application operation like Valgrind does. For any Windows developer, Deleaker is an indispensable and time-saver tool to track down memory leaks and saves invaluable developer time to focus on doing the value-added work that brings in the dough. Highly recommended to any developer making a livelihood writing code on Windows!
Financial Incentive Disclaimer: It should be disclosed that no monetary gain changed hands in writing this review except a copy of Deleaker that is essential for doing the review.