Bug reporting

If you experience a bug or crash you believe is related to PSPDFKit, please let us know.

Writing an SDK is hard. We need to interact with both platform frameworks (e.g. Apple, Google) and your application. There are many potential edge cases depending upon the app you’re building and the way you call our API. We have a large test suite and regularly write about testing on our blog, yet there will always be bugs. We usually have a fast turnaround time on issues, but there are several ways we can make the process of reproducing and fixing bugs more efficient.

We assume you’re using the latest version of Android Studio and the latest version of the PSPDFKit SDK. If you aren’t, please update first and verify that the bug still exists — thanks!

Checklist for Sending a Crash Report

  • Tell us about the crash rate. Is it a single crash? What percentage of users is affected?

  • Send us steps to reproduce the issue, if possible. If you can’t reproduce the issue — for example, if the bug was reported by one of your customers or captured via a crash reporting solution — please mention this as well. If the reproduction steps are a bit fuzzy, try to outline them as best as you can. Often, a video of the procedure that triggers the issue can help us too.

  • Attach application and system logs to your crash reports if possible. This makes finding the reason much easier.

  • Please don’t send screenshots of your code. Either send a runnable sample project or a code snippet as text.

  • If you have a sample project that can reproduce the crash, we can fix it.

  • Crashes in our SDK can originate from our code, your code, vendor code, or platform provider code. It isn’t feasible, nor is it possible, to act on every crash report we receive. However, we do our best in offering a stable and reliable software product, and therefore also constantly monitor and analyze crash reports from our own PDF Viewer apps as well.

Depending upon the category of the problem, there are various options that work best for reporting. Keep reading to find out more.

Incorrect/Partial Rendering

If there’s a PDF that doesn’t render correctly, please send us the file. Before submitting it, you should verify that the latest version of Adobe Acrobat renders the file correctly. We go to extreme lengths to ensure that even partly broken files are rendered as accurately as possible.

Additionally, you should let us know which particular device and OS you’ve tested with, as different devices and versions might have different settings and fonts installed.

API Issues

  • Send us a small, runnable example project that demonstrates the issue. You can start a new project or use one of the samples we provide as a base. Often, it also helps to first try a particular issue with the Catalog sample project (which you get in the PSPDFKit Portal as part of the download). This is because it can tell us if the issue occurs with our samples as well, or only in combination with your app.

  • Send us the entire project. Sometimes an issue is based on a complex set of conditions and you may have problems isolating them in a smaller sample project. In that case, we also accept the complete project as a last resort. As part of the license agreement, we have a standard NDA that covers such software exchanges, and we’ll destroy any material we’ve received once the issue has been resolved. Since projects are usually large, a link to a ZIP file uploaded via Dropbox works best. Please also send a demo user account if one is required.

Crashes

Stack traces that contain PSPDFKit methods contain obfuscated names of packages, classes, and methods. To allow us to quickly retrace the crash, please always send us the stack trace in plain text format, together with the PSPDFKit version number your app is using.

Obtaining Stack Traces

  • Crashes are usually emitted to Logcat. Please don’t make a screenshot of a Logcat view; plain text stack traces will help us investigate your problem faster.

  • If you can reproduce your crash while debugging:

    1. Add a breakpoint to the affected line.

    2. Click on the Get thread dump button.

    3. Click on the Export to Text File button in the newly opened Dump tab.

    4. Send us the generated file.

Generate thread dump

Third-Party Crash Reporting Services

We recommend using a third-party crash reporting service instead of relying solely on the Google Play Developer Console. This allows you to discover more issues and will lead to a more stable product and greater customer satisfaction. There are several services; the most common ones are Crashlytics/Fabric by Google (formerly Twitter) and Bugsee, which can also record a video leading up to the crash.

Providing Logs

While the stack trace is already helpful as a starting point, it lacks extra context. Without this extra information, fixing issues often becomes impossible, as any change would just be a shot in the dark. If you’re using a third-party crash reporting service, such as Crashlytics, you can enhance the crash reports you receive by including the logging output PSPDFKit produces. To do this, you can attach a custom Logger that will send the logs to the crash reporting service you’re using.

Below you’ll see how this would work with Crashlytics, but it would work similarly with any other crash reporting service:

PdfLog.addLogger { priority, tag, message, throwable ->
    // Add our log statement to the Crashlytics log.
    Crashlytics.log(priority, tag, message)
    // We also track handled exceptions so that we get a complete picture of what's going on.
    if (throwable != null) Crashlytics.logException(throwable)
}
PdfLog.addLogger((priority, tag, message, throwable) -> {
    // Add our log statement to the Crashlytics log.
    Crashlytics.log(priority, tag, message);
    // We also track handled exceptions so that we get a complete picture of what's going on.
    if (throwable != null) Crashlytics.logException(throwable);
});

NDK Crash Reports

If PSPDFKit is crashing natively (i.e. inside the native libraries), please provide us with a native crash dump. You can define the path for crash dumps via PSPDFKit#setNativeCrashDumpPath and download a minidump from that path from your device using adb pull /path/to/crashDump. Dumps are in the Google Breakpad format and are also accepted by crash reporting services like Crashlytics.

Unstripped Libraries

As of PSPDFKit for Android 8.2, we include our unstripped native libraries to help us with crash reporting. Our release package since PSPDFKit for Android 8.2.0 contains our unstripped native core library, libpspdfkit.so, for our supported architectures (arm64, armeabi, x86, x86_64). These libraries are located inside the release ZIP file under <release_zip>/unstrippedNativeLibs. If they’re in .zip files, you’ll need to unzip them before using them.

If you’re faced with a crash with a stack trace coming from libpspdfkit.so, you might see a stack trace like this:

SIGSEGV
MyPdfActivity
Segmentation violation (invalid memory reference)
Feb 29th 2020, 12:12:12 UTC

STACKTRACE

SIGSEGV: Segmentation violation (invalid memory reference)

0  libpspdfkit.so +0x12686a8 0x70bd2d46a8
1  libpspdfkit.so +0x12462a0 0x70bd2b22a4
2  libpspdfkit.so +0x1248878 0x70bd2b487c
3  libpspdfkit.so +0x123f3b4 0x70bd2ab3b8
4  libpspdfkit.so +0x1116d48 0x70bd182d4c
5  libpspdfkit.so +0x110ed60 0x70bd17ad64
6  libpspdfkit.so +0x112c4d0 0x70bd1984d4
17 libpspdfkit.so +0xadc39c  Java_com_pspdfkit_internal_jni_NativePage_00024CppProxy_native_1renderPageWithCache
18 base.odex +0x320898       art_jni_trampoline

The first address column shows the address offset inside libpspdfkit.so. This address can be used to find the function name of the particular frame. There are a couple of tools that can be used to find this information. The de facto standard is to use ndk-stack, as described in the Android developers guide. We have a blog post describing how to use it with crash logs and logcat.

ndk-stack is a Python script that uses llvm-symbolizer under the hood. We noticed that sometimes ndk-stack doesn’t work, but llvm-symbolizer does.

llvm-symbolizer is located inside the NDK, which can be installed with Android Studio or the sdkmanager app. You can find it inside the Android SDK home folder:

$ <ANDROID_SDK_HOME>/ndk/<NDK-VERSION>/toolchains/llvm/prebuilt/darwin-x86_64/bin/llvm-symbolizer

llvm-symbolizer can be used from the terminal like so:

# Assuming the crash report came from an arm64 device.
$ <ANDROID_SDK_HOME>/ndk/<NDK-VERSION>/toolchains/llvm/prebuilt/darwin-x86_64/bin/llvm-symbolizer \
    --demangle \
    --functions=linkage \
    --inlines \
    --obj <RELEASE_ZIP>/unstrippedNativeLibs/arm64-v8a/libpspdfkit.so

Paste the address offsets from the stack trace (e.g. 0x12686a8) and press Enter.