[Bug c++/80883] New: Hardcoded null DSO handle parameter to __cxa_thread_atexit() on MinGW-w64 targets

lh_mouse at 126 dot com gcc-bugzilla@gcc.gnu.org
Thu May 25 19:57:00 GMT 2017


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80883

            Bug ID: 80883
           Summary: Hardcoded null DSO handle parameter to
                    __cxa_thread_atexit() on MinGW-w64 targets
           Product: gcc
           Version: 7.1.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: lh_mouse at 126 dot com
  Target Milestone: ---

It looks like that GCC for MinGW-w64 targets always passes a null DSO handle to
`__cxa_thread_atexit()` when registering destructors for objects with thread
storage duration. This violates Itanium ABI apparently, doesn't it?
The `__cxa_thread_atexit()` function calls `GetModuleHandleExW()` to obtain a
DLL handle from the function that will be called, which isn't reliable at all,
because when we have `thread_local std::string s; s = "hello";` the first
parameter actually points to `std::string::~basic_string` which is in
libstdc++.
The destructor is then called only when libstdc++ is unloaded, but it should
have been called when the DLL that contains that thread_local definition is
unloaded.


Testcase:
(This can be found http://paste.ubuntu.com/24657853/ at the moment.)
---------------------------------------------
E:\Desktop>cat test.cc
#include <string>

extern "C" int __stdcall DllMain(void *hInstance, void *, unsigned long
dwReason, void *pReserved){
        thread_local std::string s;
        s = "hello";
        return 1;
}

E:\Desktop>g++ test.cc -std=c++11 -O3 -shared -S

E:\Desktop>cat test.s
        .file   "test.cc"
        .section .rdata,"dr"
.LC0:
        .ascii "hello\0"
        .text
        .globl  DllMain
        .def    DllMain;        .scl    2;      .type   32;     .endef
        .seh_proc       DllMain
DllMain:
.LFB1041:
        pushq   %rsi
        .seh_pushreg    %rsi
        pushq   %rbx
        .seh_pushreg    %rbx
        subq    $56, %rsp
        .seh_stackalloc 56
        .seh_endprologue
        leaq    __emutls_v._ZGVZ7DllMainE1s(%rip), %rcx
        call    __emutls_get_address
        movq    %rax, %rsi
        leaq    __emutls_v._ZZ7DllMainE1s(%rip), %rcx
        call    __emutls_get_address
        movq    %rax, %rbx
        cmpb    $0, (%rsi)
        jne     .L2
        leaq    16(%rax), %rax
        movq    %rax, (%rbx)
        movq    $0, 8(%rbx)
        movb    $0, 16(%rbx)
        movb    $1, (%rsi)
        xorl    %r8d, %r8d
        movq    %rbx, %rdx
        leaq   
_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev(%rip), %rcx
        call    __cxa_thread_atexit
.L2:
        movq    8(%rbx), %r8
        movq    $5, 32(%rsp)
        leaq    .LC0(%rip), %r9
        xorl    %edx, %edx
        movq    %rbx, %rcx
        call   
_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE10_M_replaceEyyPKcy
        movl    $1, %eax
        addq    $56, %rsp
        popq    %rbx
        popq    %rsi
        ret
        .seh_endproc
        .data
        .align 32
__emutls_v._ZZ7DllMainE1s:
        .quad   32
        .quad   8
        .quad   0
        .quad   0
        .align 32
__emutls_v._ZGVZ7DllMainE1s:
        .quad   8
        .quad   8
        .quad   0
        .quad   0
        .ident  "GCC: (gcc-7-branch HEAD with MCF thread model, built by
LH_Mouse.) 7.1.1 20170518"
        .def    __emutls_get_address;   .scl    2;      .type   32;     .endef
        .def    _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev;     
.scl    2;      .type   32;     .endef
        .def    __cxa_thread_atexit;    .scl    2;      .type   32;     .endef
        .def   
_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE10_M_replaceEyyPKcy;      
.scl    2;      .type   32;     .endef
        .section       
.rdata$.refptr._ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev, "dr"
        .globl 
.refptr._ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev
        .linkonce       discard
.refptr._ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev:
        .quad   _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev

E:\Desktop>gcc --version
gcc (gcc-7-branch HEAD with MCF thread model, built by LH_Mouse.) 7.1.1
20170518
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


E:\Desktop>
---------------------------------------------
In the case of Windows x64 ABI the first four parameters are passed in
RCX/XMM0, RDX/XMM1, R8/XMM2 and R9/XMM3, respectively.
The third parameter (DSO handle) is R8 and here it is apparently set to zero on
line #43.


More information about the Gcc-bugs mailing list