#1928 CRT calls TlsFree before TlsGetValue, leading to racy accesses and leaks


Running Dr. Memory (http://code.google.com/p/drmemory/) on this simple

#include <iostream>
int main() 
    try {
        std::cout << "throwing exception" << std::endl;
        throw std::exception();
    } catch (std::exception&) {
        std::cout << "caught exception" << std::endl;
    return 0;

Results in two error reports, one "UNADDRESSABLE ACCESS" and one memory
leak. These are detailed in these two Dr. Memory issue tracker entries:


I tried with the latest mingw and the same errors are present.

% /c/mingw/bin/g++ -v
Using built-in specs.
Target: mingw32
Configured with: ../gcc-4.7.2/configure --enable-languages=c,c++,ada,fortran,objc,obj-c++ --disable-sjlj-exceptions --with-dwarf2 --enable-shared --enable-libgomp --disable-win32-registry --enable-libstdcxx-debug --disable-build-poststage1-with-cxx --enable-version-specific-runtime-libs --build=mingw32 --prefix=/mingw
Thread model: win32
gcc version 4.7.2 (GCC)
% /c/mingw/bin/ld -v
GNU ld (GNU Binutils) 2.23.1
% uname -a
CYGWIN_NT-6.1-WOW64 kraken 1.7.16(0.262/5/3) 2012-07-20 22:55 i686 Cygwin

I'm on Windows 7 Ultimate 6.1.7601 Service Pack 1 Build 7601

I built like this:
% /c/mingw/bin/g++ -static-libgcc -static-libstdc++ -ggdb -mthreads -o cppexcept-mingw.exe cppexcept.cpp

I ran Dr. Memory like this:
% ~/drmemory/releases/DrMemory-Windows-1.5.0-5/bin/drmemory.exe -batch -- ./cppexcept-mingw.exe

The -mthreads makes no difference in whether the bugs are reported.

At the Dr. Memory team we believe, after looking at the mingw and gcc sources, that these two errors both stem from the TlsFree being called too early. See the two Dr. Memory issue links above for further information.


  • Derek Bruening

    Derek Bruening - 2013-02-20

    I'm pasting in the Dr. Memory errors here for easier reference:

    Error #1: UNADDRESSABLE ACCESS: reading 0x7efdde1c-0x7efdde20 4 byte(s)
    # 0 KERNELBASE.dll!TlsGetValue   
    # 1 __mingwthr_run_key_dtors               [/usr/src/mingw-runtime/mingw-runtime-3.20-1/src/mingwrt-3.20-mingw32/tlsthrd.c:108]
    # 2 __mingw_TLScallback                    [/usr/src/mingw-runtime/mingw-runtime-3.20-1/src/mingwrt-3.20-mingw32/tlsthrd.c:133]
    # 3 __dyn_tls_dtor@12                      [/usr/src/mingw-runtime/mingw-runtime-3.20-1/src/mingwrt-3.20-mingw32/tlssup.c:170]
    # 4 ntdll.dll!LdrpCallInitRoutine
    # 5 ntdll.dll!LdrpCallTlsInitializers
    # 6 ntdll.dll!LdrShutdownProcess
    # 7 ntdll.dll!RtlExitUserProcess
    # 8 KERNEL32.dll!ExitProcessStub
    # 9 __mingw_CRTStartup                     [/usr/src/mingw-runtime/mingw-runtime-3.20-1/src/mingwrt-3.20-mingw32/crt1.c:252]
    #10 mainCRTStartup                         [/usr/src/mingw-runtime/mingw-runtime-3.20-1/src/mingwrt-3.20-mingw32/crt1.c:264]
    #11 KERNEL32.dll!BaseThreadInitThunk
    Note: @0:00:00.577 in thread 6616
    Note: instruction: mov    0x00000e10(%eax,%ecx,4) -> %eax
    Error #2: LEAK 8 direct bytes 0x003420b8-0x003420c0 + 0 indirect bytes
    # 0 __cxa_get_globals                      [/usr/src/packages/mingw-gcc/mingw-gcc-4.5.2-1/src/gcc-4.5.2/libstdc++-v3/libsupc++/eh_globals.cc:132]
    # 1 __cxa_allocate_exception               [/usr/src/packages/mingw-gcc/mingw-gcc-4.5.2-1/src/gcc-4.5.2/libstdc++-v3/libsupc++/eh_alloc.cc:132]
    # 2 test_exception()                       [/d/derek/dr/test/cppexcept.cpp:30]
    # 3 main                                   [/d/derek/dr/test/cppexcept.cpp:38]
          1 unique,     1 total unaddressable access(es)
          0 unique,     0 total uninitialized access(es)
          0 unique,     0 total invalid heap argument(s)
          0 unique,     0 total GDI usage error(s)
          0 unique,     0 total warning(s)
          1 unique,     1 total,      8 byte(s) of leak(s)
          0 unique,     0 total,      0 byte(s) of possible leak(s)
  • Earnie Boyd

    Earnie Boyd - 2013-02-20
    • labels: --> duplicate?, tls
    • status: unread --> assigned
    • assigned_to: Earnie Boyd
    • category: Unknown --> Waiting_User_Response
  • Derek Bruening

    Derek Bruening - 2013-02-20

    Can you run your tests on the current repository 4.0-dev branch code please?

    Hmmm, I've been using binary releases of mingw. I can try to make some time to build mingw from the latest sources.

    Note that it may be simpler and faster, if you have the latest mingw already built, to grab Dr. Memory from http://code.google.com/p/drmemory/downloads/list and run it on the tiny app in the original entry above. We have built-in DWARF2 mingw symbol support and perhaps our tool could be useful to your project (it's essentially "Valgrind Memcheck for Windows").

  • Derek Bruening

    Derek Bruening - 2013-02-20

    Sorry, I just discovered that the g++ 4.7.2 was failing to compile (the installation BIN was not on the path so it failed to find
    libgmp-10.dll, etc., with a silent error in a non-cmd window) and I was running the 4.5.2-built executable while verifying it also happened w/ 4.7.2.

    g++ 4.5.2 is where we observed this bug. It is not present on 4.7.2.

    This can be resolved.


Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

No, thanks