Open milianw opened 6 years ago
After updating to the Fall Creators update and installing an updated syscalls_x64.txt, I see an improved backtrace:
~~Dr.M~~ Error #1: LEAK 100 direct bytes 0x0000018f2c4e0290-0x0000018f2c4e02f4 + 0 indirect bytes
~~Dr.M~~ # 0 replace_operator_new_array [d:\drmemory_package\common\alloc_replace.c:2928]
~~Dr.M~~ # 1 ntdll.dll!LdrResolveDelayLoadedAPI +0x15b (0x00007ffbd6ef1dfc <ntdll.dll+0x21dfc>)
~~Dr.M~~ # 2 _Init_thread_unlock [f:\dd\vctools\crt\vcstartup\src\misc\thread_safe_statics.cpp:149]
~~Dr.M~~ # 3 foo [c:\qt\src\training-material\addon\debugging\ex_leak\main.cpp:9]
~~Dr.M~~ # 4 _Init_thread_header [f:\dd\vctools\crt\vcstartup\src\misc\thread_safe_statics.cpp:224]
~~Dr.M~~ # 5 ucrtbased.dll!_initterm_e [minkernel\crts\ucrt\src\appcrt\startup\initterm.cpp:40]
~~Dr.M~~ # 6 KERNEL32.dll!BaseThreadInitThunk +0x13 (0x00007ffbd5ce1fe4 <KERNEL32.dll+0x11fe4>)
I.e. foo shows up now, but main is still missing. Is this maybe a strange behavior of statics in Windows?
Removing the static
from the initialization of bar
in main, I instead again get:
~~Dr.M~~ Error #1: LEAK 4 direct bytes 0x00000197a8be0340-0x00000197a8be0344 + 0 indirect bytes
~~Dr.M~~ # 0 replace_operator_new [d:\drmemory_package\common\alloc_replace.c:2899]
~~Dr.M~~ # 1 ntdll.dll!LdrResolveDelayLoadedAPI +0x15b (0x00007ffbd6ef1dfc <ntdll.dll+0x21dfc>)
~~Dr.M~~ # 2 ucrtbased.dll!_initterm_e [minkernel\crts\ucrt\src\appcrt\startup\initterm.cpp:40]
~~Dr.M~~ # 3 KERNEL32.dll!BaseThreadInitThunk +0x13 (0x00007ffbd5ce1fe4 <KERNEL32.dll+0x11fe4>)
Sadly, no foo, no main.
I suspect this is limited to VS2017 ucrt, though in general efficient callstacks on Windows are painful, and the current scheme has been tuned for 32-bit. Many functions in system or crt libs have FPO, which can result in skipping higher frames. To counter this Dr. Memory has a lot of scanning options to find retaddrs w/o frame pointers. Going to debug info (as debuggers do) is considered too expensive, as callstacks need to be gathered on every single malloc in case it's leaked later.
What we should do for 64-bit Windows is walk the SEH64 unwind info which is #1222 but that's not implemented (if someone would like to contribute some work toward that feature...).
You can see a number of options here: http://drmemory.org/docs/page_options.html -callstack_conservative or -callstack_bad_fp_list may help.
Take this trivial example code:
Compile it (I use qmake, but these are the effective compile flags:)
Then run it through drmemory and look at the leak report:
Note how it does not show any frame in the file I wrote at all. Both main and foo are nowhere to be found. In a debugger like from Visual Studio, I see the frames properly when I step through the execution.