NDK Symbols
For Android applications, when native code is used it will be compiled into shared object files, usually with the symbol names removed. In order to replace the obfuscated data with a human-readable stacktrace, a shared object (.so
) file containing those symbols is required.
Use the POST /ndk-symbol endpoint to upload shared object files from your build.
Compatibility
To use this API you will need:
a compatible version of the BugSnag library in your app:
(for On-premise) to be using a recent version of the Upload API (v3.2211.0+ single machine or v5.2211.0+ of clustered)
If you cannot use the latest API you need to use the legacy endpoint, see Legacy API.
cURL example
Extracting symbols
The intermediate shared object files generated for an Android NDK build will contain the symbols. Since only symbols are required, it is recommend that you remove the executable code in order to reduce file size.
To check whether a shared object file contains debug symbols, run the file
command with the path to the shared object file. The output will include stripped
if the file has been stripped of debug symbols, and debug_info, not stripped
if it contains debug symbols.
To extract symbols from a full shared object file that contains executable code and symbols, run the objcopy
command with the following parameters:
If you do not have an objcopy
in your path you will be able to find one using find $ANDROID_HOME/ndk -iname "*objcopy"
on macOS, Linux, and Cygwin. Note that for NDK version 23 and higher you should use llvm-objcopy
while for version 22 and lower you must use objcopy
(which is GNU objcopy).
Symbolication guide
See our symbolication guide for a higher-level overview of integrating uploads into your build systems to see full stacktraces for all your releases.
Legacy API
As noted above, the /so-symbol
endpoint is for use if your tooling is not compatible with the /ndk-symbol
endpoint.
There are two different types of mapping file that can be used to map a stack trace depending on what debug information is available in the shared object file:
- symbol mapping file: Contains all of the debug information required to map back to the original file, line and method.
- symbol table mapping file: Contains the information required to map back to the original method only.
In general the intermediate shared object files generated for an Android NDK build should contain the required details for a symbol mapping file but the shared object files generated for some native Android libraries, for example Unity libraries, will only contain the information for a symbol table mapping file.
Uploading symbol mapping files
To upload symbol mapping files, POST
them to the /so-symbol
endpoint of the upload server with the following parameters:
soSymbolFile
– the path to the shared object mapping file.apiKey
– your BugSnag integration API key for this application.appId
– the AndroidapplicationId
for this application.versionCode
– the AndroidversionCode
for this application release.arch
– the architecture of the shared object that the symbols are for (e.g. x86, armeabi-v7a).sharedObjectName
– the name of the shared object that the symbols are for.versionName
(optional) – the AndroidversionName
for this application release.projectRoot
(optional) – a path to remove from the beginning of the filenames in the mapping filebuildUUID
(optional) – a UUID to identify this builds. This is required if you build multiple different apps with the sameappId
andversionCode
. If you use this, you’ll also need to set thecom.bugsnag.android.BUILD_UUID
value in yourAndroidManifest.xml
.overwrite
(optional) – overwrite any existing mappings for this version of your app.
If you are creating the shared object mapping files without using the BugSnag Android Gradle plugin then you must run the objdump
command with the following parameters and save the output to a file:
Locate the correct objdump
binary for a given architecture using find $ANDROID_HOME/ndk-bundle -iname "*objdump"
on macOS, Linux, and Cygwin.
Note – objdump
is not included in the NDK v23 and up. If you are using a more recent version of the NDK then we recommend using the non-legacy API endpoint above.
The output should look something like:
If the output does not look like this it may be due to the objdump
command being run on a shared object file where the debug symbols have been stripped. The command needs to be run against an intermediate shared object file that is output from the build process before the symbols are stripped.
If the intermediate shared object files don’t produce output like this, it may be the case that the full debug information isn’t available. In some cases (e.g. with native Android Unity libraries) it may be possible to extract the symbol table from the shared object file so that the method names can be mapped. See the Uploading symbol table mapping files section for how to generate and upload these mappings.
The API also supports uploading compressed mapping files. For example, to compress the file using gzip:
Here’s an example request with curl:
If the file is accepted then an HTTP 200 response will be returned with the body “OK”.
If not, there are several possible problems which will be indicated with an HTTP 4XX response:
- duplicate shared object file – indicates that the file has already been uploaded. You can ignore this error by using the buildUUID parameter, or by using the overwrite parameter.
- invalid apiKey – indicates that the provided apiKey doesn’t correspond to an Insight Hub project.
- missing param – indicates that the
appId
orversionCode
parameters are missing. - Mapping file does not contain any debug info or lines – indicates that the mapping file is not in the correct format.
- Mapping file does not contain a debug info section – indicates that the debug_info section is missing (normally if
--dwarf=info
wasn’t passed toobjdump
). - Mapping file does not contain a debug lines section – indicates that the debug_line section is missing (normally if
--dwarf=rawline
wasn’t passed toobjdump
).
Uploading symbol table mapping files
In some cases the shared object files don’t contain the full debug information required to map back to the original file, line and method but they do contain a symbol table which can be used to map the method. This is normally the case for native Android libraries in Unity.
To upload symbol table mapping files, POST
them to the /so-symbol-table
endpoint of the upload server (see parameters for Uploading symbol mapping files).
If you are creating the shared object mapping files without using the BugSnag Android Gradle plugin then you must run the objdump
command with the following parameters and save the output to a file:
Locate the correct objdump
binary for a given architecture using find $ANDROID_HOME/ndk-bundle -iname "*objdump"
on macOS, Linux, and Cygwin.
Note – objdump
is not included in the NDK v23 and up. If you are using a more recent version of the NDK then we recommend using the non-legacy API endpoint above.
The output should look something like:
If the output does not look like this it may be due to the objdump
command being run on a shared object file where the all the debug symbols have been stripped. The command needs to be run against an intermediate shared object file that is output from the build process before the symbols are stripped. For native Android Unity libraries the shared object files with the symbol table within them normally have a .sym.so
file extension
The API also supports uploading compressed mapping files. For example, to compress the file using gzip:
Here’s an example request with curl:
If the file is accepted then an HTTP 200 response will be returned with the body “OK”.
If not, there are several possible problems which will be indicated with an HTTP 4xx response:
- duplicate shared object symbol table file – indicates that the file has already been uploaded. You can ignore this error by using the buildUUID parameter, or by using the overwrite parameter.
- invalid apiKey – indicates that the provided apiKey doesn’t correspond to an Insight Hub project.
- missing param – indicates that the
appId
orversionCode
parameters are missing. - mapping file does not contain a symbol table – indicates that the mapping file is not in the correct format.
- symbol table within mapping file does not contain function mappings – indicates that the symbol table doesn’t have any appropriate mappings. Often this is due to the symbols not being present in the shared object file.