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>