-
-
Notifications
You must be signed in to change notification settings - Fork 6.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
cmake: fix unity with Windows Unicode + TrackMemory #11928
Conversation
818f5c5
to
3788015
Compare
So, for one thing, libtests and curl tool wasn't finding libcurl DLL, that was the next issue. After fixing that, the non-unity builds started running as expected, but their unity counterparts kept failing. They run fine locally with wine64, but crash on startup on real Windows with 0xc0000374 (heap corruption) in "StackHash_a77e". [ Unity binaries are also much smaller, but I attribute that to the more concise debug info in the unity builds. Their size become similar after stripping. ] So the next issue is to find what causes these shared/debug unity builds to fail on real Windows. UPDATE: The issue doesn't happen with non-unicode builds: UPDATE 2: The crashing curl tool happens with unicode + debug + unity |
b13738c
to
fe90a01
Compare
I'm about to give up finding the issue, and instead disable UNITY for UPDATE: It was |
"TrackMemory" is `ENABLE_DEBUG=ON` (aka `ENABLE_CURLDEBUG=ON`, aka `-DCURLDEBUG`). There is an issue with memory tracking and Unicode when build in "unity" mode, which results in the curl tool crashing right on startup, even without any command-line option. Interestingly this doesn't happen under WINE (at least on the system I tested this on), but consistenly happens on real Windows machines. Crash is 0xC0000374 heap corruption. Both shared and static curl executables are affected. This limitation probably won't hit too many people, but it remains a TODO to find and fix the root cause and drop this workaround. Example builds and runs: https://ci.appveyor.com/project/curlorg/curl/builds/48169111/job/17cptxhtpubd7iwj#L313 (static) https://ci.appveyor.com/project/curlorg/curl/builds/48169111/job/76e1ge758tbyqu9c#L317 (shared) Follow-up to 3f8fc25 curl#11095 Ref curl#11928 Closes #xxxxx
"TrackMemory" is `ENABLE_DEBUG=ON` (aka `ENABLE_CURLDEBUG=ON`, aka `-DCURLDEBUG`). There is an issue with memory tracking and Unicode when built in "unity" mode, which results in the curl tool crashing right on startup, even without any command-line option. Interestingly this doesn't happen under WINE (at least on the system I tested this on), but consistenly happens on real Windows machines. Crash is 0xC0000374 heap corruption. Both shared and static curl executables are affected. This limitation probably won't hit too many people, but it remains a TODO to find and fix the root cause and drop this workaround. Example builds and runs: https://ci.appveyor.com/project/curlorg/curl/builds/48169111/job/17cptxhtpubd7iwj#L313 (static) https://ci.appveyor.com/project/curlorg/curl/builds/48169111/job/76e1ge758tbyqu9c#L317 (shared) Follow-up to 3f8fc25 #11095 Ref: #11928 Closes #12005
fe90a01
to
d610bf8
Compare
Found the root cause of the startup crash with unity builds with Unicode and TrackMemory enabled at the same time. We must make sure that the `memdebug.h` header doesn't apply to `lib/curl_multibyte.c` (as even noted in a comment there.). In unity builds all headers apply to all sources, including `curl_multibyte.c`. This probably resulted in an infinite loop on startup. This patch excludes this source from unity compilation with TrackMemory enabled, in both libcurl and curl tool. Also delete the earlier workaround that fully disabled unity for affected builds. Also enable unity mode for a debug unicode CI job. Follow-up to d82b080 curl#12005 Follow-up to 3f8fc25 curl#11095 Closes curl#11928
d610bf8
to
144e18a
Compare
|
The way to track this down was not the most obvious. While doing the first tests I added a way to run Then it took a long series of builds to narrow this down the mininum conditions. When this cleared up, I had some guesses where to look, but eyeballing the source didn't help. I was also looking at headers, assuming that these could affect both libcurl and curl, so missed the comment in the affected source file. At this point I created one build with and one without the issue and planned to compare disassembled binaries. For this I had to learn how to tell CMake to use Next I picked the compiler commands from the build logs and re-run them by replacing
Comparing texts this large was a no-go, so picked up the This still had too much noise, so restarted the At this point it was a matter of sifting through the two diffs for
The risk I took to strip The fix itself was trivial, after realizing that we also use |
Sounds like the outline to an unreleased Tom Clancy thriller! ☺
|
Switch from `curl-gnumake.sh` to `curl-cmake.sh` with upcoming curl release v8.5.0. cmake builds are now _faster_ for Windows builds than raw gnumake (aka `Makefile.mk`). They also use 'unity' mode, which makes builds run fast with the side-effect of also creating potentially more efficient binaries by allowing better compiler optimizations. This also makes curl-for-win use the same build system for all target platforms (`Makefile.mk` is not available for *nix platforms). Initially on 2022-07-04 cmake was 25% slower than gnumake. By 2022-09-26 this reduced to 20%, by 2023-07-29 to 18% and after the latest round of updates gnumake came out 7% slower than cmake. This is for Windows, for a triple x64, arm64 and x86 build. In absolute times this is 27m22s for cmake and 29m11s for gnumake. (FWIW autotools builds are 52% slower than cmake unity builds now.) Making cmake builds fast was a multi-year effort with these major steps: 1. add support for cmake builds in curl-for-win. 420e73c 2. bring it in-line with gnumake and autotools builds and tidy-up as much as possible. Scattered to a many commits. 3. delete a whole bunch of unused feature detections. curl/curl@4d73854 curl/curl#9044 (and a lot more smaller commits) 4. speed up picky warning option initialization by avoiding brute-force all options. (first in libssh2, then in curl, then applied also ngtcp2, nghttp3, nghttp2) curl/curl@9c543de curl/curl#10973 5. implement single build run for shared and static libcurl + tool (first in libssh2) curl/curl@1199308 curl/curl#11505 53dcd49 6. implement single build pass for shared and static libcurl (for Windows initially) curl/curl@2ebc74c curl/curl#11546 7. extend above to non-Windows (e.g. macOS) curl/curl@fc9bfb1 curl/curl#11627 bafa77d (mac) 1b27304 (linux) 8. implement unity builds: single compiler invocation for libcurl + tool curl/curl@3f8fc25 curl/curl#11095 curl/curl@f42a279 curl/curl#11928 67d7fd3 9. speed up 4x the cmake initialization phase (for Windows) curl/curl@2100d9f curl/curl#12044 10. speed up cmake initialization even more by pre-filling detection results for our well-known mingw-w64 environments. 74dd967 5a43c61 +1: speed up autotools initialization by mitigating a brute-force feature detection on Windows. This reduced total build times by 5 minutes at the time, for the 3 Windows targets in total. curl/curl@6adcff6 curl/curl#9591 Also update build times for cmake-unity and gnumake, based on runs: cmake-unity: https://ci.appveyor.com/project/curlorg/curl-for-win/builds/48357875 gnumake: https://ci.appveyor.com/project/curlorg/curl-for-win/builds/48358005
Also adjust `()` around low-level calls preventing macro overrides via e.g. `memdebug.h`: - add for `malloc` and `free`. - drop for `_open`. (We do not override `_open` in curl.) Tidy-up: also sync libcurlu custom macro order in cmake with autotools. Follow-up to f42a279 curl#11928 Closes curl#16742
Also adjust `()` around low-level calls preventing macro overrides via e.g. `memdebug.h`: - add for `malloc` and `free`. - drop for `_open`. (We do not override `_open` in curl.) Tidy-up: also sync libcurlu custom macro order in cmake with autotools. Follow-up to f42a279 curl#11928 Closes curl#16742
Found the root cause of the startup crash in unity builds with Unicode
and TrackMemory enabled at the same time.
We must make sure that the
memdebug.h
header doesn't apply tolib/curl_multibyte.c
(as even noted in a comment there.) In unitybuilds all headers apply to all sources, including
curl_multibyte.c
.This probably resulted in an infinite loop on startup.
Exclude this source from unity compilation with TrackMemory enabled,
in both libcurl and curl tool. Enable unity mode for a debug Unicode
CI job to keep it tested. Also delete the earlier workaround that
fully disabled unity for affected builds.
Follow-up to d82b080 #12005
Follow-up to 3f8fc25 #11095
Closes #11928
Crashing on startup example:
https://ci.appveyor.com/project/curlorg/curl/builds/48113110/job/3ou611asxeop6uvi#L2522