From 6071eb1b02c8c370fade82447534cf135dddb4d1 Mon Sep 17 00:00:00 2001 From: Siavash Sameni Date: Thu, 9 Apr 2026 17:38:49 +0400 Subject: [PATCH] =?UTF-8?q?fix(android):=20drop=20staticlib=20from=20crate?= =?UTF-8?q?-type=20=E2=80=94=20root=20cause=20of=20=5F=5Finit=5Ftcb=20cras?= =?UTF-8?q?h?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- desktop/src-tauri/Cargo.toml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/desktop/src-tauri/Cargo.toml b/desktop/src-tauri/Cargo.toml index eed2e1a..61f60e6 100644 --- a/desktop/src-tauri/Cargo.toml +++ b/desktop/src-tauri/Cargo.toml @@ -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"