Skip to main content
Version: 0.69

Symbolicating a stack trace

If a React Native app throws an unhandled exception in a release build, the output may be obfuscated and hard to read:

07-15 10:58:25.820 18979 18998 E AndroidRuntime: FATAL EXCEPTION: mqt_native_modules
07-15 10:58:25.820 18979 18998 E AndroidRuntime: Process: com.awesomeproject, PID: 18979 07-15 10:58:25.820 18979 18998 E AndroidRuntime: com.facebook.react.common.JavascriptException: Failed, js engine: hermes, stack:
07-15 10:58:25.820 18979 18998 E AndroidRuntime: p@1:132161
07-15 10:58:25.820 18979 18998 E AndroidRuntime: p@1:132084
07-15 10:58:25.820 18979 18998 E AndroidRuntime: f@1:131854
07-15 10:58:25.820 18979 18998 E AndroidRuntime: anonymous@1:131119

The sections like p@1:132161 are minified function names and bytecode offsets. To debug the problem, you would instead want to translate it into file, line and function name: AwesomeProject/App.js:54:initializeMap. This is known as symbolication. You can symbolicate minified function names and bytecode like the above by passing metro-symbolicate a generated source map and the stack trace.

The metro-symbolicate package is installed by default in the React Native template project from setting up your development environment.

From a file containing the stacktrace:

npx metro-symbolicate android/app/build/generated/sourcemaps/react/release/index.android.bundle.map < stacktrace.txt

From adb logcatdirectly:

adb logcat -d | npx metro-symbolicate android/app/build/generated/sourcemaps/react/release/index.android.bundle.map

This will turn each minified function name and offset like p@1:132161 into the actual file- and function name AwesomeProject/App.js:54:initializeMap.

Notes on Sourcemaps

  • Multiple source maps may be generated by the build process. Make sure to use the one in the location shown in the examples.
  • Make sure that the source map you use corresponds to the exact commit of the crashing app. Small changes in source code can cause large differences in offsets.
  • If metro-symbolicate exits immediately with success, make sure the input comes from a pipe or redirection and not from a terminal.