Skip to content

„Native crashes (SIGSEGV/SIGBUS/SIGABRT) in libarcore_c.so on Samsung Galaxy A56 / Android 16 — finalizer destroy + worker-thread + free #1769

Description

@RGregat

SPECIFIC ISSUE ENCOUNTERED

Over several field-test sessions of an ARCore app on a single Samsung Galaxy A56 (Android 16) we collected 8 native tombstones, all crashing in libarcore_c.so (identical BuildId
15fc3723f0012d756162123aa00372fd). They are not one crash but three related native memory-safety failure modes:

1) Native-peer destruction during GC reclamation (5 of 8) — SIGBUS / SIGSEGV.
When the Java GC reclaims an ARCore wrapper object, the native *_destroy / *_close runs against a corrupted or already-freed native handle:

  • com.google.ar.core.Frame.finalizeArFrame_destroySIGBUS, PC jumps to garbage 0x10000005e
  • com.google.ar.core.HitResult.finalizeArHitResult_destroySIGBUS, PC → 0x100000061
  • NativeAllocationRegistry$CleanerThunk.runSIGBUS, PC → 0x10000005e
  • android.hardware.camera2.impl.CameraMetadataNative.finalizeCameraMetadata_closeSIGSEGV (null) — camera metadata finalized with an invalid handle, in the camera2 path ARCore drives (×2)

The near-identical garbage PCs across the SIGBUS cases (0x10000005e / 0x100000061) point to the same corrupted-function-pointer / freed-object signature.

2) Crash inside ARCore's own worker threads (2 of 8) — SIGSEGV.
Pure libarcore_c.so null / near-null dereferences, no app or finalizer frame:

  • thread ms_depth → SIGSEGV, fault addr 0x168 (member access off a null base)
  • thread MTC_mapping → SIGSEGV (null)

3) Heap corruption detected on free (1 of 8) — SIGABRT.
The allocator aborts during free called from libarcore_c.so on the main thread: "Pointer tag for 0x… was truncated" — a double-free / overflow in ARCore native memory.

All occur during normal ARCore use; none is reachable or fixable from app code (we never call these destroy functions — they run on the GC finalizer/cleaner threads or inside ARCore's own threads). The device
has pointer tagging enabled (PR_TAGGED_ADDR_ENABLE), which appears to turn otherwise-silent memory corruption into hard, reproducible crashes — so this device may be a useful signal for latent native
memory-safety bugs.

VERSIONS USED

  • Android Studio: Panda 4 - 2025.3.4 Patch 1 (build toolchain: AGP 9.x, Kotlin 2.3.10, JDK 21)
  • ARCore SDK for Android: integrated via SceneView io.github.sceneview:arsceneview:4.17.0; bundled libarcore_c.so is 1.54
  • Device manufacturer, model, and O/S: Samsung Galaxy A56 (a56x), Android 16
  • Google Play Services for AR (ARCore): ~1.54.x — libarcore_c.so BuildId 15fc3723f0012d756162123aa00372fd (run the adb command above to confirm the exact versionName)
  • Output of adb shell getprop ro.build.fingerprint:
    samsung/a56xnaxx/a56x:16/BP4A.251205.006/A566BXXSACZE2_OJMACZE2:user/release-keys

STEPS TO REPRODUCE THE ISSUE

  1. Run a continuous ARCore session on a Samsung Galaxy A56 / Android 16 (camera tracking active, depth enabled).
  2. Exercise the API continuously for several minutes — acquire a Frame every render frame and perform frequent hit-tests (HitResult) while moving the device (tracking / relocalisation stress) — so many
    native-backed wrapper objects become garbage and are reclaimed by the GC.
  3. A crash occurs sporadically (GC-timing / tracking dependent), in one of the three modes above: most often on the FinalizerDaemon / cleaner thread (ArFrame_destroy / ArHitResult_destroy /
    CameraMetadata_close), occasionally inside ARCore's ms_depth / MTC_mapping threads, occasionally as a free-time SIGABRT.

We do not have a deterministic minimal repro — the crashes are non-deterministic and GC-timing dependent — but they recur reliably on this device over normal multi-minute sessions. Full tombstones (text +
.pb) are available.

WORKAROUNDS (IF ANY)

None effective. These are native signals (SIGSEGV / SIGBUS / SIGABRT) on the GC finalizer/cleaner or on ARCore's own threads, so they cannot be caught from Java. We verified the app never retains or
double-frees these objects; reducing Java-object churn does not stop the GC from eventually finalizing them and hitting the native destroy path. Reducing session length / motion lowers the frequency but does
not eliminate the crashes.

ADDITIONAL COMMENTS

Hypothesis: ARCore 1.54 native code mismanages the lifetime/ownership of native peer objects (ArFrame, ArHitResult, camera2 CameraMetadata), so their native resources are freed/corrupted before or while
the GC finalizer / NativeAllocationRegistry cleaner destroys them (use-after-free / double-free), plus separate null-deref crashes inside the depth (ms_depth) and mapping (MTC_mapping) worker threads.
The free-time SIGABRT (truncated pointer tag) is the same memory-safety class caught at allocation time.

Representative backtraces (one per mode; all same device/OS and the identical libarcore_c.so BuildId above):

Mode 1 — ArFrame_destroy on FinalizerDaemon (SIGBUS, fault 0x10000005e):

  #00 pc 000000010000005e  <unknown>
  #04 pc 00000000010ba3f0  libarcore_c.so (ArFrame_destroy+12)
  #05 pc 00000000002b03a0  libart.so (art_quick_generic_jni_trampoline+144)
  #10 pc ...               com.google.ar.core.Frame.finalize+0
  #14 pc ...               java.lang.Daemons$FinalizerDaemon.doFinalize+208

Mode 1 (camera2 variant) — CameraMetadata_close on FinalizerDaemon (SIGSEGV, null):

  #00 pc 0000000000000000  <unknown>
  #01 pc 0000000000228f2c  /system/lib64/libandroid_runtime.so (CameraMetadata_close(_JNIEnv*, _jclass*, long)+56)
  #03 pc ...               android.hardware.camera2.impl.CameraMetadataNative.close+124
  #04 pc ...               android.hardware.camera2.impl.CameraMetadataNative.finalize+116
  #05 pc ...               java.lang.Daemons$FinalizerDaemon.doFinalize+208

Mode 2 — ARCore worker thread MTC_mapping (SIGSEGV, null), entirely in libarcore_c.so:

  #00 pc 0000000001a07d48  libarcore_c.so (offset 0xda8000)
  #01 pc 00000000014886e4  libarcore_c.so (offset 0xda8000)
  #02 pc 000000000148f0d8  libarcore_c.so (offset 0xda8000)

Mode 3 — heap corruption on free, main thread (SIGABRT):

  Abort message: 'Pointer tag for 0x726f772e5d37345b was truncated, see ...tagged-pointers'
  #00 pc 00000000000754c8  libc.so (abort+156)
  #01 pc 0000000000059500  libc.so (free+104)
  #02 pc 0000000001a69798  libarcore_c.so (offset 0xda8000)

We're happy to attach the full text + .pb tombstones, provide more captures, or run instrumented builds.

Mode_1_AR_Frame.zip
Mode_1_Camera_Metadata.zip
Mode_2.zip
Mode_3.zip

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions