Skip to content

SourceMap Configuration


Sourcemap (source mapping) is used to map the compressed code in the production environment back to the original source code. RUM supports this source file information mapping by zipping and uploading the corresponding symbol table files, which can automatically convert the error measurement data reported.

Zip Package Packaging Instructions

Zip compress and package the .map files generated after js files are obfuscated and compressed by webpack. It must be ensured that the file path after decompressing the zip package matches the URL path in the error_stack. Assuming the following error_stack:

ReferenceError
  at a.hideDetail @ http://localhost:8080/static/js/app.7fb548e3d065d1f48f74.js:1:1037
  at a.showDetail @ http://localhost:8080/static/js/app.7fb548e3d065d1f48f74.js:1:986
  at <anonymous> @ http://localhost:8080/static/js/app.7fb548e3d065d1f48f74.js:1:1174

The path that needs to be converted is /static/js/app.7fb548e3d065d1f48f74.js, with its corresponding sourcemap path being /static/js/app.7fb548e3d065d1f48f74.js.map. Therefore, the directory structure after decompressing the corresponding zip package should be as follows:

sourcemap.zip
└──static/
    └── js
    └── app.7fb548e3d065d1f48f74.js.map

Converted error_stack_source:

ReferenceError
  at a.hideDetail @ webpack:///src/components/header/header.vue:94:0
  at a.showDetail @ webpack:///src/components/header/header.vue:91:0
  at <anonymous> @ webpack:///src/components/header/header.vue:101:0

The packaging method is basically the same as Web.

Android currently has two types of sourcemap files: one is the mapping file generated after Java bytecode is compressed and obfuscated by R8/Proguard, and the other is the (unstripped) .so file containing the symbol table and debugging information when compiling C/C++ native code. If your Android application contains both types of sourcemap files, both types of files need to be packaged into the zip package when packaging. The directory structure after decompressing the zip package is similar to:

sourcemap.zip
├── mapping.txt
├── armeabi-v7a/
│   ├── libgameengine.so
│   ├── libothercode.so
│   └── libvideocodec.so
├── arm64-v8a/
│   ├── libgameengine.so
│   ├── libothercode.so
│   └── libvideocodec.so
├── x86/
│   ├── libgameengine.so
│   ├── libothercode.so
│   └── libvideocodec.so
└── x86_64/
    ├── libgameengine.so
    ├── libothercode.so
    └── libvideocodec.so

By default, the mapping file will be located in: <project folder>/<Module>/build/outputs/mapping/<build-type>/, while .so files will be in: <project folder>/<Module>/build/intermediates/cmake/debug/obj/ when using CMake to compile the project, or in: <project folder>/<Module>/build/intermediates/ndk/debug/obj/ (debug compilation) or <project folder>/<Module>/build/intermediates/ndk/release/obj/ (release compilation) when using NDK.

The conversion effect is as follows:

Original error_stack:

java.lang.ArithmeticException: divide by zero
    at prof.wang.activity.TeamInvitationActivity.o0(Unknown Source:1)
    at prof.wang.activity.TeamInvitationActivity.k0(Unknown Source:0)
    at j9.f7.run(Unknown Source:0)
    at java.lang.Thread.run(Thread.java:1012)

Converted error_stack_source:

java.lang.ArithmeticException: divide by zero
at prof.wang.activity.TeamInvitationActivity.onClick$lambda-0(TeamInvitationActivity.java:1)
at java.lang.Thread.run(Thread.java:1012)

Original error_stack:

