Skip to content

Android: in-process crash handler aborts with std::bad_alloc while parsing process maps, losing the original crash #2235

Closed

Description

@iscekic

bot: Android in-process crash handler aborts with std::bad_alloc while parsing process maps, and the original crash is lost

Summary

On Android, the in-process backend aborts inside its own unwinder while capturing a crash. The abort becomes the crash that Play and Sentry report, so the fault that actually killed the app is never recorded.

Crashing thread (mechanism: Tombstone, so this is the tombstone's crashing thread):

sentry_backend_inproc.c              handler_thread_main
sentry_backend_inproc.c              process_ucontext_deferred
sentry_backend_inproc.c              make_signal_event
sentry_unwinder_libunwindstack.cpp   sentry__unwind_stack_libunwindstack
unwindstack::Maps::Parse
android::procinfo::ReadMapFile
android::base::ReadFileToString
android::base::ReadFdToString
std::__ndk1::basic_string<T>::append
operator new
-> std::bad_alloc -> abort

Event message:

terminating due to uncaught exception of type std::bad_alloc: std::bad_alloc:
Fatal signal SIGABRT (6), SI_QUEUE (-1), pid = 16371 (…)

Environment

  • sentry-native 0.16.6, through sentry-java 8.57.0 and @sentry/react-native 8.28.0.
  • Android 13 through 17, arm64-v8a.
  • Mostly recent Pixel devices; device class "high", installed from Play, not rooted.
  • Hundreds of events from dozens of users over a fortnight on one app version, and this is the single largest crash group on that version.

Why this looks like a defect rather than low memory

  • sentry__unwind_stack_libunwindstack calls LocalMaps::Parse() with no try/catch, and that call allocates through std::string growth while building the maps table.
  • Allocation therefore happens in the handler thread during crash capture, where a failure has no recovery path.
  • Several samples carry scudo allocator frames under the same abort, which points at the allocation failing rather than the app's own memory use.
  • The events span devices with large heaps, and the app's own native crash rate on that version is stable, so "the device was out of memory" does not explain the distribution.
  • src/unwinder/sentry_unwinder_libunwindstack.cpp is unchanged between 0.16.6, 0.17.4 and master, so no released version contains a guard for this.

Possible directions

  1. Avoid heap growth in the unwinder path: parse /proc/self/maps into a preallocated or mmaped buffer instead of std::string.
  2. Wrap make_signal_event so a std::bad_alloc degrades to an event without a stack trace instead of aborting the process.
  3. Mark the unwinder entry point noexcept and handle allocation failure inside it, so the crash handler always returns.

Out-of-process handling (#1725) would sidestep the whole path, but this one still loses crash reports today on the in-process backend.

Happy to test a patch against our release build and report back.

Activity

  1. moved this to Waiting for: Product Owner in GitHub Issues with 👀 3on Oct 22, 2026
  2. linear-code commented on Oct 22, 2026

    @linear-code
  3. jpnurmi commented on Oct 23, 2026

    @jpnurmi
    Collaborator

    Thanks for the report! We'll take a look.

  4. moved this from Waiting for: Product Owner to No status in GitHub Issues with 👀 3on Oct 23, 2026
  5. added a commit that references this issue on Oct 23, 2026
    522b36e
  6. added a commit that references this issue on Oct 26, 2026
    b191093
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    AndroidErrorsissues relates to the error reporting product

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions