Bisection for the __init_tcb+4 crash that Step E introduced: drop the
full Oboe C++ build (200+ files, hundreds of KB of code) and replace
it with ONE tiny cpp/cpp_smoke.cpp that exercises the libc++ features
Oboe uses — std::atomic, std::mutex, std::thread — via an
extern "C" wzp_cpp_smoke() function that's exported but NEVER called
from Rust.
Still compiled with cpp_link_stdlib("c++_shared"), same as Oboe.
libc++_shared.so still copied into gen/android jniLibs. But no Oboe
headers, no Oboe source files, no -llog / -lOpenSLES links.
Hypothesis: if cpp_smoke.cpp alone reproduces the __init_tcb crash,
the trigger is "any libc++_shared link that references
std::thread/std::mutex" and Oboe is not the specific culprit. If it
launches cleanly, Oboe itself (its size, its static constructors, or
a specific header) is responsible — and we then bisect Oboe's
source tree.
fetch_oboe() and add_cpp_files_recursive() are retained in build.rs
with #[allow(dead_code)] so re-enabling the full Oboe compile is a
one-line edit once we've identified what's safe to include.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
31 lines
1.1 KiB
C++
31 lines
1.1 KiB
C++
// cpp_smoke.cpp — minimal C++ test that exercises the libc++_shared
|
|
// features Oboe uses (std::thread, std::mutex, std::atomic) without being
|
|
// Oboe itself.
|
|
//
|
|
// Built via cc::Build::new().cpp(true).cpp_link_stdlib("c++_shared") and
|
|
// replaces the full Oboe bridge compile during the Step E bisection of
|
|
// the __init_tcb+4 crash. The function is `extern "C"` and exported so
|
|
// the linker can't dead-code-eliminate it — the std::thread /
|
|
// std::lock_guard / std::atomic::fetch_add uses pull in libc++'s
|
|
// bindings to bionic pthread, matching what Oboe would force.
|
|
//
|
|
// The function is NEVER called from Rust. If we crash anyway, the trigger
|
|
// is just *linking* this code in. If it launches cleanly, Oboe itself
|
|
// (size, static ctors, specific headers) is the culprit.
|
|
|
|
#include <atomic>
|
|
#include <mutex>
|
|
#include <thread>
|
|
|
|
namespace {
|
|
std::atomic<int> g_counter{0};
|
|
std::mutex g_mutex;
|
|
}
|
|
|
|
extern "C" int wzp_cpp_smoke(void) {
|
|
std::lock_guard<std::mutex> lock(g_mutex);
|
|
std::thread t([]() { g_counter.fetch_add(1); });
|
|
t.join();
|
|
return g_counter.load();
|
|
}
|