backtrace:
#00 pc 00000000000057fc  /data/app/~~Taci3mQyw7W7iWT7Jxo-ag==/com.ft-Q8m2flQFG1MbGImPiuAZmQ==/lib/arm64/libft_native_exp_lib.so (xc_test_call_4+12)
#01 pc 00000000000058a4  /data/app/~~Taci3mQyw7W7iWT7Jxo-ag==/com.ft-Q8m2flQFG1MbGImPiuAZmQ==/lib/arm64/libft_native_exp_lib.so (xc_test_call_3+8)
#02 pc 00000000000058b4  /data/app/~~Taci3mQyw7W7iWT7Jxo-ag==/com.ft-Q8m2flQFG1MbGImPiuAZmQ==/lib/arm64/libft_native_exp_lib.so (xc_test_call_2+12)
#03 pc 00000000000058c4  /data/app/~~Taci3mQyw7W7iWT7Jxo-ag==/com.ft-Q8m2flQFG1MbGImPiuAZmQ==/lib/arm64/libft_native_exp_lib.so (xc_test_call_1+12)
#04 pc 0000000000005938  /data/app/~~Taci3mQyw7W7iWT7Jxo-ag==/com.ft-Q8m2flQFG1MbGImPiuAZmQ==/lib/arm64/libft_native_exp_lib.so (xc_test_crash+112)
...

Converted error_stack_source:

backtrace:

Abort message: 'abort message for ftNative internal testing'
#00 0x00000000000057fc /data/app/~~Taci3mQyw7W7iWT7Jxo-ag==/com.ft-Q8m2flQFG1MbGImPiuAZmQ==/lib/arm64/libft_native_exp_lib.so (xc_test_call_4+12)
xc_test_call_4
/Users/Brandon/Documents/workplace/working/StudioPlace/xCrash/xcrash_lib/src/main/cpp/xcrash/xc_test.c:65:9
#01 0x00000000000058a4 /data/app/~~Taci3mQyw7W7iWT7Jxo-ag==/com.ft-Q8m2flQFG1MbGImPiuAZmQ==/lib/arm64/libft_native_exp_lib.so (xc_test_call_3+8)
xc_test_call_3
/Users/Brandon/Documents/workplace/working/StudioPlace/xCrash/xcrash_lib/src/main/cpp/xcrash/xc_test.c:73:13
#02 0x00000000000058b4 /data/app/~~Taci3mQyw7W7iWT7Jxo-ag==/com.ft-Q8m2flQFG1MbGImPiuAZmQ==/lib/arm64/libft_native_exp_lib.so (xc_test_call_2+12)
xc_test_call_2
/Users/Brandon/Documents/workplace/working/StudioPlace/xCrash/xcrash_lib/src/main/cpp/xcrash/xc_test.c:79:13
#03 0x00000000000058c4 /data/app/~~Taci3mQyw7W7iWT7Jxo-ag==/com.ft-Q8m2flQFG1MbGImPiuAZmQ==/lib/arm64/libft_native_exp_lib.so (xc_test_call_1+12)
xc_test_call_1
/Users/Brandon/Documents/workplace/working/StudioPlace/xCrash/xcrash_lib/src/main/cpp/xcrash/xc_test.c:85:13
#04 0x0000000000005938 /data/app/~~Taci3mQyw7W7iWT7Jxo-ag==/com.ft-Q8m2flQFG1MbGImPiuAZmQ==/lib/arm64/libft_native_exp_lib.so (xc_test_crash+112)
xc_test_crash
/Users/Brandon/Documents/workplace/working/StudioPlace/xCrash/xcrash_lib/src/main/cpp/xcrash/xc_test.c:126:9
...

On the iOS platform, the sourcemap file is a symbol table file with a .dSYM extension that contains debugging information. In general, it is located in the same directory as the .app file after the project is compiled, as shown below:

$ ls -l Build/Products/Debug-iphonesimulator/
total 0
drwxr-xr-x   6 zy  staff  192  8  9 15:27 Fishing.app
drwxr-xr-x   3 zy  staff   96  8  9 14:02 Fishing.app.dSYM
drwxr-xr-x  15 zy  staff  480  8  9 15:27 Fishing.doccarchive
drwxr-xr-x   6 zy  staff  192  8  9 13:55 Fishing.swiftmodule

Note that XCode Release compilation generates .dSYM files by default, but Debug compilation does not generate them by default. The following settings need to be made for XCode:

Build Settings -> Code Generation -> Generate Debug Symbols -> Yes
Build Settings -> Build Option -> Debug Information Format -> DWARF with dSYM File

When performing zip packaging, simply package the corresponding .dSYM files into the zip package. If your project involves multiple .dSYM files, they need to be packaged together into the zip package. Afterwards, copy the zip package to <DataKit installation directory>/data/rum/ios. The directory structure after decompressing the zip package is similar to the following (.dSYM files are essentially directories, similar to macOS executable programs .app):

