How to Handle NDK Crashes
In this post, we’ll look at how to handle NDK crashes when using PSPDFKit for Android.
What Is NDK?
The Android NDK is a native development kit, and it allows you to develop Android apps using C/C++.
Here at PSPDFKit, the largest percentage of our codebase is written in C++. This helps us control the performance of our SDK and share code across the multiple platforms we support. However, it also increases the chances of a crash happening at the native level.
NDK Crash
When a native crash happens in your application, the crash logs won’t contain fully readable symbol names, but you’ll get a list of addresses that point to the location where the crash happened, similar to this:
pid: 1656, tid: 1656, name: crasher >>> crasher <<< signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr -------- r0 00000000 r1 00000678 r2 00000006 r3 f70b6dc8 ip 00000006 sp ff96ad18 lr f700ced5 pc f700dc98 cpsr 400b0010 backtrace: #00 pc 00042c98 libc.so #01 pc 00041ed1 libc.so #02 pc 00018d35 libpspdfkit.so #03 pc 00000f21 libpspdfkit.so #04 pc 00016795 libpspdfkit.so #05 pc 00000abc libpspdfkit.so
Sometimes the logs can look very different depending on the nature of the crash, but always look out for libpspdfkit.so
to be sure that the PSPDFKit library is involved in the crash.
Symbolicating Native Crashes
To make sense of these logs, you’ll need to convert them to a human-readable <source-file>:<line-number>
format, which is done via a process called symbolication.
You can follow the steps below to symbolicate a crash log.
1 — Go to the PSPDFKit Portal and download the unstripped native library symbols.
2 — Use the ndk-stack
tool of your local NDK as follows:
cat crash.dump | ndk-stack -sym PSPDFKit-for-Android-NDK-Debugging-Symbols-<version>/<arch>
Since symbols are different for each PSPDFKit version and CPU architecture, it’s necessary to provide a path to the appropriate symbols.
You can also read the logs directly from logcat:
adb logcat | ndk-stack -sym PSPDFKit-for-Android-NDK-Debugging-Symbols-<version>/<arch>
The steps above may be enough to help you solve the problem. However, if this process doesn’t return any data, you’re probably using a mini dump from Google Breakpad. In this case, please report the crash to our support team for further assistance.
Support
When you report the crash, you’ll be asked to provide the crash logs from logcat or a native crash mini dump file and information about the PSPDFKit version and CPU architecture where the crash happened.
You can define the path for crash dumps via PSPDFKit#setNativeCrashDumpPath
and download a mini dump from that path from your device using adb pull /path/to/crashDump
, as explained in our troubleshooting guides.
These dumps are in the Google Breakpad format and are also accepted by crash reporting services like Crashlytics. Uploading these dump files to the crash analytics servers may be configured differently, depending on the service you use.
Firebase Crashlytics
To provide the full native crash dump in the Google Breakpad mini dump file format, Firebase has a specific configuration. Please make sure you follow all the steps, as it differs slightly from the usual Firebase configuration.
When you reach step 5, follow the alternative way as explained in the Upload symbols for library modules and external dependencies section. For the unstrippedNativeLibsDir
, you can download the unstripped .so
files from the PSPDFKit Portal.
Conclusion
In this post, you saw how to handle native crashes when using PSPDFKit for Android. If you have more questions about native crash handling, feel free to contact us on support, and we’ll be happy to help.
Julius joined Nutrient in 2021 as an Android engineer and is now the Cross-Platform Team Lead. He has a passion for exploring new technologies and solving everyday problems. His daily tools are Dart and Flutter, which he finds fascinating. Outside of work, he enjoys movies, running, and weightlifting.