在 2020/10/8 22:56, Jason Merrill 写道:
> 
> Hmm, why isn't the mingw implementation used for all programs?  That would 
> avoid the bug.
> 

There was a little further discussion about this [1].

TL;DR: The mingw-w64 function is linked statically and subject to issues about 
order of destruction.

Recently mingw-w64 has got its own `__cxa_thread_atexit()` so libstdc++ no 
longer exposes it. This patch for libstdc++ fixes
calling conventions for destructors on i686 so they match mingw-w64 ones.


[1] https://github.com/msys2/MINGW-packages/issues/7096

[2] Below is a direct quote from #mingw-w64 on OFTC:
    (lh_ideapad is me and wbs is Martin Storsjö.)

```
[14:29:32] <lh_ideapad> wbs, what was the rationale for the `__thiscall` 
convention for `__cxa_thread_atexit()` and
`__cxa_atexit()` in our CRT? I suspect it is correct, but it is not specified 
anywhere in Itanium ABI.
[14:30:41] <lh_ideapad> In case of evidence for that, the GCC prototype (with 
default __cdecl) should be wrong.
[14:31:10] <lh_ideapad> See this:  
https://github.com/msys2/MINGW-packages/issues/7096
[14:52:05] <wbs> lh_ideapad: itanium ABI doesn't really talk about windows 
things, but, the function that is passed to
__cxa_thread_atexit is the object's destructor function, and when calling the 
destructor, which is technically a member
function, it's done with the thiscall calling convention
[14:52:31] <wbs> lh_ideapad: example: https://godbolt.org/z/qbfWT1 (only clang 
as there's no gcc-mingw there, but if you try
the same there you'll see the same thing)
[14:52:35] <minifox> Title: Compiler Explorer (at godbolt.org)
[14:52:58] <wbs> lh_ideapad: the destruct function shows that when calling 
__ZN7MyClassD1Ev, the destructor, it passes the
object pointer in ecx, i.e. thiscall
[14:53:42] <wbs> lh_ideapad: and when adding the object to the cleanup list, 
the __ZN7MyClassD1Ev function is passed
directly to ___cxa_thread_atexit, which then will need to call the function 
using the thiscall convention
[14:59:54] <wbs> lh_ideapad: so yes, I would agree with your patch changing 
libsupc++ to use thiscall
[15:13:01] <lh_ideapad> gcc is doing the same thing with a wrong calling 
convention , leaving a garbage value on
i686-w64-mingw32.
[15:13:38] <wbs> yup, so definite +1 on your libsupc++ patch for that
[15:14:00] <lh_ideapad> then how about `__cxa_atexit`?
[15:14:26] <wbs> I would say it should work the same, but gcc doesn't normally 
use that one, right?
[15:14:29] <lh_ideapad> it's not used by GCC (the standard `atexit()` is used).
[15:15:26] <wbs> clang has a flag -fuse-cxa-atexit, which makes it use 
cxa_atexit instead of atexit
[15:15:40] <lh_ideapad> I was a bit dubious on it.
[15:18:59] <lh_ideapad> GCC has `-fuse-cxa-atexit` too .  Let me check.
[15:18:59] <wbs> (I tested it), clang does use __cxa_atexit if the 
-fuse-cxa-atexit flag is used, and then the dtor
(thiscall) is passed directly to __cxa_atexit, so that's +1 datapoint to that 
it should have thiscall. gcc doesn't use
__cxa_atexit for i686 windows despite -fuse-cxa-atexit, so that's no points in 
either direction
[15:19:28] <wbs> both clang and gcc use a wrapper function that fixes the 
calling convention, when using atexit at least
[15:20:22] <lh_ideapad> `-fuse-cxa-atexit` seems to have no effect on 
`i686-w64-mingw32-g++`.
[15:20:46] <wbs> exactly. so in practice it doesn't matter for gcc, but I think 
libsupc++ should handle it the same
[15:23:11] <lh_ideapad> ok I will compose a new patch for both functions later 
today.
[15:23:13] <lh_ideapad> :)
[15:23:25] <wbs> \o/
[15:24:40] <wbs> then for the other issue that the user was posting about; I 
remember testing and noticing that the
mingw-w64-crt implementation of __cxa_thread_atexit doesn't work with emutls, 
but in all of my tests, it has been a
non-issue as it has ended up using the libsupc++ code instead
[15:50:50] <lh_ideapad> probably static linking is broken, so one must link 
against shared libstdc++.
[15:52:20] <lh_ideapad> it doesn't matter whether it is the CRT or libsupc++ 
implementation that is linked statically.
[15:53:13] <wbs> it seems like current msys builds of libstdc++ doesn't include 
__cxa_thread_atexit in libstdc++ at all. I'm
pretty sure I tested this back when I made the mingw version, but I'll 
investigate and try to pinpoint what changed (did gcc
at some point start noticing that mingw-w64-crt contains it and stop providing 
their own?) or whether I just missed
something when I tested it back when I wrote it...
[15:59:47] <wbs> I'll follow up on that other issue and mingw bugtracker issue, 
but I'll do a couple hours of comple
testing/studying things first to be able to give an informed comment
[16:15:34] * pamaury (~pama...@ip-41.net-89-3-53.rev.numericable.fr) has joined
[16:27:34] <lh_ideapad> wbs, there is a check in `libstdc++-v3/configure.ac` 
around line 275.
[16:29:22] <wbs> lh_ideapad: yeah, but in my tests it doesn't pick up on it. I 
test by cross-bootstrapping a toolchain, so
maybe this check runs before the mingw-w64-crt actually is built
[16:29:50] <wbs> so it doesn't detect if just bootstrapping once, but if 
building a new gcc in an already complete
environment, it behaves differently
[16:33:21] * Pali (~p...@0001caa5.user.oftc.net) has joined
[16:34:52] <wbs> ah, here it is:
[16:34:52] <wbs> # Only do link tests if native. Else, hardcode.
[16:34:52] <wbs> if $GLIBCXX_IS_NATIVE; then
```





-- 
Best regards,
LH_Mouse

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to