diff --git a/desktop/src-tauri/build.rs b/desktop/src-tauri/build.rs index 3584776..e17495c 100644 --- a/desktop/src-tauri/build.rs +++ b/desktop/src-tauri/build.rs @@ -38,14 +38,6 @@ fn build_oboe_android(target: &str) { .file("cpp/getauxval_fix.c") .compile("getauxval_fix"); - // pthread_shim: interpose pthread_create so Rust libstd can't use the - // broken static pthread_create stub (which calls __init_tcb, crashing - // in a .so). Our shim forwards to libc.so's real one via RTLD_NEXT. - // Compiled as its own static lib so the linker links it ahead of libstd. - cc::Build::new() - .file("cpp/pthread_shim.c") - .compile("pthread_shim"); - let oboe_dir = fetch_oboe(); match oboe_dir { Some(oboe_path) => { @@ -112,12 +104,6 @@ fn build_oboe_android(target: &str) { // Oboe requires Android log + OpenSLES backends println!("cargo:rustc-link-lib=log"); println!("cargo:rustc-link-lib=OpenSLES"); - - // Wrap pthread_create: redirect every `pthread_create` reference to our - // `__wrap_pthread_create` in pthread_shim.c, which forwards to the real - // libc.so symbol via dlsym. Without this the linker binds to libstd's - // bundled broken static pthread_create stub (see pthread_shim.c). - println!("cargo:rustc-link-arg=-Wl,--wrap=pthread_create"); } /// Recursively add all .cpp files from a directory to a cc::Build. diff --git a/desktop/src-tauri/cpp/pthread_shim.c b/desktop/src-tauri/cpp/pthread_shim.c deleted file mode 100644 index 8fa5b44..0000000 --- a/desktop/src-tauri/cpp/pthread_shim.c +++ /dev/null @@ -1,80 +0,0 @@ -/* pthread_shim.c - * - * Interpose pthread_create via `--wrap=pthread_create` to bypass Rust libstd's - * broken static pthread_create stub. The stub (from an old bundled libc.a) - * calls __init_tcb+4 and SIGSEGVs in dlopen-loaded .so libraries. - * - * Approach: - * 1. The linker rewrites every `pthread_create` reference inside libstd - * (and everywhere else) into `__wrap_pthread_create` — our function. - * 2. Inside __wrap_pthread_create we call libc.so's real pthread_create - * via dlsym(RTLD_DEFAULT). Because --wrap redirects only references, - * the symbol `pthread_create` itself is NOT defined in our .so, so - * RTLD_DEFAULT finds the one exported by libc.so (always loaded). - * 3. We log every step via __android_log_print so we can diagnose any - * lookup failure from logcat (tag: WZP_pthread_shim). - */ - -#ifdef __ANDROID__ - -#define _GNU_SOURCE -#include -#include -#include -#include -#include - -#define TAG "WZP_pthread_shim" -#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__) -#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__) - -typedef int (*pthread_create_fn)(pthread_t *, const pthread_attr_t *, - void *(*)(void *), void *); - -static pthread_create_fn resolve_real_pthread_create(void) { - /* RTLD_DEFAULT: search the global symbol table starting with the main - * executable (app_process64), then every shared library loaded into the - * process in load order. libc.so is always loaded first, so its - * pthread_create export is the first match — and since we never define - * a symbol literally named "pthread_create" (only __wrap_pthread_create), - * there's no ambiguity. */ - pthread_create_fn fn = (pthread_create_fn)dlsym(RTLD_DEFAULT, "pthread_create"); - if (fn != NULL) { - LOGI("resolved pthread_create via RTLD_DEFAULT at %p", (void *)fn); - return fn; - } - LOGE("dlsym(RTLD_DEFAULT, pthread_create) returned NULL: %s", dlerror()); - - /* Fall back to explicit dlopen of libc.so — bionic is normally happy - * to hand back the already-loaded mapping. */ - void *libc = dlopen("libc.so", RTLD_LAZY | RTLD_NOLOAD); - if (libc == NULL) { - libc = dlopen("libc.so", RTLD_LAZY); - } - if (libc == NULL) { - LOGE("dlopen(libc.so) failed: %s", dlerror()); - return NULL; - } - fn = (pthread_create_fn)dlsym(libc, "pthread_create"); - if (fn == NULL) { - LOGE("dlsym(libc, pthread_create) returned NULL: %s", dlerror()); - return NULL; - } - LOGI("resolved pthread_create via dlopen(libc.so) at %p", (void *)fn); - return fn; -} - -int __wrap_pthread_create(pthread_t *thread, const pthread_attr_t *attr, - void *(*start_routine)(void *), void *arg) { - static pthread_create_fn real = NULL; - if (real == NULL) { - real = resolve_real_pthread_create(); - if (real == NULL) { - LOGE("__wrap_pthread_create: no real pthread_create found, returning EAGAIN"); - return 11; /* EAGAIN — best we can do */ - } - } - return real(thread, attr, start_routine, arg); -} - -#endif /* __ANDROID__ */