Hong
Hong

Reputation: 18501

Is there a way to prevent Android app code shrinker R8 from changing line numbers?

Android Studio started to use R8 instead of ProGuard by default recently.

The stack traces from ProGuard are fairly easy to understand without using any tools despite code is obfuscated. Let's use the following example:

 java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.Boolean.booleanValue()' on a null object reference
    at net.foo.anroid.Foo.wb.d(SourceFile:453)
    at net.foo.anroid.Foo.wb.a(SourceFile:213)
    at net.foo.anroid.Foo.wb.n(SourceFile:103)
    at net.foo.anroid.Foo.qa.run(Unknown Source:2)
    at java.lang.Thread.run(Thread.java:764)

Usually I know exactly to which file net.foo.anroid.Foo.wb corresponds, and the line numbers (e.g. 453, 213...) are the actual lines numbers in the source file for ProGuard.

However, for R8, the only way to figure out which line is which is looking them up in mapping.txt.

This is really a significant nuisance. If there is no good way to locate the source code quickly from a stack trace, I will go back to ProGuard for this reason alone.

Is there a way to prevent R8 from changing line numbers?

Upvotes: 10

Views: 1666

Answers (2)

sgjesse
sgjesse

Reputation: 4628

This has been discussed from time to time on the R8 team, and we went with always optimizing line numbers for a number of reasons:

  • It saved in the area of 5% on the dex size
  • For release builds where optimizations like inlining are turned on retracing is needed anyway to expand the inlined frames
  • It is one less option in the testing matrix

Right now it is always turned off for debug builds, and for release builds when both -dontoptimize (implies no inlining) and -dontobfuscate are set in the configuration.

When you use retrace (remember to use the one from Proguard version 6 or later) you don't need to cut out the stacktrace, as retrace will pass non stack trace lines through unmodified.

There is currently no library to do this in the app, and as that requires the mapping file to be included in the app that defeats the purpose of making apks small.

Upvotes: 9

Martin Zeitler
Martin Zeitler

Reputation: 76699

Set these in the ProGuard configuration:

-keepattributes SourceFile,LineNumberTable

then use ReTrace jar:

ReTrace can read an obfuscated stack trace and restore it to what it would look like without obfuscation. The restoration is based on the mapping file that ProGuard can write out during obfuscation. The mapping file links the original class names and class member names to their obfuscated names.

java -jar retrace.jar [options...] mapping_file [stacktrace_file]

for example:

java -jar retrace.jar mapping.txt stacktrace.log

Upvotes: 1

Related Questions