https://bugs.winehq.org/show_bug.cgi?id=53912
Bug ID: 53912 Summary: Static initialization in Winelibs may hang the loader as of Wine 7.21 Product: Wine Version: 7.21 Hardware: x86-64 OS: Linux Status: UNCONFIRMED Severity: normal Priority: P2 Component: winelib Assignee: wine-bugs@winehq.org Reporter: mail@robbertvanderhelm.nl Distribution: ---
Static initialization in Winelibs may cause the loader to stall as of Wine 7.21. Compiling the below file using `wineg++ -o main main.cpp -m64 -mwindows` and then running `./main.exe` will hang indefinitely. I noticed that this happens with LoadCursor(). Other functions may be affected similarly.
#include <windows.h>
static const HCURSOR arrow_cursor = LoadCursor(nullptr, IDC_ARROW);
int main(int argc, char* argv[]) { return 0; }
https://bugs.winehq.org/show_bug.cgi?id=53912
Fabian Maurer dark.shadow4@web.de changed:
What |Removed |Added ---------------------------------------------------------------------------- Keywords| |regression CC| |dark.shadow4@web.de
--- Comment #1 from Fabian Maurer dark.shadow4@web.de --- It does work in wine-7.20? Can you do a regression test to find the commit that broke it?
https://bugs.winehq.org/show_bug.cgi?id=53912
--- Comment #2 from Robbert van der Helm mail@robbertvanderhelm.nl --- It does work in Wine 7.20 and anything before that, yes. I found out about it after I got reports of yabridge hanging indefinitely with Wine 7.21 (or actually a wine-tkg build based on Wine Staging commit cf32a7092b75d847b9f5608fbdad45a4636bbfe9), and I tracked that down to this line of code: https://github.com/robbert-vdh/yabridge/blob/8c1679a034d8a381a07af0ec5c89e24...
I just did a bisect and it seems like this is the problematic commit: https://github.com/wine-mirror/wine/commit/1d1690782b167f3ea24990c260665f71a...
https://bugs.winehq.org/show_bug.cgi?id=53912
Austin English austinenglish@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Regression SHA1| |1d1690782b167f3ea24990c2606 | |65f71a0e70d1c CC| |julliard@winehq.org
https://bugs.winehq.org/show_bug.cgi?id=53912
--- Comment #3 from Robbert van der Helm mail@robbertvanderhelm.nl --- To add I found another situation where this happens but I'm having trouble finding a simple minimal reproducer for it. I tracked it down to the below line of code, but the weird thing is that it only happens with unity builds. That's where Meson concatenates all .cpp files and compiles them as one whole. I can confirm that reverting 1d1690782b167f3ea24990c260665f71a0e70d1c also fixes the issue in this case.
https://github.com/robbert-vdh/yabridge/blob/2b00b7094be113cdc8a1ffef7473ada...
In case it's helpful for debugging, the `yabridge-host.exe.so` binary from the `yabridge-5.0.0.tar.gz` on this release page is affected by this regression in both ways: https://github.com/robbert-vdh/yabridge/releases/tag/5.0.0
https://bugs.winehq.org/show_bug.cgi?id=53912
--- Comment #4 from Robbert van der Helm mail@robbertvanderhelm.nl --- Anything I can do to help fix this? I'd dive in myself but I don't know nearly enough about these parts of Wine's internals to be able to easily trace down the race condition. Or just some pointers on where to start poking around would also be appreciated. This has been a bit inconvenient for certain yabridge users (https://github.com/robbert-vdh/yabridge) since downgrading to Wine (Staging) 7.20 is somewhat involved when using the WineHQ repos on Ubuntu/Debian.
https://bugs.winehq.org/show_bug.cgi?id=53912
Fabian Maurer dark.shadow4@web.de changed:
What |Removed |Added ---------------------------------------------------------------------------- Ever confirmed|0 |1 Keywords| |testcase Severity|normal |major Status|UNCONFIRMED |NEW
--- Comment #5 from Fabian Maurer dark.shadow4@web.de --- I don't think there's something you can do, just wait. Should be fixed in the upcoming code freeze, it's kinda important IMHO.
https://bugs.winehq.org/show_bug.cgi?id=53912
Jonathan Romano jonathan@luxaritas.com changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |jonathan@luxaritas.com
https://bugs.winehq.org/show_bug.cgi?id=53912
--- Comment #6 from Robbert van der Helm mail@robbertvanderhelm.nl --- Any chance this could get fixed before 8.0? (which will probably live on in distro repos for quite some time)
https://bugs.winehq.org/show_bug.cgi?id=53912
--- Comment #7 from Alexandre Julliard julliard@winehq.org --- This should be fixed in 8.0-rc1, provided that the binaries are recompiled. The recompiled binaries should also work fine on older Wine.
https://bugs.winehq.org/show_bug.cgi?id=53912
--- Comment #8 from Robbert van der Helm mail@robbertvanderhelm.nl --- Only just got around to testing this. While the example I posted in the OP now compiles and runs fine, it seems like things still very much broken. Running the yabridge-host.exe binary from https://github.com/robbert-vdh/yabridge results in an immediate stack overflow before the main function is executed, so there's likely still an issue with static initialization somewhere. This happens both with older binaries compiled with older Wine version, as well as with a fresh binary compiled with Wine 8.0 rc1. And both with and without the workarounds for the bugs in Wine 7.21 and 7.22. If you want to test this, run/compile version 5.0.0 to get the version without any workarounds.
https://bugs.winehq.org/show_bug.cgi?id=53912
--- Comment #9 from Robbert van der Helm mail@robbertvanderhelm.nl --- Okay, here's another minimal program that immediately causes a segfault when run:
#include <iostream>
int main(int argc, char *argv[]) { std::cerr << argc << std::endl; }
Compile and run this with `wineg++ -o main -m64 -mwindows main.cpp` (also happens without the explicit -m64 -mwindows). The equivalent program with printf instead of iostreams doesn't cause a segfault.
https://bugs.winehq.org/show_bug.cgi?id=53912
Sergei Petrosian panpetrosian@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |panpetrosian@gmail.com
https://bugs.winehq.org/show_bug.cgi?id=53912
--- Comment #10 from Alexandre Julliard julliard@winehq.org --- Part of the fix was missing on 64-bit, df31d3c7fe6365f0fc4098487311e93e186b0417 should help.
https://bugs.winehq.org/show_bug.cgi?id=53912
--- Comment #11 from Robbert van der Helm mail@robbertvanderhelm.nl --- I just built Wine from 17e5ff74308f41ab662d46f684db2c6023a4a16b and the issue remains the same. Both the example program I posted above and yabridge trigger a memory error with 64-bit Wine. I also tried compiling 32-bit versions of both with -m32 since you mentioned that a fix should already be in place for that, but those versions crash in the exact same way for me.
https://bugs.winehq.org/show_bug.cgi?id=53912
--- Comment #12 from Alexandre Julliard julliard@winehq.org --- Did you rebuild the binaries with latest Wine? If so, can you please mail me a binary that doesn't work for you?
https://bugs.winehq.org/show_bug.cgi?id=53912
--- Comment #13 from Robbert van der Helm mail@robbertvanderhelm.nl --- I did. Or at least, I tried to. I changed my search PATH so that the built Wine binaries and tools were in there, symlinked ../winebuild/winebuild in the tools/winegcc directory since it always looks for winebuild relative to the winegcc/wineg++ binary, and compiled the binaries with build-64/tools/winegcc/wineg++ (and the same thing in my 32-bit+wine64 build directory). This is the binary it produced (no idea if there's a way to verify that it actually used the correct stack and not my system wide Wine installation):
https://gist.github.com/robbert-vdh/601eb097d116406a7184af3a9ac4561d
https://bugs.winehq.org/show_bug.cgi?id=53912
--- Comment #14 from Alexandre Julliard julliard@winehq.org --- Yes, it was built with the correct winebuild, thanks! I'll have a look.
https://bugs.winehq.org/show_bug.cgi?id=53912
--- Comment #15 from Alexandre Julliard julliard@winehq.org --- It seems to have been using the wrong libwinecrt0 though. You may want to do a make install to a temp dir and run winegcc from there to make sure it picks up the right libraries.
https://bugs.winehq.org/show_bug.cgi?id=53912
--- Comment #16 from Robbert van der Helm mail@robbertvanderhelm.nl --- I grabbed the wine-git AUR package and replaced my system Wine with a build from commit g17e5ff74308. Using that Wine toolchain the hello world program compiles and runs as expected again. I also compiled both yabridge 5.0.0 (from before I added any workarounds for Wine 7.21/7.22, and with the unity builds I had to disable later enabled) and yabridge 5.0.2 (with all the workarounds in place).
Interestingly the 5.0.0 version without any workarounds also runs under Wine 7.21 and 7.22. I tested the binaries with Wine versions as far back as 5.10 and they also seem to work fine, so that's great. I'll revert the changes in a new release and publish updated builds built with Wine 8.0-rc2 once that gets released. Hopefully these mandatory rebuilds with specific Wine versions won't cause distro packagers too much trouble heh.
https://bugs.winehq.org/show_bug.cgi?id=53912
Alexandre Julliard julliard@winehq.org changed:
What |Removed |Added ---------------------------------------------------------------------------- Resolution|--- |FIXED Status|NEW |RESOLVED
--- Comment #17 from Alexandre Julliard julliard@winehq.org --- Yes, having to rebuild is annoying, but other attempts at fixing that in ntdll didn't work out unfortunately. Hopefully this approach will be more future-proof, since the constructor support is embedded in the .dll.so file and no longer relies on ntdll.
https://bugs.winehq.org/show_bug.cgi?id=53912
Alexandre Julliard julliard@winehq.org changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |CLOSED
--- Comment #18 from Alexandre Julliard julliard@winehq.org --- Closing bugs fixed in 8.0-rc2.