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_modules07-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:13216107-15 10:58:25.820 18979 18998 E AndroidRuntime: p@1:13208407-15 10:58:25.820 18979 18998 E AndroidRuntime: f@1:13185407-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 logcat
directly:
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 used 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.