Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 97 additions & 0 deletions docs/debugging-release-builds.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
---
id: debugging-release-builds
title: Debugging Release Builds
---

import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import constants from '@site/core/TabsConstants';

## 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.

```shell
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
```

In the above stack trace, entries like `p@1:132161` are minified function names and bytecode offsets. To debug these calls, we want to translate these into file, line, and function name, e.g. `AwesomeProject/App.js:54:initializeMap`. This is known as **symbolication.**

You can symbolicate minified function names and bytecode like the above by passing the stack trace and a generated source map to [`metro-symbolicate`](https://npmjs.com/package/metro-symbolicate).

### Enabling source maps

Source maps are required to symbolicate stack traces. Make sure that source maps are enabled within the build config for the target platform.

<Tabs groupId="platform" queryString defaultValue={constants.defaultPlatform} values={constants.platforms} className="pill-tabs">
<TabItem value="android">

:::info
On Android, source maps are **enabled** by default.
:::

To enable source map generation, ensure the following `hermesFlags` are present in `android/app/build.gradle`.

```groovy
react {
hermesFlags = ["-O", "-output-source-map"]
}
```

If done correctly you should see the output location of the source map during Metro build output.

```text
Writing bundle output to:, android/app/build/generated/assets/react/release/index.android.bundle
Writing sourcemap output to:, android/app/build/intermediates/sourcemaps/react/release/index.android.bundle.packager.map
```

</TabItem>
<TabItem value="ios">

:::info
On iOS, source maps are **disabled** by default. Use the following instructions to enable them.
:::

To enable source map generation:

- Open Xcode and edit the build phase "Bundle React Native code and images".
- Above the other exports, add a `SOURCEMAP_FILE` entry with the desired output path.

```diff
+ SOURCEMAP_FILE="$(pwd)/../main.jsbundle.map";
WITH_ENVIRONMENT="../node_modules/react-native/scripts/xcode/with-environment.sh"
```

If done correctly you should see the output location of the source map during Metro build output.

```text
Writing bundle output to:, Build/Intermediates.noindex/ArchiveIntermediates/application/BuildProductsPath/Release-iphoneos/main.jsbundle
Writing sourcemap output to:, Build/Intermediates.noindex/ArchiveIntermediates/application/BuildProductsPath/Release-iphoneos/main.jsbundle.map
```

</TabItem>
</Tabs>

### Using `metro-symbolicate`

With source maps being generated, we can now translate our stack traces.

```shell
# Print usage instructions
npx metro-symbolicate

# From a file containing the stack trace
npx metro-symbolicate android/app/build/generated/sourcemaps/react/release/index.android.bundle.map < stacktrace.txt

# From adb logcat (Android)
adb logcat -d | npx metro-symbolicate android/app/build/generated/sourcemaps/react/release/index.android.bundle.map
```

### Notes on source maps

- 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.
2 changes: 1 addition & 1 deletion docs/profile-hermes.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ npx react-native profile-hermes [destinationDir]
### Enabling source map

:::info
You may read about source maps on the [source maps](sourcemaps.md) page.
You may read about source maps on the [Debugging Release Builds](debugging-release-builds.md) page.
:::

### Common errors
Expand Down
82 changes: 0 additions & 82 deletions docs/sourcemaps.md

This file was deleted.

39 changes: 0 additions & 39 deletions docs/symbolication.md

This file was deleted.

5 changes: 2 additions & 3 deletions website/sidebars.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@
"running-on-device",
"fast-refresh",
"metro",
"symbolication",
"sourcemaps",
"libraries",
"typescript",
"upgrading"
Expand Down Expand Up @@ -64,7 +62,8 @@
"Debugging": [
"debugging",
"react-devtools",
"native-debugging"
"native-debugging",
"debugging-release-builds"
],
"Testing": [
"testing-overview"
Expand Down
2 changes: 2 additions & 0 deletions website/static/_redirects
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
/docs/building-for-apple-tv /docs/building-for-tv
/docs/building-from-source /contributing/how-to-build-from-source
/docs/contributing /contributing/overview
/docs/next/sourcemaps /docs/next/debugging-release-builds
/docs/next/symbolication /docs/next/debugging-release-builds
/docs/publishing-forks /contributing/how-to-build-from-source#publish-your-own-version-of-react-native
/docs/testing /contributing/how-to-run-and-write-tests
/docs/understanding-cli https://github.com/react-native-community/cli#react-native-cli
Expand Down