Skip to content

[Hermes V1] Crash in CodeBlock::getSourceLocation when DevTools connected - missing null check on state.codeBlock #56284

Closed as not planned

Description

@benji-jo

Description

When using Hermes V1 (RCT_HERMES_V1_ENABLED=1 on iOS, hermesV1Enabled=true on Android) with React Native 0.83.4, the app crashes when React Native DevTools is connected.

The crash occurs in hermes::vm::CodeBlock::getSourceLocation() due to a null pointer dereference. The debugger's getLocationForState() does not check if state.codeBlock is null before calling ->getSourceLocation().

This is the same root cause as #55571 (which was closed due to inactivity).

Root Cause Analysis

In include/hermes/VM/Debugger/Debugger.h:

OptValue<hbc::DebugSourceLocation> getLocationForState(
    const InterpreterState &state) const {
  return state.codeBlock->getSourceLocation(state.offset);
  //     ^^^^^^^^^^^^^^^^ can be null — no null check
}

And in sameStatementDifferentInstruction:

auto aLoc = getLocationForState(a);
auto bLoc = getLocationForState(b);
return a.codeBlock == b.codeBlock && aLoc->statement == bLoc->statement;
//                                   ^^^^ aLoc/bLoc can be None when codeBlock is null

Crash Log

Thread 19 Crashed:: com.facebook.react.runtime.JavaScript
Exception Type:    EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000000000000

0  hermesvm  hermes::vm::CodeBlock::getSourceLocation(unsigned int) const + 28
1  hermesvm  hermes::vm::Debugger::runUntilValidPauseLocation(hermes::vm::InterpreterState&) + 144
2  hermesvm  hermes::vm::Debugger::runDebugger(hermes::vm::Debugger::RunReason, hermes::vm::InterpreterState&) + 1148
3  hermesvm  hermes::vm::Interpreter::interpretFunction<false, false>(...) + 3152
...
9  tracer    facebook::react::TimerCallback::invoke(facebook::jsi::Runtime&) + 88
10 tracer    facebook::react::TimerManager::callTimer(int)::$_0::operator()(...) + 268

ARM Thread State:
x0: 0x0000000000000000 (null — this pointer for CodeBlock)
far: 0x0000000000000000
esr: 0x92000006 (Data Abort) byte read Translation fault

Steps to Reproduce

  1. Use React Native 0.83.4 (or 0.84.0) with Hermes V1 enabled
  2. Run the app in debug mode
  3. Connect React Native DevTools
  4. The app starts logging normally, then crashes after a few seconds when high-volume JS calls (e.g. timer callbacks, TurboModule calls) trigger the debugger

Expected Behavior

DevTools should work without crashing when Hermes V1 is enabled. getLocationForState() should handle null state.codeBlock gracefully.

Suggested Fix

OptValue<hbc::DebugSourceLocation> getLocationForState(
    const InterpreterState &state) const {
  if (!state.codeBlock) return llvh::None;
  return state.codeBlock->getSourceLocation(state.offset);
}

Environment

  • React Native: 0.83.4
  • Hermes V1: enabled (RCT_HERMES_V1_ENABLED=1)
  • Platform: iOS (also reproducible on Android)
  • New Architecture: enabled
  • DevTools: standalone React Native DevTools

Related Issues

