Have you ended up scratching your head trying to read through a.b.c.d() crash reports…worse, an NPE occurring there?!
Many times, we receive crash reports or logs from tester/user devices but those logs would be obfuscated because we’ve switched on “ProGuard” on our release builds. One of the most popular tools, almost every Android application would have is Firebase Crashlytics. The dashboard makes it so much easier to detect and get a stack trace of the crashes from our customer devices. But if we don’t configure the ProGuard rules to not mess up (obfuscate) the source file and the line numbers, the stack trace would pretty much be unreadable.
To solve that issue, Firebase has suggested adding these two lines to our ProGuard config file (Source) –
-keepattributes SourceFile,LineNumberTable # Keep file names and line numbers.
-keep public class * extends java.lang.Exception # Optional: Keep custom exceptions.
If we do this, it would not obfuscate our source file and the line numbers. The logs obtained now would be readable but the downside is that if someone takes our APK and unzips it, the source code would be available to them as it is to us in our Android Studio.
So now the ideal solution should be that we obfuscate the source code when generating the release build but also be able to read the obfuscated stack trace (we are the owners of the source, we should be allowed!), right? Well, there’s a way!
And it’s quite easy, really.
The ideal solution
Whenever we generate a release build with ProGuard turned on, our Gradle generates a mapping.txt file for us. It will reside under build/outputs/mapping/{variant}/mapping.txt. This is literally our key to un-obfuscate the stack trace.
Next, go to the ProGuard GitHub releases here and download the zip. Extract it and inside the “lib” folder, run the following command –
java -jar proguardgui.jar
Tada! You’ll now see the Proguard GUI.
Go to the “ReTrace” menu option and click on “Browse” to select your mapping.txt file.
Paste the Obfuscated Stack Trace and click on ReTrace! That’s it. All the a.b.c.d() would now make clear sense to you!