redex
redex copied to clipboard
Line number mappings not properly emitted for DebugInfoKind::NoCustomSymbolication
Background
When using DebugInfoKind::NoCustomSymbolication
, line numbers are not properly emitted in the final proguard mapping. There are two causes:
- Line Number mappings from original proguard file are not passed through to final mapping file
- Line number mappings are not provided for methods inlined by Redex.
Problem
Example 1
Suppose there is a method callerMethod
that has had a method called existingInlinedMethod
inlined into it by a prior optimizer. This would generate the following mapping:
com.android.Test -> a:
1:5:java.lang.Object callerMethod() -> b
1:1:java.lang.Object existingInlinedMethod():3:3 -> b
# Note: the original line numbers for this method inlined previously does not need to be contiguous
2:2:java.lang.Object existingInlinedMethod():5:5 -> b
After Redex is ran the mapping file would look like the following:
com.android.Test -> a
1:5java.lang.Object callerMethod() -> b
Example 2
Suppose there is a method calleeMethod
to be inlined into callerMethod
by Redex. Due to be a previous optimizer (R8), a method existingInlinedMethod
was already inlined into calleeMethod
. The mapping file may look like the following:
com.android.Test -> a:
1:5:java.lang.Object calleeMethod() -> b
1:3:java.lang.Object existingInlinedMethod():3:4 -> b
com.android.Test2 -> c
1:5:java.lang.Object callerMethod() -> d
After Redex is ran the mapping file would look like the following:
com.android.Test2 -> c
1:5:java.lang.Object callerMethod() -> d
Expectation
Example 1 The expectation is that the original line number mappings would be preserved (assuming the lines remain unchanged by other optimization passes during Redex).
com.android.Test -> a:
1:5:java.lang.Object callerMethod(java.io.OutputStream) -> b
1:1:java.lang.Object existingInlinedMethod():3:3 -> b
2:2:java.lang.Object existingInlinedMethod():5:5 -> b
Example 2
The expectation is that all of the original line number mappings would be preserved and passed through to the final location.
com.android.Test2 -> c
1:5:java.lang.Object callerMethod() ->d
1:5:java.lang.Object calleeMethod() -> d
1:3:java.lang.Object existingInlinedMethod():3:4 -> d
Solution
- Pass through
ProguardMap
toDexOutput::write_pg_mapping
. - Create a
method -> min/max line number
mapping for every method referenced withinDexPosition
entries of the IRCode. - Iterate through IRCode and adjust
min/max line number
as necessary when aDexPosition
is encountered. - For every method in the mapping, find existing line number entries from the proguard mapping file that are within the min/max line number range and re-emit them. If no entries are found in the existing proguard mapping, emit a simple min/max line number mapping entry.