Use umdh to locate C++ memory leaks under windows

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

windbg x64 v6.12

windbg x86 v6.12

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:

  1. Find user-mode memory leaks with UMDH

Guess you like

Origin blog.csdn.net/itas109/article/details/130303643