Hello.  There is a handy tool called Dr. Memory, which I have been using to 
check for memory leaks in programs I develop with MSYS2 and mingw-w64:

   http://www.drmemory.org/

I noticed that it always reports a small memory leak for the application I was 
debugging.  It's not a big deal, but it was kind of annoying so I am trying to 
figure out what is wrong.  After a lot of debugging, I figured out that any 
variable using thread-local storage (__thread) is reported as a memory leak if 
the program uses it in any way.  Here is a simple program I used to reproduce 
the error:

     #include <stdio.h>
     
     static __thread int foo;
     
     int main(int argc, char * const argv[])
     {
         printf("%d %p\n", sizeof(foo), &foo);
         return 0;
     }

This is the version of GCC I am using:

     $ gcc -v
     Using built-in specs.
     COLLECT_GCC=C:\msys64\mingw32\bin\gcc.exe
     
COLLECT_LTO_WRAPPER=C:/msys64/mingw32/lib/gcc/i686-w64-mingw32/4.9.2/lto-wrapper.exe
     Target: i686-w64-mingw32
     Configured with: ../gcc-4.9.2/configure --prefix=/mingw32 
--with-local-prefix=/mingw32/local --build=i686-w64-mingw32 
--host=i686-w64-mingw32 --target=i686-w64-mingw32 
--with-native-system-header-dir=/mingw32/i686-w64-mingw32/include 
--libexecdir=/mingw32/lib --with-gxx-include-dir=/mingw32/include/c++/4.9.2 
--enable-bootstrap --with-arch=i686 --with-tune=generic 
--enable-languages=c,lto,c++,objc,obj-c++,fortran,ada --enable-shared 
--enable-static --enable-libatomic --enable-threads=posix --enable-graphite 
--enable-fully-dynamic-string --enable-libstdcxx-time=yes 
--disable-libstdcxx-pch --disable-libstdcxx-debug --enable-cloog-backend=isl 
--enable-version-specific-runtime-libs --disable-cloog-version-check 
--disable-isl-version-check --enable-lto --enable-libgomp --disable-multilib 
--enable-checking=release --disable-rpath --disable-win32-registry 
--disable-nls --disable-werror --disable-symvers --with-libiconv 
--with-system-zlib --with-gmp=/mingw32 --with-mpfr=/mingw32 --with-
mpc=/mingw32 --with-isl=/mingw32 --with-cloog=/mingw32 --with-pkgversion='Rev5, 
Built by MSYS2 project' --with-bugurl=http://sourceforge.net/projects/msys2 
--with-gnu-as --with-gnu-ld --disable-sjlj-exceptions --with-dwarf2
     Thread model: posix
     gcc version 4.9.2 (Rev5, Built by MSYS2 project)

I compiled it and tested it like this:

     gcc -g bug.c -o bug.exe && drmemory -leaks_only bug.exe

And Dr. Memory reported this leak, which goes away if I remove the line that 
accesses the address of the thread local variable:

     Error #1: POSSIBLE LEAK 8 direct bytes 0x00d30898-0x00d308a0 + 0 indirect 
bytes
     # 0 replace_malloc                      
[d:\drmemory_package\common\alloc_replace.c:2377]
     # 1 libwinpthread-1.dll!?              +0x0      (0x64b4466c 
<libwinpthread-1.dll+0x466c>)
     # 2 KERNELBASE.dll!WaitForSingleObjectEx+0xb6     (0x76a12cc7 
<KERNELBASE.dll+0x2cc7>)
     # 3 KERNELBASE.dll!WaitForSingleObjectEx+0xd7     (0x76a12ce8 
<KERNELBASE.dll+0x2ce8>)
     # 4 libwinpthread-1.dll!?              +0x0      (0x64b44db3 
<libwinpthread-1.dll+0x4db3>)
     # 5 libwinpthread-1.dll!?              +0x0      (0x64b4466c 
<libwinpthread-1.dll+0x466c>)
     # 6 libwinpthread-1.dll!?              +0x0      (0x64b4cd42 
<libwinpthread-1.dll+0xcd42>)
     # 7 __emutls_get_address                
[C:/repo/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/pesect.c:230]
     # 8 main                                
[C:\Users\David\Documents\bugs\mingw_leak/bug.c:7]

Interestingly, if I compile with g++ instead of GCC, the stack trace looks 
different:

     Error #1: POSSIBLE LEAK 8 direct bytes 0x00d405b0-0x00d405b8 + 0 indirect 
bytes
     # 0 replace_malloc                      
[d:\drmemory_package\common\alloc_replace.c:2377]
     # 1 libwinpthread-1.dll!?              +0x0      (0x64b4466c 
<libwinpthread-1.dll+0x466c>)
     # 2 KERNELBASE.dll!WaitForSingleObjectEx+0xb6     (0x76a12cc7 
<KERNELBASE.dll+0x2cc7>)
     # 3 KERNELBASE.dll!WaitForSingleObjectEx+0xd7     (0x76a12ce8 
<KERNELBASE.dll+0x2ce8>)
     # 4 libwinpthread-1.dll!?              +0x0      (0x64b44db3 
<libwinpthread-1.dll+0x4db3>)
     # 5 libwinpthread-1.dll!?              +0x0      (0x64b4466c 
<libwinpthread-1.dll+0x466c>)
     # 6 libwinpthread-1.dll!?              +0x0      (0x64b4cd42 
<libwinpthread-1.dll+0xcd42>)
     # 7 libgcc_s_dw2-1.dll!emutls_alloc     
[../../../gcc-4.9.2/libgcc/emutls.c:102]
     # 8 libgcc_s_dw2-1.dll!__emutls_get_address 
[../../../gcc-4.9.2/libgcc/emutls.c:183]
     # 9 main                                
[C:\Users\David\Documents\bugs\mingw_leak/bug.c:7]

In case the formatting of this email is messed up, you can see all of this 
information here:

https://gist.github.com/DavidEGrayson/97bf529b73315026c8f8

By the way, to get these nice stack traces, I had to compile the MSYS2 gcc 
package myself using this script:

https://github.com/Alexpux/MINGW-packages/blob/c0095d7bd46f293ff0c5c0f2499b17b48bf07e9e/mingw-w64-gcc/PKGBUILD

This was an error-prone process that I haven't actually completed yet, but the 
build got far enough to produce a usable version of libgcc_s_dw2-1.dll with 
debugging information.

Does anyone know what is causing Dr. Memory to report this memory leak?  Is it 
a bug with Dr. Memory, or is there an actual memory leak in mingw-w64?

I am trying to go one level deeper, to see if I can reproduce the bug using the 
__gthread_* functions that emutls.c uses.  However, I don't know what header to 
include or what library to link against in order to use things like 
__ghtread_active_p() in a standalone C program.  Does anyone know how to do 
that?

Alternatively, if someone can recommend a memory leak checker for Windows 
programs, particularly one that doesn't require recompilation of the target 
program, I might try it out to see if it reports the same memory leak.

Again, this isn't a very high priority problem for me, but it would be nice to 
get it fixed.  Thanks!

--David Grayson


------------------------------------------------------------------------------
Don't Limit Your Business. Reach for the Cloud.
GigeNET's Cloud Solutions provide you with the tools and support that
you need to offload your IT needs and focus on growing your business.
Configured For All Businesses. Start Your Cloud Today.
https://www.gigenetcloud.com/
_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to