[js/rn] Fix iOS SIGSEGV on JS reload by releasing Env in -invalidate - #28367
Open
Alexey Shlaikov (shlaikov) wants to merge 1 commit into
Open
Alexey Shlaikov (shlaikov) wants to merge 1 commit into
Alexey Shlaikov (shlaikov) wants to merge 1 commit into
Conversation
The static `env` shared_ptr in OnnxruntimeModule holds a jsi::WeakObject (tensorConstructor) that points into the JSI runtime. On JS reload (e.g. Cmd+R in dev), the bridge tears down the JSI runtime before the OnnxruntimeModule instance is deallocated. When `env.reset()` runs from -dealloc, ~WeakObject calls runtime.releasePointerValue on a dead runtime, producing a SIGSEGV in jsi::Pointer::~Pointer(). Adopt RCTInvalidating and release `env` from -invalidate, which RN calls on the JS thread while the runtime is still alive. -dealloc keeps env.reset() as a no-op fallback for paths that bypass invalidate. Repro: 1. Create an InferenceSession in a RN iOS app 2. Press Cmd+R in the simulator (or otherwise reload the bridge) 3. App crashes with EXC_BAD_ACCESS Crash signature: Thread: com.facebook.react.runtime.JavaScript -[OnnxruntimeModule dealloc] -> shared_ptr<onnxruntimejsi::Env>::reset -> ~Env() -> ~WeakObject() -> ~Pointer() -> SIGSEGV at 0x0
Author
|
@microsoft-github-policy-service agree |
Sanaa Hamel (sanaa-hamel-microsoft)
approved these changes
May 5, 2026
Guenther Schmuelling (guschmue)
approved these changes
May 5, 2026
Author
|
Could a maintainer re-run the failed Windows CPU job? It died on the setup-python cache step, unrelated to this diff. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
The static
envshared_ptr inOnnxruntimeModuleholds anonnxruntimejsi::EnvwhosetensorConstructor_is astd::shared_ptr<facebook::jsi::WeakObject>pointing into the JSI runtime.On a JS reload (e.g. Cmd+R during development) the React Native bridge tears down the JSI runtime before the Obj-C
OnnxruntimeModuleinstance is deallocated. Whenenv.reset()runs from-dealloc,~WeakObjectcallsruntime.releasePointerValue(...)on a runtime that no longer exists, producing a SIGSEGV injsi::Pointer::~Pointer().This change makes
OnnxruntimeModuleadoptRCTInvalidatingand resetsenvfrom-invalidate, which React Native calls on the JS thread while the runtime is still alive.-deallockeepsenv.reset()as a no-op fallback for paths that may bypass-invalidate.Files changed:
js/react_native/ios/OnnxruntimeModule.h— declare conformance toRCTInvalidating, import its header.js/react_native/ios/OnnxruntimeModule.mm— implement-invalidateto reset the staticenv.Motivation and Context
After the JSI migration (#25764) any iOS app that loads an
InferenceSessionand then triggers a JS reload (Cmd+R, fast refresh that escalates to a full reload, or programmaticDevSettings.reload()) crashes hard. This is reproducible 100% of the time ononnxruntime-react-native@1.24.xwith React Native 0.85.Repro
InferenceSession.DevSettings.reload()).EXC_BAD_ACCESS (SIGSEGV) KERN_INVALID_ADDRESS at 0x0.Crash signature (from a real
.ips):RCTInvalidatingis the standard React Native escape hatch for this exact lifecycle problem — it is invoked on the JS thread before the bridge invalidates modules and tears down the runtime, so any JSI handles can be released safely.I have not touched the Android side. The Android JNI binding stores
tensorConstructordifferently and I have not seen the equivalent crash there; happy to follow up in a separate PR if maintainers want symmetric handling.