Skip to content

SIGABRT in EventQueue::flushEvents / RawEvent destructor on Android (New Architecture, RN 0.86.2) during heavy JS-thread work #57963

Description

@EliandroDevWme

Body

Description

We're seeing a native SIGABRT crash (uncaught, mechanism: signalhandler) with a stack trace entirely inside Fabric/RuntimeScheduler internals — no first-party JS frames involved. It has occurred twice on the same physical device so far.

Environment

  • React Native: 0.86.2
  • Expo SDK: 57
  • Architecture: New Architecture (Fabric) — mandatory on this RN version
  • Hermes: yes
  • Platform: Android 16
  • Device: Samsung Galaxy S24 FE (SM-S721B), arm64-v8a
  • App version tag: 1.4.3 (build 40)

Repro context

Both occurrences happened during the same user flow:

  1. App resumes from background (onResume).
  2. User taps a sync/refresh action, which kicks off a data import: a network download followed by a single large SQLite transaction (expo-sqlite, withExclusiveTransactionAsync) that sequentially imports ~19 groups of records, each step logged synchronously via console.log.
  3. A few milliseconds after one of the intermediate import steps logs, the process aborts.

The JS thread is doing sustained synchronous-ish work throughout the import (a tight loop of awaited SQLite operations, several dozen ms apart), right after the app comes back to the foreground — so there may be a backlog of native UI/touch events queued for delivery to JS at the same time.

Stack trace

SIGABRT: Abort

    at <unknown> (<unknown>)
    at facebook::jni::detail::FunctionWrapper<T>::call (Registration-inl.h:95)
    at facebook::jni::detail::CallWithJniConversions<T>::call (Registration-inl.h:66)
    at facebook::jni::detail::MethodWrapper<T>::dispatch (Registration-inl.h:129)
    at facebook::jni::JNativeRunnable::run (NativeRunnable.h:44)
    at std::__ndk1::function<T>::operator() (function.h:978)
    at std::__ndk1::__function::__value_func<T>::operator()[abi:ne180000] (function.h:425)
    at std::__ndk1::__function::__func<T>::operator() (function.h:308)
    at std::__ndk1::__function::__alloc_func<T>::operator()[abi:ne180000] (function.h:166)
    at std::__ndk1::__invoke_void_return_wrapper<T>::__call[abi:ne180000]<T> (invoke.h:419)
    at std::__ndk1::__invoke[abi:ne180000]<T> (invoke.h:344)
    at facebook::react::(anonymous namespace)::wrapRunnable::lambda::operator() (JMessageQueueThread.cpp:37)
    at std::__ndk1::function<T>::operator() (function.h:978)
    at std::__ndk1::__function::__value_func<T>::operator()[abi:ne180000] (function.h:425)
    at std::__ndk1::__function::__func<T>::operator() (function.h:308)
    at std::__ndk1::__function::__alloc_func<T>::operator()[abi:ne180000] (function.h:166)
    at std::__ndk1::__invoke_void_return_wrapper<T>::__call[abi:ne180000]<T> (invoke.h:419)
    at std::__ndk1::__invoke[abi:ne180000]<T> (invoke.h:344)
    at const::lambda::operator() (ReactInstance.cpp:93)
    at std::__ndk1::function<T>::operator() (function.h:978)
    at std::__ndk1::__function::__value_func<T>::operator()[abi:ne180000] (function.h:425)
    at facebook::react::RuntimeScheduler_Modern::runEventLoop (RuntimeScheduler_Modern.cpp:266)
    at facebook::react::RuntimeScheduler_Modern::runEventLoopTick (RuntimeScheduler_Modern.cpp:312)
    at facebook::react::RuntimeScheduler_Modern::executeTask (RuntimeScheduler_Modern.cpp:375)
    at facebook::react::Task::execute (Task.cpp:60)
    at std::__ndk1::function<T>::operator() (function.h:978)
    at std::__ndk1::__function::__value_func<T>::operator()[abi:ne180000] (function.h:425)
    at std::__ndk1::__function::__func<T>::operator() (function.h:308)
    at std::__ndk1::__function::__alloc_func<T>::operator()[abi:ne180000] (function.h:166)
    at std::__ndk1::__invoke_void_return_wrapper<T>::__call[abi:ne180000]<T> (invoke.h:419)
    at std::__ndk1::__invoke[abi:ne180000]<T> (invoke.h:344)
    at const::lambda::operator() (EventBeat.cpp:70)
    at std::__ndk1::function<T>::operator() (function.h:978)
    at std::__ndk1::__function::__value_func<T>::operator()[abi:ne180000] (function.h:425)
    at facebook::react::EventQueue::flushEvents (EventQueue.cpp:113)
    at std::__ndk1::vector<T>::~vector[abi:ne180000] (vector:501)
    at std::__ndk1::vector<T>::__destroy_vector::operator()[abi:ne180000] (vector:490)
    at std::__ndk1::vector<T>::__clear[abi:ne180000] (vector:920)
    at std::__ndk1::vector<T>::__base_destruct_at_end[abi:ne180000] (vector:926)
    at std::__ndk1::allocator_traits<T>::destroy[abi:ne180000]<T> (allocator_traits.h:316)
    at std::__ndk1::__destroy_at<facebook::react::RawEvent> (construct_at.h:67)
    at facebook::react::RawEvent::~RawEvent (RawEvent.h:25)
    at std::__ndk1::shared_ptr<T>::~shared_ptr[abi:ne180000] (shared_ptr.h:645)
    at std::__ndk1::__shared_weak_count::__release_shared[abi:ne180000] (shared_ptr.h:184)
    at <unknown> (<unknown>)
    at <unknown> (<unknown>)
    at <unknown> (<unknown>)
    at <unknown> (<unknown>)
    at <unknown> (<unknown>)
    at abort (<unknown>)

