facebook / react-native

A framework for building native applications using React
https://reactnative.dev
MIT License
117.72k stars 24.16k forks source link

App restarts / crashes when enabling remote debugging with RN 0.73.9 for Android #45399

Open Sushant-Sardeshpande opened 1 month ago

Sushant-Sardeshpande commented 1 month ago

Description

When enabling remote debugging using NativeDevSettings.setIsDebuggingRemotely(true) on Android the app keeps on restarting and eventually crashes.

Steps to reproduce

  1. Install the app using 'yarn android'
  2. Notice that the app will keep on restarting and eventually crash

React Native Version

0.73.9

Affected Platforms

Runtime - Android

Output of npx react-native info

info Fetching system and libraries information...
System:
  OS: macOS 14.5
  CPU: (10) arm64 Apple M2 Pro
  Memory: 93.36 MB / 16.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 20.15.0
    path: /usr/local/bin/node
  Yarn:
    version: 3.6.4
    path: /opt/homebrew/bin/yarn
  npm:
    version: 10.8.1
    path: /usr/local/bin/npm
  Watchman:
    version: 2024.01.22.00
    path: /opt/homebrew/bin/watchman
Managers:
  CocoaPods:
    version: 1.14.3
    path: /usr/local/bin/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 23.5
      - iOS 17.5
      - macOS 14.5
      - tvOS 17.5
      - visionOS 1.2
      - watchOS 10.5
  Android SDK:
    Android NDK: 24.0.8215888
IDEs:
  Android Studio: 2024.1 AI-241.15989.150.2411.11948838
  Xcode:
    version: 15.4/15F31d
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 17.0.10
    path: /usr/bin/javac
  Ruby:
    version: 2.6.10
    path: /usr/bin/ruby
npmPackages:
  "@react-native-community/cli": Not Found
  react:
    installed: 18.2.0
    wanted: 18.2.0
  react-native:
    installed: 0.73.9
    wanted: 0.73.9
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: false
  newArchEnabled: false
iOS:
  hermesEnabled: Not found
  newArchEnabled: false

Stacktrace or Logs

After some restarts it crashes with the exception:

FATAL EXCEPTION: mqt_js
                                                                                                    Process: com.androidjsc, PID: 9748
                                                                                                    java.lang.AssertionError: No source URL loaded, have you initialised the instance?
                                                                                                        at com.facebook.infer.annotation.Assertions.assertNotNull(Assertions.java:19)
                                                                                                        at com.facebook.react.modules.debug.SourceCodeModule.getTypedExportedConstants(SourceCodeModule.java:32)
                                                                                                        at com.facebook.fbreact.specs.NativeSourceCodeSpec.getConstants(NativeSourceCodeSpec.java:45)
                                                                                                        at com.facebook.react.bridge.JavaModuleWrapper.getConstants(JavaModuleWrapper.java:127)
                                                                                                        at com.facebook.jni.NativeRunnable.run(Native Method)
                                                                                                        at android.os.Handler.handleCallback(Handler.java:942)
                                                                                                        at android.os.Handler.dispatchMessage(Handler.java:99)
                                                                                                        at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.java:29)
                                                                                                        at android.os.Looper.loopOnce(Looper.java:201)
                                                                                                        at android.os.Looper.loop(Looper.java:288)
                                                                                                        at com.facebook.react.bridge.queue.MessageQueueThreadImpl$4.run(MessageQueueThreadImpl.java:234)
                                                                                                        at java.lang.Thread.run(Thread.java:1012)
2024-07-12 10:58:36.834  9748-9812  Process                 com.androidjsc

Reproducer

https://github.com/Sushant-Sardeshpande/androidRemoteDebugging/tree/main

Screenshots and Videos

No response

Sushant-Sardeshpande commented 1 month ago

Get the following log on the metro bundler:

Error: Unable to resolve module ./debugger-ui/debuggerWorker.aca173c4 from /Users/sushantsardeshpande/WebstormProjects/androidRemoteDebugging/ReproducerApp/.:

None of these files exist:

cortinico commented 1 month ago

FYI Remote JavaScript Debugging is deprecated, as you can see from:

https://reactnative.dev/docs/other-debugging-methods#remote-javascript-debugging-deprecated

cc @huntie

Sushant-Sardeshpande commented 1 month ago

Yup, we do plan to move to Hermes and use either the Hermes or Experimental debugger. However, as of now we did face some issues with date formats that were working with JSC but not Hermes, in case we face more issues we might want to keep using JSC for some more time. In which case I think for Android, remote debugging does seem to work better than adb or Flipper, at least for me.

Sushant-Sardeshpande commented 1 month ago

FYI Remote JavaScript Debugging is deprecated, as you can see from:

https://reactnative.dev/docs/other-debugging-methods#remote-javascript-debugging-deprecated

cc @huntie

Was doing some debugging, and realized that when it tried to reload it was always creating a new thread. PREFS_REMOTE_JS_DEBUG_KEY had been set but not used. In DevSupportManagerBase.java UiThreadUtil.runOnUiThread( () -> { mDevSettings.setRemoteJSDebugEnabled(isRemoteJSDebugEnabled); handleReloadJS(); });

Added a condition over it to read for the preference before starting another thread. if (mDevSettings.isRemoteJSDebugEnabled() != isRemoteJSDebugEnabled) { UiThreadUtil.runOnUiThread( () -> { mDevSettings.setRemoteJSDebugEnabled(isRemoteJSDebugEnabled); handleReloadJS(); }); } That seemed to do the trick for me. Not entirely sure if it would be the right way. Would appreciate if someone could confirm. Alternately I can assign it to a DevSettings button instead. Seems like because it always causes a reload, the issue happens if the component where this is invoked from is the landing component for the app.

jehillert commented 1 day ago

@cortinico Remote debugging is critical for a good developer experience and just because it is deprecated doesn't mean it should be allowed to break without a good substitute (i.e., not flipper).

Also, you guys have said "We will leave Remote JS Debugging deprecated, but not remove it until we have an full alternative ready for the community." Half of the appeal of our ecosystem are tools like the classic redux-devtools. That one tool alone has probably influenced billions of dollars of IT decisions. We had access to it, we updated, and now we don't. It's frustrating.

CC @huntie