[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