Skip to content

DO NOT MERGE: test a MultiSSL libcurl (curl[openssl]) on Windows arm64 - #6755

Closed
Fedr wants to merge 26 commits into
masterfrom
ci/arm64-curl-openssl-repro
Closed

DO NOT MERGE: test a MultiSSL libcurl (curl[openssl]) on Windows arm64#6755
Fedr wants to merge 26 commits into
masterfrom
ci/arm64-curl-openssl-repro

Conversation

@Fedr

@Fedr Fedr commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Throwaway CI experiment — do not merge.

MeshLib's Windows arm64 legs run MRViewer.CPRTestGet/CPRTestPost on every PR and they pass, because plain cpr gets a Schannel-only libcurl:

[info] libcurl version: libcurl/8.21.0 Schannel zlib/1.3.2
[info] libcurl SSL backend [0]: schannel (id=8)
[  OK  ] MRViewer.CPRTestGet (241 ms)

A downstream Windows app appends curl[openssl] to the same requirements file, which makes vcpkg build a MultiSSL libcurl (OpenSSL/3.6.3 (Schannel), backends openssl + schannel). With that build, arm64 crashes with an access violation reading 0x879 inside cpr::Session::Get on the first HTTPS request; the identical x64 build is fine, and forcing the Schannel backend at runtime does not help — so the suspect is the MultiSSL backend dispatch on arm64 rather than OpenSSL's TLS code.

This branch adds curl[openssl] to requirements/windows.txt to see whether the crash follows the MultiSSL libcurl into MeshLib's own arm64 MRTest.

Scope trimming (throwaway, so the leg is cheap):

  • Windows minimal matrix reduced to the two arm64 vs2026 legs.
  • skip-image-rebuild so the requirements/windows.txt change does not fire the four-triplet windows-vcpkg-build-upload prepare job; the build jobs install their own deps with --write-s3.
  • All non-Windows platforms disabled by label.

Expected outcome: MRViewer.CPRTestGet crashes/fails on arm64 → confirms MultiSSL libcurl as the cause and makes MeshLib the minimal reproducer. If it passes, something outside libcurl's feature set is at fault.

Adds curl[openssl] to the Windows vcpkg requirements, which makes vcpkg
build libcurl with both OpenSSL and Schannel (MultiSSL) instead of the
Schannel-only default, and trims the Windows minimal matrix to the two
arm64 legs so only that configuration is exercised.

Purpose: a downstream Windows app that requests curl[openssl] crashes
with an access violation inside cpr::Session::Get on the first HTTPS
request on arm64 only, while MeshLib's Schannel-only arm64 build passes
MRViewer.CPRTestGet/CPRTestPost. This branch checks whether the crash
follows the MultiSSL libcurl into MeshLib.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Fedr and others added 7 commits September 2, 2026 11:33
Adds a raw-libcurl gtest (no cpr, every step logged, curl verbose trace
through spdlog) and a verbose cpr session test, then runs each of them
in its own process, with and without CURL_SSL_BACKEND=schannel, and
copies vcpkg's PDBs next to the binaries so the crash stack resolves to
function and line instead of nearest export.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The default handler prints only the faulting data address, and unwinding
through OpenSSL's arm64 code fails (no libssl/libcrypto frames appear at
all), so the stack has been useless. A vectored handler now reports the
faulting PC as module+RVA, every general register, and the module+RVA of
every return-address-looking word near SP. Adds a raw-libcurl variant
that sets CURLSSLOPT_NATIVE_CA, and runs each probe in its own process.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
vcpkg already ships debug libssl/libcrypto in the same package, so the
release/debug question needs no rebuild: back up the release DLLs, drop
the debug ones (plus the debug CRT they need) next to the binaries, and
rerun the raw libcurl request. If it passes, the defect is
optimization-dependent codegen rather than OpenSSL logic.

The fault handler now also prints the module's PE timestamp/size and the
nine instructions around the faulting PC, so the running code can be
matched against an offline disassembly with certainty.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
scripts/arm64_openssl_mre.c is ~90 lines of C against libssl/libcrypto
only - no curl, no cpr, no C++: open a TLS 1.3 client connection and
report where it dies, printing the faulting instruction as module+RVA and
the bogus x0. The CI step compiles it with cl /O2 and runs it twice in the
same directory, first against the release OpenSSL DLLs and then against
the debug ones, so one log shows both outcomes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The reproducer needs OpenSSL headers, import libs and DLLs - nothing
else - so building MeshLib first (submodules, vcpkg restore, MRBind, the
whole CMake build, ~25 min) to reach it was pure waste. The new workflow
downloads the prebuilt arm64 OpenSSL package straight from the vcpkg
binary cache, compiles the reproducer with cl /O2 and runs it twice.
@Fedr

Fedr commented Sep 2, 2026

Copy link
Copy Markdown
Contributor Author

Done with this branch: it was only ever a diagnostic, and it answered the question.

The arm64 crash is not a MeshLib, cpr, curl or MultiSSL problem. It is an MSVC ARM64 code-generation defect: at /O2 /Gs0 the prologue calls bl __chkstk before spilling the link register, so tls_parse_all_extensions returns into its own prologue, wrecks sp on the way, and faults reading 0x879. OpenSSL is exposed because its VC-WIN64-ARM configuration passes /Gs0; -O1 and -Od produce a correct prologue.

Reported, with a ~25-line reproducer:

Nothing here is mergeable - the curl[openssl] line, the throwaway workflows and the debug instrumentation all existed to reproduce and bisect. The two files worth keeping, if this comes up again, are scripts/arm64_prologue_repro.c (the compiler reproducer) and scripts/arm64_openssl_mre.c (a ~30-line libssl client that crashes against an /O2 OpenSSL and completes the handshake against -O1).

@Fedr Fedr closed this Sep 2, 2026
@Fedr
Fedr deleted the ci/arm64-curl-openssl-repro branch September 2, 2026 13:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant