Use umdh to locate C++ memory leaks under windows
If you need to reprint, please indicate the source: https://blog.csdn.net/itas109
Technical exchange: 129518033
environment:
OS: windows 10(1909 内部版本18363)
windbg: 6.12 x64
UMDH: 6.1.7650
foreword
The User Mode Dump Heap (UMDH) utility is used with the operating system to analyze process-specific Windows heap allocations. UMDH finds which routine in a particular process is leaking memory.
1. Install umdh
2. Use umdh to take a memory snapshot
2.1 Command line mode
- Turn on stack trace
Note: This function will affect the performance of the program after it starts, so use it with caution in the production environment.
"C:\Program Files\Debugging Tools for Windows (x64)\gflags" -i main.exe +ust
- Set the application pdb path (the system pdb path is optional)
SET _NT_SYMBOL_PATH=D:\MemoryLeakTest\build
or
SET _NT_SYMBOL_PATH=D:\MemoryLeakTest\build;srv*c:\symbols*http://msdl.microsoft.com/download/symbols
- Take a snapshot of the current memory
"C:\Program Files\Debugging Tools for Windows (x64)\umdh" -pn:main.exe -f:Snap1.log
- The program runs for a period of time or performs some operation that is suspected of leaking
Here, the test program main.exe will apply for new memory every time you press Enter
- Take a snapshot after running
"C:\Program Files\Debugging Tools for Windows (x64)\umdh" -pn:main.exe -f:Snap2.log
- analysis results
Note: At this time, the pdb required by the system may be downloaded, and you need to wait for a while
"C:\Program Files\Debugging Tools for Windows (x64)\umdh" -d Snap1.log Snap2.log -f:result.txt
2.2 Batch mode
env.bat
@echo off
SET APP_NAME=main.exe
SET APP_PDB_PATH=D:\MemoryLeakTest\build
@REM SET SYSTEM_PDB_PATH=srv*c:\symbols*http://msdl.microsoft.com/download/symbols
SET WINDBG_PATH=C:\Program Files\Debugging Tools for Windows (x64)
SET PATH=%WINDBG_PATH%;%PATH%
SET _NT_SYMBOL_PATH=%APP_PDB_PATH%;%SYSTEM_PDB_PATH%
SET CURRENT_PWD=%~dp0
gflags -i %APP_NAME% +ust
start.bat
@echo off
call env.bat
umdh -pn:%APP_NAME% -f:%CURRENT_PWD%\Snap1.log
pause
end.bat
@echo off
call env.bat
umdh -pn:%APP_NAME% -f:%CURRENT_PWD%\Snap2.log
umdh -d %CURRENT_PWD%\Snap1.log %CURRENT_PWD%\Snap2.log -f:%CURRENT_PWD%\result.txt
pause
3. Analysis of results
There is a memory leak at line 8 of main.cpp
// Debug library initialized ...
DBGHELP: main - private symbols & lines
.\main.pdb
DBGHELP: ntdll - export symbols
DBGHELP: KERNEL32 - export symbols
DBGHELP: KERNELBASE - export symbols
DBGHELP: VCRUNTIME140D - export symbols
DBGHELP: ucrtbased - export symbols
//
// Each log entry has the following syntax:
//
// + BYTES_DELTA (NEW_BYTES - OLD_BYTES) NEW_COUNT allocs BackTrace TRACEID
// + COUNT_DELTA (NEW_COUNT - OLD_COUNT) BackTrace TRACEID allocations
// ... stack trace ...
//
// where:
//
// BYTES_DELTA - increase in bytes between before and after log
// NEW_BYTES - bytes in after log
// OLD_BYTES - bytes in before log
// COUNT_DELTA - increase in allocations between before and after log
// NEW_COUNT - number of allocations in after log
// OLD_COUNT - number of allocations in before log
// TRACEID - decimal index of the stack trace in the trace database
// (can be used to search for allocation instances in the original
// UMDH logs).
//
+ 1076 ( 1076 - 0) 1 allocs BackTraceE2CEAC2E
+ 1 ( 1 - 0) BackTraceE2CEAC2E allocations
ntdll!RtlWalkHeap+00000213
ntdll!RtlAllocateHeap+00000AEB
ucrtbased!calloc_base+00001226
ucrtbased!calloc_base+00000FCD
ucrtbased!malloc_dbg+0000002F
ucrtbased!malloc+0000001E
main!operator new+00000013 (d:\agent\_work\2\s\src\vctools\crt\vcstartup\src\heap\new_scalar.cpp, 35)
main!operator new[]+00000013 (d:\agent\_work\2\s\src\vctools\crt\vcstartup\src\heap\new_array.cpp, 29)
main!main+00000038 (d:\MemoryLeakTest\main.cpp, 8)
main!invoke_main+00000034 (d:\agent\_work\2\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl, 79)
main!__scrt_common_main_seh+0000012E (d:\agent\_work\2\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl, 288)
main!__scrt_common_main+0000000E (d:\agent\_work\2\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl, 331)
main!mainCRTStartup+00000009 (d:\agent\_work\2\s\src\vctools\crt\vcstartup\src\startup\exe_main.cpp, 17)
KERNEL32!BaseThreadInitThunk+00000014
ntdll!RtlUserThreadStart+00000021
Total increase == 1076 requested + 44 overhead = 1120
4. Test procedure
main.exe
Note: Because windbg is 64-bit, the program needs to be compiled as a 64-bit program
- main.cpp
#include <iostream>
int main()
{
while (true)
{
printf("Press Enter to Continue\n");
getchar();
char *s = new char[1024];
}
return 0;
}
- CMakeLists.txt
cmake_minimum_required(VERSION 2.8.12)
project(main)
add_executable( ${PROJECT_NAME} main.cpp)
License
License under CC BY-NC-ND 4.0: Attribution-Noncommercial Use-No Derivatives
If you need to reprint, please indicate the source: https://blog.csdn.net/itas109
Technical exchange: 129518033
Reference: