Skip to content

chore(sentry): pin sentry-native 0.16.5, and the crash daemon walks ARM32 frame chains - #64

Merged
GLinnik21 merged 1 commit into
mainfrom
chore/sentry-native-0.16.5
Sep 2, 2026
Merged

chore(sentry): pin sentry-native 0.16.5, and the crash daemon walks ARM32 frame chains#64
GLinnik21 merged 1 commit into
mainfrom
chore/sentry-native-0.16.5

Conversation

@GLinnik21

Copy link
Copy Markdown
Owner

The pin moves 0.13.9 → 0.16.5. Two things this repo hand-wrote against 0.13.9 are
upstream now and leave the patch: the non-regular-file guard when reading
/proc//maps entries as ELF (sentry__elf_open), and the ptrace snapshot of
the other threads — #1747's per-thread remote libunwind unwinding replaces it
with DWARF frames and symbol names. Also gone: previous-handler chaining and the
flush_scope fields (release, dist, environment, sdk, event_id), which upstream
fills. The patch shrinks from 600 lines to what upstream does not do.

What it still does, and why:

  • process_vm_readv wrapper for glibc 2.12 (also needed by the daemon now).
  • ARM32 registers in the event, and a frame-pointer walk that reads BOTH
    ARM32 frame records. GCC's push {..,fp,lr}; add fp,sp,#N leaves fp on the
    LR slot ([fp-4] saved fp, [fp] return); rustc/LLVM leaves it on the saved-fp
    slot ([fp] saved fp, [fp+4] return). The old patch hard-coded the GCC shape,
    so a crash in Rust — nearly every crash — walked one frame and reported a
    saved fp as a return address. Candidates are judged against the crashed
    process's mappings, recorded with permission bits while maps is parsed:
    return address in an executable, non-writable mapping; saved fp above the
    current frame in a writable one. Fail closed when the mapping snapshot is
    incomplete or differs on a second read after the stack copy. Both halves
    are upstream PRs (fix(native): read frame records at pointer width in the crash daemon's FP walk getsentry/sentry-native#2052, #2053) and drop out of the
    patch once a pinned release contains them.
  • Pointer-width stack reads with a subtraction range check.
  • 32-frame cap for non-crashed threads (the 256 KiB record ceiling), the 30 s
    handler budget, and the two webOS-only signal-handler escapes.

libsentry and our C are built with -funwind-tables so the remote unwinder gets
through them (it stopped at threadpool_thread before).

Device-verified on the debug install: SIGSEGV and SIGABRT → envelope → import
(queued=1 rejected=0, native_wins=1) → flushed → visible in the Sentry project
with sdk.version 0.16.5; crashed thread crash_on_purpose ← plex_run ← __libc_start_main; a GCC-built noinline chain leaf ← f2 ← f1 ← __libc_start_main. fwcompat matrix unchanged (OK 4.4.2→11.2.0); both binaries
still need only GLIBC_2.12.

🤖 Generated with Claude Code

…RM32 frame chains

The pin moves 0.13.9 → 0.16.5. Two things this repo hand-wrote against 0.13.9 are
upstream now and leave the patch: the non-regular-file guard when reading
/proc/<pid>/maps entries as ELF (sentry__elf_open), and the ptrace snapshot of
the other threads — #1747's per-thread remote libunwind unwinding replaces it
with DWARF frames and symbol names. Also gone: previous-handler chaining and the
flush_scope fields (release, dist, environment, sdk, event_id), which upstream
fills. The patch shrinks from 600 lines to what upstream does not do.

What it still does, and why:

- process_vm_readv wrapper for glibc 2.12 (also needed by the daemon now).
- ARM32 registers in the event, and a frame-pointer walk that reads BOTH
  ARM32 frame records. GCC's `push {..,fp,lr}; add fp,sp,#N` leaves fp on the
  LR slot ([fp-4] saved fp, [fp] return); rustc/LLVM leaves it on the saved-fp
  slot ([fp] saved fp, [fp+4] return). The old patch hard-coded the GCC shape,
  so a crash in Rust — nearly every crash — walked one frame and reported a
  saved fp as a return address. Candidates are judged against the crashed
  process's mappings, recorded with permission bits while maps is parsed:
  return address in an executable, non-writable mapping; saved fp above the
  current frame in a writable one. Fail closed when the mapping snapshot is
  incomplete or differs on a second read after the stack copy. Both halves
  are upstream PRs (getsentry/sentry-native#2052, #2053) and drop out of the
  patch once a pinned release contains them.
- Pointer-width stack reads with a subtraction range check.
- 32-frame cap for non-crashed threads (the 256 KiB record ceiling), the 30 s
  handler budget, and the two webOS-only signal-handler escapes.

libsentry and our C are built with -funwind-tables so the remote unwinder gets
through them (it stopped at threadpool_thread before).

Device-verified on the debug install: SIGSEGV and SIGABRT → envelope → import
(queued=1 rejected=0, native_wins=1) → flushed → visible in the Sentry project
with sdk.version 0.16.5; crashed thread `crash_on_purpose ← plex_run ←
__libc_start_main`; a GCC-built noinline chain `leaf ← f2 ← f1 ←
__libc_start_main`. fwcompat matrix unchanged (OK 4.4.2→11.2.0); both binaries
still need only GLIBC_2.12.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings September 2, 2026 22:53
@GLinnik21
GLinnik21 merged commit 399b317 into main Sep 2, 2026
@GLinnik21
GLinnik21 deleted the chore/sentry-native-0.16.5 branch September 2, 2026 22:53

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The version pin, patch adjustments, build flags, and accompanying docs/tests are consistent and appear internally coherent for the intended webOS ARM32 crash-walk behavior.

Pull request overview

This PR updates the vendored Sentry Native crash handler integration to a pinned sentry-native 0.16.5 release, reducing the downstream webOS/ARM32 patch surface by dropping functionality that has moved upstream and keeping only the remaining webOS/ARM32-specific crash-walk requirements (notably ARM32 frame-chain correctness and glibc 2.12 compatibility).

Changes:

  • Pin sentry-native to 0.16.5 in the build script and update the downstream webos-arm32.patch accordingly.
  • Improve ARM32 crash-walk reliability: pointer-width stack reads, dual frame-record shape support, mapping-snapshot verification, and a longer handler wait budget for cold crashes.
  • Align build flags and documentation/examples with the new pinned version and unwinding requirements.
File summaries
File Description
vendor/sentry-native/webos-arm32.patch Updates the downstream webOS/ARM32 patch for sentry-native 0.16.5, keeping only non-upstreamed webOS/ARM32 crash-walk behavior and compatibility shims.
rust-modules/src/telemetry/native.rs Updates the representative native event/schema preview and tests to report sdk.version 0.16.5.
Makefile Adds -funwind-tables to C compilation flags to support remote DWARF unwinding paths.
docs/agent-reference.md Updates the crash-forensics architecture notes to reflect the new upstream/unpatched behavior and the 0.16.5 pin.
ci/build-sentry-native.sh Pins the build to 0.16.5, updates SHA256, and sets explicit C flags for unwind tables + frame pointers in the cross build.
.agents/skills/crash-triage/SKILL.md Updates the crash triage skill text to match the new crash-daemon unwinding behavior and limits.
Review details
  • Files reviewed: 5/6 changed files
  • Comments generated: 0
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

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.

2 participants