fix(android): drop staticlib from crate-type — root cause of __init_tcb crash
Some checks failed
Mirror to GitHub / mirror (push) Failing after 42s
Build Release Binaries / build-amd64 (push) Failing after 3m47s

External research (per rust-lang/rust#104707) pointed at this as the
highest-probability cause of our byte-identical __init_tcb+4 /
pthread_create SIGSEGVs:

> Having 'staticlib' alongside 'cdylib' in crate-type leaks non-exported
> symbols from the staticlib into the cdylib's symbol table. For a
> Tauri Android cdylib, that means bionic's private pthread_create /
> __init_tcb code — which got pulled in statically from libc.a the
> moment any cc::Build C++ file added C++-linkage overhead — ends up
> bound LOCALLY inside our .so instead of being resolved dynamically
> against libc.so at dlopen time.

Symptoms that match the theory exactly:
- llvm-nm on the crashing .so shows __init_tcb and pthread_create as
  LOCAL symbols with C++ name mangling (bionic's own pthread_create.cpp)
- Adding any cc::Build cpp(true) step reliably triggers the crash,
  independent of which linker (android24-clang vs android26-clang) or
  which libc++ linkage (shared/static/none)
- The legacy wzp-android crate (["cdylib", "rlib"]) works fine on the
  same phone with the same NDK + Rust toolchain + Oboe C++ code
- tauri.conf.json bundle.android.minSdkVersion=26 propagates to
  gradle but the .so still crashes byte-identically

Drop 'staticlib' from crate-type. If we ever need it for iOS, re-add
behind a target.'cfg(target_os = "ios")' gate. The desktop binary
still links against the rlib, so the bin target on macOS/Linux/Windows
is unaffected.

Source: https://github.com/rust-lang/rust/issues/104707

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Siavash Sameni
2026-04-09 17:38:49 +04:00
parent c9cd043657
commit 6071eb1b02

View File

@@ -7,9 +7,21 @@ default-run = "wzp-desktop"
# Library target — required for Tauri mobile (Android/iOS link the app as a cdylib)
# and also used by the desktop binary below.
#
# `staticlib` was DROPPED from crate-type because rust-lang/rust#104707
# documents that having staticlib alongside cdylib leaks non-exported
# symbols from staticlibs into the cdylib. Bionic's private `__init_tcb`
# / `pthread_create` symbols end up bound LOCALLY inside our .so instead
# of resolved dynamically against libc.so at dlopen time — which crashes
# at launch as soon as tao tries to std::thread::spawn() from the JNI
# onCreate callback. The legacy wzp-android crate uses ["cdylib", "rlib"]
# and runs fine on the same phone with the same NDK + Rust toolchain.
#
# iOS Tauri builds that actually need staticlib can re-add it behind a
# target cfg if we ever ship on iOS.
[lib]
name = "wzp_desktop_lib"
crate-type = ["staticlib", "cdylib", "rlib"]
crate-type = ["cdylib", "rlib"]
[[bin]]
name = "wzp-desktop"