3 Replies Latest reply: Jan 4, 2012 11:44 AM by Andrew Dinn RSS

Reference to local variables inside a method

Bela Ban Master

The documentation states:

"Note that it is only possible to use local or parameter variable names such as $i, $this or $arg1 if the trigger method bytecode includes a local variable table, e.g. if it has been compiled with the -g flag"

 

If I have a method foo():

 

public void foo(intx, int y) {

     int num=20;

     ...

}

 

I therefore assume that

 

AFTER WRITE $num

 

won't work unless the code has been compiled with -g, correct ?

If so, is there any other way to be able to refer to "num" ?

 

Can I refer to "num" as $3 ?

Cheers,

Bela

  • 1. Re: Reference to local variables inside a method
    Andrew Dinn Master

    Hi Bela,

    Bela Ban wrote:

     

    The documentation states:

    "Note that it is only possible to use local or parameter variable names such as $i, $this or $arg1 if the trigger method bytecode includes a local variable table, e.g. if it has been compiled with the -g flag"

     

    If I have a method foo():

     

    public void foo(intx, int y) {

         int num=20;

         ...

    }

     

    I therefore assume that

     

    AFTER WRITE $num

     

    won't work unless the code has been compiled with -g, correct ?

     

    Yes, it is necessary to compile with -g if you want to refer to a local var in the location (AT) clause. it's exactly the same as if you want to refer to it in the BIND, IF or DO clauses.

     

    This ought also to be sufficient for such references to work. However, there is an outstanding bug Hotspot/OpenJDK which means it is not always guaranteed to work:

     

      https://issues.jboss.org/browse/BYTEMAN-28

     

    In brief, if a target class is loaded before any rules are installed then local variable references don''t work.

     

    What happens is that Hotspot/OpenJDK assume they don't need to keep hold of the local var tables aftre a clas shas been loaded so they discard them to retrieve space. If a rule is in place before the class gets loaded and the Byteman agent transforms the class bytecode then Hotspot/OpenJDK keep hold of the full original bytecode including local var info. So, if you load your rules from the Java command line local var references work but if you submit them to a running program they will fail unless you get the rules into the JVM before the target class has been loaded. SInce BMUnit dynamically submits rules just before running a test this often (but not always) means that references fail.

    Bela Ban wrote:

     

    Can I refer to "num" as $3 ?

     

    No, I am afraid that doesn't work. although it is an interesting suggestion. Firstly, there is a safety issue here since it makes it a lot easier to think you are referring to a parameter when you mean a local var and vice versa. Also, there is the question of what the specific type or element type of $n is when the stackmap info and bytecode merely indicate that it is, respectively, an object or an array. It might not alway be possible to type check rules using these sort of references even though the injected code is performing legitimate operations.

     

    That said, it would be nice to have this available both as a workaround for BYTEMAN-28 and also as a way of referring to locals even when the bytecode contains no local var info. I would be happy to think this through further maybe adding it as something you would enable e.g. by setting a system property when you load the agent. However, I would probably need to find several spare days to  work thorugh the type issues and then implement it so it won't happen quickly. If you really want it  raise a JIRA so I can keep it in mind

  • 2. Re: Reference to local variables inside a method
    Bela Ban Master

    Hi Andrew,

     

    no worries, I'll accept that it won't work with dynamically submitted rules, as used in BMUnit. I don't think I'll need access to local variables anyway, I just tested this for completeness.

    Thanks !

  • 3. Re: Reference to local variables inside a method
    Andrew Dinn Master

    Just for completeness?

     

    I can see I'm not going to get away with anything from now on ;-)