Skip to content

android: fixed-point preload to resolve transitive .so deps#343

Open
leaiss wants to merge 1 commit into
mainfrom
fix/android-preload-fixed-point
Open

android: fixed-point preload to resolve transitive .so deps#343
leaiss wants to merge 1 commit into
mainfrom
fix/android-preload-fixed-point

Conversation

@leaiss
Copy link
Copy Markdown
Collaborator

@leaiss leaiss commented May 27, 2026

Summary

Regression fix on top of PR #333. The preload loop in target_plugin_loader.c did a single readdir pass — fine if the filesystem visited dependency-leaves first, broken if it didn't. The current CNSDK bundle's deps are: libdxrp050 → libleiaSDK → libblink → libSNPE + liblicense_utils. When readdir visits libblink before liblicense_utils, libblink's preload fails (its DT_NEEDED for liblicense_utils can't resolve in the namespace yet), libleiaSDK fails (needs libblink), and libdxrp050_leia_cnsdk.so ultimately fails to dlopen with:

dlopen failed: library \"libleiaSDK-faceTrackingInApp.so\" not found:
  needed by .../libdxrp050_leia_cnsdk.so in namespace clns-7.

This regression silently broke the validation chain on Android-36 emulator — xrCreateInstance returned XR_ERROR_INITIALIZATION_FAILED instead of the previously-validated XR_SUCCESS.

Fix

Iterate the preload loop until a full pass loads nothing new. Worst case O(N²) dlopen attempts for N libs, but N is small (~16) and dlopen of an already-loaded soinfo is essentially free. After fixed-point, any libs still unloaded get logged at WARN with their last dlerror — useful for diagnosing genuinely broken deps vs. ordering issues.

Some SNPE DSP .so files always fail on non-Qualcomm hardware (libcdsprpc.so missing, or 32-bit Skel files); they're never reached at runtime on the main load path, so they're noise in the report rather than blockers.

Verification

Android-36 x86_64 emulator (arm64 binary translation), runtime APK + leia-cnsdk plug-in (post bundle-transitive) + cube_handle_vk_android test app:

Step Before this PR After this PR
Runtime broker resolves
Runtime dlopen
Plug-in libdxrp050_leia_cnsdk.so dlopen ❌ libleiaSDK not found
Plug-in negotiate + probe
xrCreateInstance ❌ XR_ERROR_INITIALIZATION_FAILED ✅ XR_SUCCESS
xrCreateVulkanInstanceKHR ✅ XR_SUCCESS
xrCreateVulkanDeviceKHR ❌ VK_ERROR_EXTENSION_NOT_PRESENT (expected emulator limit)

Same emulator wall as documented in docs/getting-started/android-emulator-setup.md.

Test plan

  • :src:xrt:targets:openxr_android:assembleInProcessDebug builds clean.
  • On Android-36 emulator with the bundled-transitive runtime APK + cube_handle_vk_android, logcat shows preloaded libleiaSDK-faceTrackingInApp.so (etc.) and xrCreateInstance -> XR_SUCCESS.
  • On Lume Pad once it arrives, expectation is the preload list is smaller (system-supplied CNSDK?) but the same fixed-point logic still applies safely.

🤖 Generated with Claude Code

…n lib dir

PR #333's single-pass preload broke once readdir returned candidates
in an order where a dependent .so was visited before its in-bundle
deps. Reproduced on Android-36 emulator with the current CNSDK
bundle (libblink → libSNPE + liblicense_utils):

  dlopen failed: library "libleiaSDK-faceTrackingInApp.so" not found:
    needed by .../libdxrp050_leia_cnsdk.so in namespace clns-7

readdir visited libblink before liblicense_utils → libblink preload
failed (transitive dep not yet in soinfo) → libleiaSDK preload failed
(needs libblink) → libdxrp050 dlopen failed (needs libleiaSDK).
xrCreateInstance regressed to XR_ERROR_INITIALIZATION_FAILED.

Fix: iterate the preload loop until a full pass loads nothing new.
For our dep depth of ~3, two passes converge. Worst case O(N^2)
dlopen attempts for N libs, but N is small (~16) and dlopen of an
already-loaded soinfo is essentially free. Final unloaded libs get
logged at WARN with the last dlerror for diagnosis (some SNPE DSP
.so always fail on non-Qualcomm hardware — libcdsprpc.so missing or
32-bit Skel files — which is fine; they're never reached at runtime
on the emulator/Lume Pad load path).

Verified on Android-36 x86_64 emulator: xrCreateInstance now reaches
XR_SUCCESS again, plug-in leia-cnsdk activates, xrCreateVulkanInstanceKHR
succeeds, xrCreateVulkanDeviceKHR hits the expected emulator
extension-limit (VK_ERROR_EXTENSION_NOT_PRESENT) — the same wall
documented in docs/getting-started/android-emulator-setup.md.
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.

1 participant