Stay organized with collections
Save and categorize content based on your preferences.
By default, native code libraries are stripped in release builds of your app.
This stripping consists of removing the symbol table and debugging information
contained in any native libraries used by your app. Stripping native code
libraries results in significant size savings; however, it's impossible to
diagnose crashes on the Google Play Console due to the missing information (such
as class and function names). To debug crashes, you must include a debug symbols
file with your app in Play Console.
Upload a symbols file
The Google Play Console reports native crashes under Android
vitals. With a few steps, you
can generate and upload a native debug symbols file for your app. This file
enables symbolicated native crash stack traces (that include class and function
names) in Android vitals to help you debug your app in production. These steps
vary depending on the version of the Android Gradle plugin used in your project
and whether you're using an Android App Bundle (recommended) or APK.
Android Gradle plugin version 4.1 or later
If your project builds an Android App Bundle (AAB), you can configure your build
to automatically include the native debug symbols file in the AAB so it's
uploaded to the Play Console when you publish your app. To include this file in
release builds, add the following to your app's build.gradle.kts file:
android.buildTypes.release.ndk.debugSymbolLevel = { SYMBOL_TABLE | FULL }
Select the debug symbol level from the following:
Use SYMBOL_TABLE to get function names in the Play Console's symbolicated
stack traces. This level supports
tombstones.
Use FULL to get function names, files, and line numbers in the Play
Console's symbolicated stack traces.
If your project builds an APK, use the
android.buildTypes.release.ndk.debugSymbolLevel setting shown earlier to
generate the native debug symbols file separately. Manually upload the native
debug symbols
file
to the Google Play Console (the process is similar to uploading a mapping file
to deobfuscate stack traces).
As part of the build process, the Android Gradle plugin outputs this file in the
following project location:
Android Gradle plugin version 4.0 or earlier (and other build systems)
As part of the build process, the Android Gradle plugin keeps a copy of the
unstripped libraries in a project directory. This directory structure is similar
to the following:
Content and code samples on this page are subject to the licenses described in the Content License. Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.
Last updated 2025-05-30 UTC.
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2025-05-30 UTC."],[],[],null,["# Include native symbols in your release build\n\nBy default, native code libraries are stripped in release builds of your app.\nThis stripping consists of removing the symbol table and debugging information\ncontained in any native libraries used by your app. Stripping native code\nlibraries results in significant size savings; however, it's impossible to\ndiagnose crashes on the Google Play Console due to the missing information (such\nas class and function names). To debug crashes, you must include a debug symbols\nfile with your app in Play Console.\n\nUpload a symbols file\n---------------------\n\nThe Google Play Console reports native crashes under [Android\nvitals](/topic/performance/vitals/crash#diagnose-crashes). With a few steps, you\ncan generate and upload a native debug symbols file for your app. This file\nenables symbolicated native crash stack traces (that include class and function\nnames) in Android vitals to help you debug your app in production. These steps\nvary depending on the version of the Android Gradle plugin used in your project\nand whether you're using an Android App Bundle (recommended) or APK.\n| **Note:** To restore symbol names in crash reports yourself, use the [ndk-stack\n| tool](/ndk/guides/ndk-stack), which comes packaged with the Android NDK.\n\n### Android Gradle plugin version 4.1 or later\n\nIf your project builds an Android App Bundle (AAB), you can configure your build\nto automatically include the native debug symbols file in the AAB so it's\nuploaded to the Play Console when you publish your app. To include this file in\nrelease builds, add the following to your app's `build.gradle.kts` file:\n\n`android.buildTypes.release.ndk.debugSymbolLevel = { SYMBOL_TABLE | FULL }`\n\nSelect the debug symbol level from the following:\n\n- Use `SYMBOL_TABLE` to get function names in the Play Console's symbolicated stack traces. This level supports [tombstones](https://source.android.com/devices/tech/debug).\n- Use `FULL` to get function names, files, and line numbers in the Play Console's symbolicated stack traces.\n\n| **Note:** There is a 300 MB limit for the native debug symbols file. If your debug symbols footprint is too large, use `SYMBOL_TABLE` instead of `FULL` to decrease the file size.\n\nIf your project builds an APK, use the\n`android.buildTypes.release.ndk.debugSymbolLevel` setting shown earlier to\ngenerate the native debug symbols file separately. Manually [upload the native\ndebug symbols\nfile](https://support.google.com/googleplay/android-developer/answer/9848633#upload_file)\nto the Google Play Console (the process is similar to uploading a mapping file\nto [deobfuscate stack traces](/topic/performance/app-optimization/test-and-troubleshoot-the-optimization#recover-original-stack-trace)).\nAs part of the build process, the Android Gradle plugin outputs this file in the\nfollowing project location:\n\n`app/build/outputs/native-debug-symbols/\u003cvar\u003evariant-name\u003c/var\u003e/native-debug-symbols.zip`\n\n### Android Gradle plugin version 4.0 or earlier (and other build systems)\n\nAs part of the build process, the Android Gradle plugin keeps a copy of the\nunstripped libraries in a project directory. This directory structure is similar\nto the following: \n\n app/build/intermediates/cmake/universal/release/obj/\n ├── armeabi-v7a/\n │ ├── libgameengine.so\n │ ├── libothercode.so\n │ └── libvideocodec.so\n ├── arm64-v8a/\n │ ├── libgameengine.so\n │ ├── libothercode.so\n │ └── libvideocodec.so\n ├── x86/\n │ ├── libgameengine.so\n │ ├── libothercode.so\n │ └── libvideocodec.so\n └── x86_64/\n ├── libgameengine.so\n ├── libothercode.so\n └── libvideocodec.so\n\n| **Note:** If you use a different build system, you could modify it to store unstripped libraries in a directory with the required structure.\n\n1. Zip up the contents of this directory:\n\n cd app/build/intermediates/cmake/universal/release/obj\n zip -r symbols.zip .\n\n2. Manually [upload the `symbols.zip` file](https://support.google.com/googleplay/android-developer/answer/9848633#upload_file) to the Google Play Console.\n\n| **Note:** If your file is too big, it's likely because your `.so` files contain a symbol table and also DWARF debugging info, which isn't needed to symbolicate your code. On AGP 4.0 or lower, you can remove the DWARF debugging info by running the following command: \n|\n| `$OBJCOPY --strip-debug lib.so lib.so.sym` \n|\n| where `$OBJCOPY` points to the specific version for the ABI you're stripping (for example, `ndk-bundle/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-objcopy`). This command is equivalent to the [`SYMBOL_TABLE` option for AGP 4.1 and higher](#agp-4.1)."]]