sourcemap.zip
├── AFNetworking.framework.dSYM
│   └── Contents
│       ├── Info.plist
│       └── Resources
│           └── DWARF
│               └── AFNetworking
└── App.app.dSYM
    └── Contents
        ├── Info.plist
        └── Resources
            └── DWARF
                └── App

The sourcemap for React Native includes native iOS, Android, and js parts, resulting in three types of source maps.

For native iOS and Android sourcemap acquisition, refer to the methods provided in the corresponding packaging instructions.

To obtain the js part of the sourcemap, follow these steps:

Android source mapping is enabled by default. The source map file is located at android/app/build/generated/sourcemaps/react/release/index.android.bundle.map

iOS requires additional configuration to enable source map generation. Open Xcode and edit the build phase item "Bundle React Native code and images". Above the other export items, add an entry SOURCEMAP_FILE with the required output path.

set -e
#  output source maps
export SOURCEMAP_FILE="./main.jsbundle.map";

With Hermes, React Native <0.71

set -e
#  output source maps
export SOURCEMAP_FILE="./main.jsbundle.map";
#  React Native 0.70, you need to set USE_HERMES to true if Hermes is used, otherwise the source maps won't be generated.
export USE_HERMES=true 

# keep the rest of the script unchanged

# When React Native (0.69,0.71) and using Hermes
# add these lines to compose the packager and compiler source maps into one file
REACT_NATIVE_DIR=../node_modules/react-native

if [ -f "$REACT_NATIVE_DIR/scripts/find-node-for-xcode.sh" ]; then
    source "$REACT_NATIVE_DIR/scripts/find-node-for-xcode.sh"
else
    # Before RN 0.70, the script was named find-node.sh
    source "$REACT_NATIVE_DIR/scripts/find-node.sh"
fi
source "$REACT_NATIVE_DIR/scripts/node-binary.sh"
"$NODE_BINARY" "$REACT_NATIVE_DIR/scripts/compose-source-maps.js" "$CONFIGURATION_BUILD_DIR/main.jsbundle.map" "$CONFIGURATION_BUILD_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH/main.jsbundle.map" -o "../$SOURCEMAP_FILE"

After obtaining the js sourcemap file, zip it together with the corresponding native sourcemap according to the format below.

// Android
sourcemap.zip
├── js/
    ├── main.jsbundle.map 
└── android/
    ├── mapping.txt
    ├── armeabi-v7a/
    │   ├── libgameengine.so
    │   ├── libothercode.so
    │   └── libvideocodec.so
    └── arm64-v8a/
        ├── libgameengine.so
        ├── libothercode.so
        └── libvideocodec.so    
// iOS
sourcemap.zip
├── js/
    ├── main.jsbundle.map 
└── ios/
    ├── AFNetworking.framework.dSYM
    │   └── Contents
    │       ├── Info.plist
    │       └── Resources
    │           └── DWARF
    │               └── AFNetworking
    └── App.app.dSYM
        └── Contents
            ├── Info.plist
            └── Resources
                └── DWARF
                    └── App

You can use tools like source-map-visualization for source mapping visualization to verify the availability of the files.

File Upload and Deletion

After completing the configuration and packaging, users can go to the frontend page [Synthetic Tests] > [Application List] > [Click the more icon in the top right corner of the uploaded application] > [SourceMap] to perform file upload and deletion operations. Please ensure that the current account has "Edit" or higher permissions.

Below the 🔍 bar, you can view the names of uploaded files and the application type. You may search by entering the file name; clicking deletes the current file.

Upload Notes:

  1. File size cannot exceed 500M;
  2. File format must be .zip;
  3. Ensure that the file paths after decompressing the zip package match the URL paths in the error_stack;
  4. Do not upload multiple files simultaneously;
  5. Uploading files with the same name will result in an overwrite prompt, please be cautious.

In addition, Datakit collector configuration supports SourceMap conversion.

For more details, see SourceMap Conversion.

Feedback

Is this page helpful? ×