Skip to content

fix(decorated-window-tao): load GTK with RTLD_LOCAL to stop sqlite interposition#368

Merged
kdroidFilter merged 2 commits into
mainfrom
fix/tao-linux-gtk-rtld-local
Jul 18, 2026
Merged

fix(decorated-window-tao): load GTK with RTLD_LOCAL to stop sqlite interposition#368
kdroidFilter merged 2 commits into
mainfrom
fix/tao-linux-gtk-rtld-local

Conversation

@kdroidFilter

Copy link
Copy Markdown
Collaborator

Summary

  • Fixes Linux: sqlite3 crashing in some cases #366 — SIGSEGV in libsqlite3.so (sqlite3VdbeMemGrow) on Linux when a Room/androidx bundled-sqlite write runs after a Tao decorated window opened (regression 2.0.7 → 2.1.0, NixOS).
  • Root cause: the CSD shadow helper introduced in 2.1.0 (nucleus_tao_linux_shadow.c) dlopen()s GTK with RTLD_GLOBAL at every window creation. On NixOS, GTK3's closure pulls libsqlite3 (gtk3 → tinysparql → sqlite), so the system sqlite enters the global symbol scope. The bundled-sqlite JNI lib binds its sqlite3_* PLT entries lazily: entry points first called after the window opened resolve to the system copy but operate on statements created by the bundled copy → segfault. This is exactly why reads (bound before the window) kept working while writes crashed.
  • Fix: RTLD_GLOBALRTLD_LOCAL for all GTK-family dlopen sites (shadow + widget helpers). Safe: every symbol is fetched via dlsym() on the explicit handles, nothing relies on dlsym(RTLD_DEFAULT), and GTK's own modules link libgtk-3.so via their own DT_NEEDED. nucleus_tao_egl.c/nucleus_tao_linux_popup.c (EGL/GL/X11/wayland — no sqlite in their closures) are deliberately left untouched.
  • Adds an e2e repro to tao-demo (SqliteReproMain.kt + runSqliteRepro task), same pattern as the Sandboxing: make extract-and-load native libraries (System.load from temp) work in store builds without upstream changes #317 probe. The NixOS closure is recreated on any distro with a patched GTK copy:
    mkdir /tmp/gtk-shim && cp /usr/lib/x86_64-linux-gnu/libgtk-3.so.0 /tmp/gtk-shim/
    patchelf --add-needed libsqlite3.so.0 /tmp/gtk-shim/libgtk-3.so.0
    ./gradlew :examples:tao-demo:runSqliteRepro

Test plan

  • E2E repro before fix: crashes with the issue's exact signature — nativeBindText (androidx bundled JNI) → system libsqlite3.so.0 → SIGSEGV in the sqlite allocator
  • E2E repro after fix (natives rebuilt, loader cache cleared): bindText write + read-back succeed, no crash
  • GTK shadow machinery still functional with RTLD_LOCAL in the same process (nativeShadowThemeStamp()Yaru-blue-dark|1)
  • grep RTLD_DEFAULT over native sources: no consumer of the global scope
  • Confirm on reporter's NixOS setup

…mbol interposition

The Linux CSD shadow helper (new in 2.1.0) dlopen()s GTK with RTLD_GLOBAL
at every decorated-window creation. On distros where GTK's dependency
closure includes libsqlite3 (NixOS: gtk3 -> tinysparql -> sqlite), the
system sqlite enters the global symbol scope and lazily-bound sqlite3_*
PLT entries of androidx/Room's bundled-sqlite JNI library resolve to the
system copy from then on. Entry points first called after the window
opened then operate on statements created by the bundled copy and
segfault (SIGSEGV in sqlite3VdbeMemGrow via bindText) — reads bound
before the window kept working, which matched the reported symptom.

Switch every GTK-family dlopen (shadow + widget helpers) to RTLD_LOCAL.
All symbols are fetched via dlsym() on the explicit handles — nothing
uses dlsym(RTLD_DEFAULT) — so no global visibility is needed, and GTK's
own modules link libgtk directly.

Includes an e2e repro (SqliteReproMain.kt + runSqliteRepro task): recreate
the NixOS closure on any distro with a patchelf'ed libgtk-3.so.0 that adds
libsqlite3.so.0 as DT_NEEDED, open a bundled-sqlite DB and read before the
window, then bindText-write after it. Crashes with RTLD_GLOBAL, passes
with RTLD_LOCAL while the shadow theme stamp stays functional.

Fixes #366
…gression test

Replaces the manual runSqliteRepro task (hardcoded /tmp shim path) with a
JUnit test: it builds the patched-GTK shim itself in a temp dir (patchelf
--add-needed libsqlite3.so.0), forks a JVM on the repro main — a SIGSEGV
kills the whole process, so the outcome must be observed from outside —
and asserts exit 0, a functional GTK shadow theme stamp (guards against a
vacuous pass where GTK never loaded) and the completed write.

Skips instead of failing wherever the scenario can't run: non-Linux, no
DISPLAY/WAYLAND_DISPLAY, no patchelf, no system libgtk-3/libsqlite3.
Verified both ways locally: passes with RTLD_LOCAL natives, fails with
RTLD_GLOBAL ones.
@kdroidFilter
kdroidFilter force-pushed the fix/tao-linux-gtk-rtld-local branch from d4957c9 to 6d27d3a Compare July 18, 2026 18:21
@kdroidFilter
kdroidFilter merged commit 57db5cc into main Jul 18, 2026
22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Linux: sqlite3 crashing in some cases

1 participant