Notes

  • Low frequency so far (2 occurrences on 1 device over 4 days), but 100% of the stack is React Native internals — no app frame to act on from our side.
  • Happy to share more Sentry context (breadcrumbs, device info) if useful.

Activity

  1. react-native-bot commented on Aug 14, 2026

    @react-native-bot
    Collaborator

    Warning

    Missing reproducer: We could not detect a reproducible example in your issue report. Reproducers are mandatory and we can accept only one of those as a valid reproducer:


    You can read more about about it on our website: How to report a bug.

  2. EliandroDevWme commented on Aug 14, 2026

    @EliandroDevWme
    Author

    Thanks for the note. This is a rare native SIGABRT (2 occurrences on 1 device over 4 days) with a stack trace entirely inside Fabric/RuntimeScheduler internals (EventQueue::flushEvents / RawEvent destructor) — no JS/app frames involved, and it depends on a timing-sensitive condition (JS thread doing sustained synchronous work right as the app resumes from background, likely with a backlog of native touch/UI events pending delivery). I don't have a deterministic reproduction I can package into RNTesterPlayground.js or a minimal project — I'm reporting it from a production crash with full context (stack trace, device/OS/RN version, breadcrumb trail) in case it's useful for triage or matches a known issue, understanding it may not meet the reproducer bar for a full investigation.

  3. buddhi-system2 commented on Aug 17, 2026

    @buddhi-system2

    We're seeing what looks like exactly this crash in production, and can corroborate with additional data points.

    Environment: RN 0.81.5 (Expo SDK 54), New Architecture, Hermes, react-native-reanimated 4.1.1. App: fitness/coaching app, ~1,100 Android 16 MAU.

    Devices — exclusively Samsung on Android 16 (API 36): Galaxy S22 (SM-S901U1), S23+ (SM-S916U), S23 Ultra (dm3q), S24/S24+ (e1q/e2q/SM-S926U), S25+ (SM-S936U), across five app releases. 100% foreground, always mid-interaction — typically within ~1s of a navigation transition or bottom-sheet animation. For a few users it reproduces nearly every session; their account data was audited and ruled out.

    We see two faces of the same corruption:

    1. SIGABRT — Scudo invalid free during event-queue cleanup (same as this issue; Google Play Vitals, symbolicated):

    Scudo ERROR: invalid chunk state when deallocating address 0x<sanitized>
    #00 libc.so (abort)
    #01 libc.so (scudo::die)
    #04 libc.so (scudo::reportInvalidChunkState)
    #05 libc.so (scudo::Allocator<...>::deallocate)
    #07 libreactnative.so (facebook::react::EventQueue::flushEvents(facebook::jsi::Runtime&) const)
    #09 libreactnative.so (facebook::react::Task::execute)
    #10-12 libreactnative.so (RuntimeScheduler_Modern::executeTask / runEventLoopTick / runEventLoop)
    

    2. SIGSEGV — constructing the event payload jsi::Value (Play Vitals + Sentry, identical stacks):

    facebook::jsi::Value::Value
      ← facebook::react::UIManagerBinding::dispatchEventToJS
      ← facebook::react::EventQueueProcessor::flushEvents
      ← facebook::react::EventQueue::flushEvents
      ← facebook::react::Task::execute
      ← facebook::react::RuntimeScheduler_Modern::runEventLoopTick → runEventLoop
    

    Notes that may help triage:

    • These crashes are invisible to Sentry's JS layer and only intermittently captured by its NDK signal handler — Play Vitals was the reliable source. Others hitting this may simply not see it.
    • Our leading suspect is the fix in 0.87.0: 5dea3b5e6c — "Events: Fix use-after-free data race in EventEmitter.cpp". dispatchEventToJS constructs a jsi::Value from the event target's instance handle — precisely the object that commit protects with the scoped lock. A racing eventTarget_/shadowNodeFamily_ mutation (unmount / emitter enable-disable) corrupting the shared_ptr would explain both signatures, including the RawEvent destructor abort here. Not yet verified on 0.87 — we're on 0.81 and the commit is absent from 0.86-stable (this issue being on 0.86.2 is consistent with that).
    • We've filed a cherry-pick request for 5dea3b5e6c into 0.86-stable: [0.86] Fix use-after-free data race in EventEmitter.cpp (fatal heap-corruption crashes on Android 16) reactwg/react-native-releases#1369.
    • Android 16's Scudo config seems to be what turns the latent race into a reliable abort — we have zero occurrences on Android ≤15 across the same fleet.

    Happy to test a patched build on affected Samsung/Android 16 devices or share fuller Vitals data.

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

    Needs: AttentionIssues where the author has responded to feedback.Needs: ReproThis issue could be improved with a clear list of steps to reproduce the issue.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions