react / react/react-native

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

Open
#57,963 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Needs: Attention Needs: Repro
Dominant language
C++
Stars
127k
Forks
25.3k
Avg merge
1d 23h
Merged PRs (30d)
4

Description

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.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with EventQueue.cpp:113 and RawEvent.h:25, then trace the surrounding scheduling flow through EventBeat.cpp, RuntimeScheduler_Modern.cpp, JMessageQueueThread.cpp, and ReactInstance.cpp. Reproduce the Android foreground-and-import scenario if possible and determine why event delivery aborts; done means the failure has an identified cause and a validated fix or regression test.

Written by the indexing model from the issue text.

Assessment

Tech stack
android, cpp, react-native, sqlite
Domain
mobile
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.