Activity

  1. react-native-bot commented on Mar 31, 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. vchan023 commented on Apr 23, 2026

    @vchan023

    Also seeing this on 84.1. When I run DevTools my app will suddenly crash either instantly or within the minute.

  3. maneesh-techversant commented on Apr 27, 2026

    @maneesh-techversant

    +1

  4. AjayFrancisTechversant commented on Apr 27, 2026

    @AjayFrancisTechversant

    +1
    I couldnt even debug properly using devtools because of this crash.

  5. vchan023 commented on May 4, 2026

    @vchan023

    Tested v0.85.2 as well and same issue. Using xcode logs for now.

  6. Mootzali commented on May 16, 2026

    @Mootzali

    +1
    I have the same issue on v0.85.3

  7. alpha0010 commented on May 21, 2026

    @alpha0010
    Contributor

    DevTools can be pretty hard to use, due to these crashes.

    Maybe we could get some more visibility on this issue by mirroring it to the hermes repo https://github.com/facebook/hermes/issues ? @benji-jo are you able to write that up, as you have done the analysis?

  8. Niko-Yea commented on May 28, 2026

    @Niko-Yea

    +1, reproducible on React Native 0.85.3 / Expo SDK 56 / Hermes V1.

    • Both iOS sim and Android emu — same crash.
    • Debug only. Release builds are fine.
  9. FTSTimSin commented on Jun 4, 2026

    @FTSTimSin

    +1

    • Consistent crashes on both RN 0.83.0 and 0.85.3.
    • Crash doesn't happen when setting RCT_HERMES_V1_ENABLED=0.
    • Debug only, crashes only seem to happen when opening DevTools so release/production builds are fine.
  10. robrechtme commented on Jun 11, 2026

    @robrechtme

    Might help narrow this down: the crash is not specific to the React Native DevTools frontend. I hit the same crash (RN 0.85.3 / Expo SDK 56 / Hermes V1 / New Architecture, iOS 26.5 simulator, debug build) with no DevTools window open at all‚ the only client attached to Metro was the metro-mcp (which connects over CDP).

    Nine crashes within ~35 minutes, all with the exact top frames:

    0  hermesvm  hermes::vm::CodeBlock::getSourceLocation(unsigned int) const + 28
    1  hermesvm  hermes::vm::Debugger::runUntilValidPauseLocation(hermes::vm::InterpreterState&) + 144
    2  hermesvm  hermes::vm::Debugger::runDebugger(hermes::vm::Debugger::RunReason, hermes::vm::InterpreterState&) + 1148
    

    The JS work underneath varied per crash (TimerManager::callTimer, drainMicrotasks, plain function calls), so any JS activity can trigger it while a client is attached. Killing every CDP client connected to Metro stopped the crashes immediately.

    This rules out DevTools-frontend-specific behavior and is consistent with the root cause being entirely in the Hermes debugger as analyzed above: any client that enables the CDP Debugger domain triggers it.

  11. erik-lissen commented on Jun 12, 2026

    @erik-lissen

    Might help narrow this down: the crash is not specific to the React Native DevTools frontend. I hit the same crash (RN 0.85.3 / Expo SDK 56 / Hermes V1 / New Architecture, iOS 26.5 simulator, debug build) with no DevTools window open at all‚ the only client attached to Metro was the metro-mcp (which connects over CDP).

    Nine crashes within ~35 minutes, all with the exact top frames:

    0  hermesvm  hermes::vm::CodeBlock::getSourceLocation(unsigned int) const + 28
    1  hermesvm  hermes::vm::Debugger::runUntilValidPauseLocation(hermes::vm::InterpreterState&) + 144
    2  hermesvm  hermes::vm::Debugger::runDebugger(hermes::vm::Debugger::RunReason, hermes::vm::InterpreterState&) + 1148
    

    The JS work underneath varied per crash (TimerManager::callTimer, drainMicrotasks, plain function calls), so any JS activity can trigger it while a client is attached. Killing every CDP client connected to Metro stopped the crashes immediately.

    This rules out DevTools-frontend-specific behavior and is consistent with the root cause being entirely in the Hermes debugger as analyzed above: any client that enables the CDP Debugger domain triggers it.

    Same repro as above - Expo 56, iOS 26.2 simulator (also on iPhone 26.5) debug build with no DevTools open. Killing all metro-mcp processes has fixed the crash

  12. react-native-bot commented on Jul 7, 2026

    @react-native-bot
    Collaborator

    This issue is waiting for author's feedback since 24 days. Please provide the requested feedback or this will be closed in 7 days.

  13. react-native-bot commented on Jul 7, 2026

    @react-native-bot
    Collaborator

    This issue is waiting for author's feedback since 24 days. Please provide the requested feedback or this will be closed in 7 days.

  14. added
    StaleThere has been a lack of activity on this issue and it may be closed soon.
    on Jul 7, 2026
  15. Mootzali commented on Jul 8, 2026

    @Mootzali

    Independent confirmation of @Elehiggle's fix — verified on Android + RN 0.85.3

    The getLocationForState null-check in this report is on the right track, but on my build it was necessary but not sufficient — with only that hunk, the crash moved rather than disappeared. The complete fix is the one @Elehiggle posted in the closely-related #55571 (#55571 (comment)... — the 2026-06-10 comment): three hunks together, with a full symbolicated stack and root-cause analysis. I'm commenting here because #56284 is the open issue and their analysis deserves a second, independent confirmation.

    My setup (independent from @Elehiggle's):

    react-native 0.85.3
    Hermes V1 (hermes-v0.16.0 source stamp; Maven hermes-android:250829098.0.10)
    Architecture New Architecture + Bridgeless (CDP target: React Native Bridgeless [C++ connection])
    Platform Android arm64-v8a, physical device
    Debugger React Native DevTools (fusebox / CDP)

    Same crash site and the same second, masked symptom @Elehiggle describes: a spurious "paused in debugger" that fires on attach without any user step, because an implicit async CDP interrupt gets surfaced as PauseReason::StepFinish. Root cause is theirs: the Ret branch in runUntilValidPauseLocation switches to StepMode::Out without ever initializing preStepState_, so the next pause dereferences preStepState_.codeBlock == nullptr, and sameStatementDifferentInstruction also dereferences both OptValue locations without hasValue() checks.

    The full fix I applied (all three hunks are @Elehiggle's, credit to them):

    include/hermes/VM/Debugger/Debugger.h — this issue's null-check, plus a hasValue() guard in sameStatementDifferentInstruction:

    // in sameStatementDifferentInstruction, after the two getLocationForState calls:
        auto aLoc = getLocationForState(a);
        auto bLoc = getLocationForState(b);
    
        // Locations may be missing (null codeBlock or no debug info).
        if (!aLoc.hasValue() || !bLoc.hasValue())
          return false;
    
        return a.codeBlock == b.codeBlock && aLoc->statement == bLoc->statement &&
            a.offset != b.offset;
    
    // in getLocationForState:
      OptValue<hbc::DebugSourceLocation> getLocationForState(
          const InterpreterState &state) const {
        if (state.codeBlock == nullptr)
          return llvh::None;
        return state.codeBlock->getSourceLocation(state.offset);
      }

    lib/VM/Debugger/Debugger.cpp (runDebugger, ~line 245) — prefer a pending async-trigger reason over synthesizing StepFinish, which fixes the spurious "paused in debugger":

            // Done stepping.
            pauseReason = asyncTriggerPauseReason_
                ? *asyncTriggerPauseReason_
                : PauseReason::StepFinish;
            curStepMode_ = llvh::None;
            asyncTriggerPauseReason_ = llvh::None;

    Verification (real, on-device — not a synthetic CDP handshake): I built RN + Hermes from source with all three hunks compiled into libhermesvm.so, installed on a physical arm64 device, attached RN DevTools, set a breakpoint in app JS, and it paused, and I stepped through, with no SIGSEGV — and no spurious "paused in debugger". Without the patch, the same sequence crashes reliably. (Method note because it burned me early: a synthetic Runtime.enable / Debugger.enable handshake does not reliably reproduce this — only a real breakpoint that resolves a source location does.)

    So this is now confirmed by two independent parties on the same RN 0.85.3 / Hermes v0.16.0 setup, on both platforms (@Elehiggle on iOS + Android, me on Android). The fix is in sdks/hermes, so it has to land in facebook/hermes and be pulled into RN on a version bump — patch-package can't reach it because Hermes is compiled from a downloaded source tarball at build time.

    Given a full root-cause + a verified fix + independent confirmation, could this be reopened / triaged? Happy to provide symbolicated stacks or test against a maintainer-preferred minimal repro.

  16. removed
    StaleThere has been a lack of activity on this issue and it may be closed soon.
    on Jul 9, 2026
  17. alpha0010 commented on Jul 14, 2026

    @alpha0010
    Contributor

    @Mootzali Are you able to write up this issue in the hermes repo https://github.com/facebook/hermes/issues ? That might help get visibility from the correct devs. (I had started trying to submit an issue there myself, but realized I just do not have a good grasp of the internals to describe it very well.)

  18. joeahn95 commented on Jul 15, 2026

    @joeahn95

    +1

    • Consistent crashes on RN 0.85.3 + iOS when devtools are connected
    • Crash does not occur when Hermes v0 is enabled
    • Can confirm @Mootzali's patch removed crashes on my setup. Hopefully a fix comes out in following versions.
  19. Mootzali commented on Jul 18, 2026

    @Mootzali

    @Mootzali Are you able to write up this issue in the hermes repo https://github.com/facebook/hermes/issues ? That might help get visibility from the correct devs. (I had started trying to submit an issue there myself, but realized I just do not have a good grasp of the internals to describe it very well.)

    @alpha0010
    Thanks for the suggestion. I'll put together an issue in the Hermes repo when I get a chance, hopefully sometime next weekend. That should give the right developers a better chance to take a look.

  20. Sarvesh0007 commented on Jul 18, 2026

    @Sarvesh0007

    I am facing the same issue of crash after moving to Expo SDK 57 only when the (DevTools are open)
    React-native version: 0.86.0
    Expo SDK version: 57.0.0
    React version: 19.2.3

  21. Mootzali commented on Jul 18, 2026

    @Mootzali

    @Sarvesh0007

    Could you try the workflow I shared earlier and let me know the results?

  22. lorenc-tomasz commented on Aug 6, 2026

    @lorenc-tomasz

    Tested facebook/hermes#2119 fix on RN 0.86.2 with Expo 57 and it seems to be working fine :)

  23. christian-apollo commented on Aug 6, 2026

    @christian-apollo

    Since this is tagged Needs: Repro — here is a repro that needs no DevTools UI, hit today on RN 0.86.2 / prebuilt hermes-engine 250829098.0.16 (iOS simulator, arm64, New Arch/Bridgeless). Root cause matches facebook/hermes#2118 (null preStepState_.codeBlock deref in Debugger::runUntilValidPauseLocation; the getSourceLocation frames are inlined in the prebuilt binary).

    1. Run any app with ongoing JS work — periodic timers or a Reanimated animation is enough.
    2. Save as oneshot.js, then:
      node oneshot.js "$(curl -s http://localhost:8081/json | python3 -c "import json,sys; print(json.load(sys.stdin)[0]['webSocketDebuggerUrl'])")"
      
    3. Repeat every few seconds. SIGSEGV at 0x0 on the JS thread — sometimes tens of seconds after the last socket closed (the poisoned step state outlives the session), sometimes after the first cycle, not deterministic.
    // oneshot.js — one CDP connect / evaluate / disconnect
    const WebSocket = require('ws');
    const ws = new WebSocket(process.argv[2], {headers: {Origin: 'http://localhost:8081'}});
    ws.on('open', () => ws.send(JSON.stringify({id: 1, method: 'Runtime.evaluate', params: {expression: '1+1', returnByValue: true}})));
    ws.on('message', () => ws.close());
    ws.on('close', () => process.exit(0));

    Crash signature from the .ips:

    Thread N Crashed :: com.facebook.react.runtime.JavaScript
    EXC_BAD_ACCESS (SIGSEGV), KERN_INVALID_ADDRESS at 0x0000000000000000
    hermes::vm::Debugger::runUntilValidPauseLocation(hermes::vm::InterpreterState&) + 135
    hermes::vm::Debugger::runDebugger(hermes::vm::Debugger::RunReason, hermes::vm::InterpreterState&) + 1434
    hermes::vm::Interpreter::interpretFunction<false, false>(...) + 14871
    
  24. react-native-bot commented on Aug 31, 2026

    @react-native-bot
    Collaborator

    This issue is waiting for author's feedback since 24 days. Please provide the requested feedback or this will be closed in 7 days.

  25. added
    StaleThere has been a lack of activity on this issue and it may be closed soon.
    on Aug 31, 2026
  26. react-native-bot commented on Sep 7, 2026

    @react-native-bot
    Collaborator

    This issue was closed because the author hasn't provided the requested feedback after 7 days.

  27. removed
    StaleThere has been a lack of activity on this issue and it may be closed soon.
    on Sep 7, 2026
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: Author FeedbackNeeds: 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