#454 VariableCleaner : inconsistent local variable table

open
4
2014-08-22
2012-09-05
No

Apply code/allocation/variable optimization to the following code:

package test;

public class Test {
private static native short doSomething(short offset);
public static short m(short offset) {
short tmp_offset;
do {
tmp_offset = doSomething(offset);
offset = (short)(tmp_offset + 1);
} while (offset > 0);
return offset;
}
}

Proguard is mapping "tmp_offset" to "offset", which is fine. Here is the bytecode generated:

0 iload_0
1 invokestatic #2 <test/Test.doSomething>
4 istore_0
5 iload_0
6 iconst_1
7 iadd
8 i2s
9 istore_0
10 iload_0
11 ifgt 0 (-11)
14 iload_0
15 ireturn

Problem is when looking at local variable table:

offset : index = 0 / start_pc = 0 / length = 1
tmp_offset : index = 0 / start_pc = 5 / length = 1

length is re-computed by VariableCleaner.trimLocalVariables() : if skipping this process, local variable table now becomes consistent:

offset : index = 0 / start_pc = 0 / length = 15
tmp_offset : index = 0 / start_pc = 5 / length = 1

In smartcard industry, when using the SUN converter to convert java code to javacard code, this one is using local variable table to map java variables to javacard variables. code generated then lost the value of "offset" which lead to a bug at runtime.

Discussion

  • Eric Lafortune
    Eric Lafortune
    2012-09-06

    • assigned_to: nobody --> lafortune
    • priority: 5 --> 4
     
  • Eric Lafortune
    Eric Lafortune
    2012-09-06

    Some virtual machines don't like debug information with overlapping local variables, which is why they are trimmed. If the Javacard converter needs it, you can comment out the trimming. Note that I get slightly different results with just the code/allocation/variable optimization:
    v0: 0 -> 5 [S offset]
    v0: 5 -> 6 [S tmp_offset]

    In general, it is very hard or even impossible to preserve all debugging information while optimizing (e.g. with variable optimizations, method inlining, etc). ProGuard makes an attempt, but it doesn't have the highest priority right now. I'd rather let ProGuard emit Javacard code, based on its own analysis.