Bug 52468 - Invalid LocalVariableTable and LineNumberTable after modifying instruction list
Summary: Invalid LocalVariableTable and LineNumberTable after modifying instruction list
Status: NEW
Alias: None
Product: BCEL - Now in Jira
Classification: Unclassified
Component: Main (show other bugs)
Version: 5.3
Hardware: PC Linux
: P2 normal
Target Milestone: ---
Assignee: issues@commons.apache.org
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-01-14 17:58 UTC by Thiago
Modified: 2012-02-04 20:01 UTC (History)
0 users



Attachments
Fixes bugs 52441, 52422 and invalid offsets in local variable and line number tables (6.87 KB, patch)
2012-01-14 17:58 UTC, Thiago
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Thiago 2012-01-14 17:58:38 UTC
Created attachment 28158 [details]
Fixes bugs 52441, 52422 and invalid offsets in local variable and line number tables

LocalVariableGen objects point to the start and end InstructionHandles which indicate the variable range. However, when changing the instruction list with MethodGen.setInstructionList, the LocalVariableGen objects point to instruction handles that do not belong to the new list. When MethodGen.getMethod is called, LocalVariable objects will be created using the bytecode offsets of handles that do not belong to the current instruction list. Because bytecode instructions can have different lengths, the offsets may be invalid (i.e., do not point to an instruction, which is invalid according to the java bytecode spec).

A similar problem occurs with LineNumberGens.


One proposed solution is to check at getLocalVariables() (and getLineNumberTable) whether the target handle belongs to the current instruction list. If not, we first search for the "best candidate" in the current list, i.e., the instruction with the position of the original targeted instruction, or the next one if there is no perfect match. Then we use this instruction's offset in the LocalVariable.

Sketch of the code:

public LocalVariableGen[] getLocalVariables() {
    int size = variable_vec.size();
    LocalVariableGen[] lg = new LocalVariableGen[size];
    variable_vec.toArray(lg);
    for (int i = 0; i < size; i++) {
        if (lg[i].getStart() == null) {
            lg[i].setStart(il.getStart());
        } else {
            lg[i].setStart(il.findHandle(lg[i].getStart().i_position));
        }
     ...
}

The patch in attachment fixes this problem plus the last 2 bugs I reported ( https://issues.apache.org/bugzilla/show_bug.cgi?id=52441 and https://issues.apache.org/bugzilla/show_bug.cgi?id=52422 ).
Comment 1 Torsten Curdt 2012-02-04 20:01:30 UTC
Would be great to have a test case for this. Sounds about right though.