[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: a bug in soot (coffi)



Before we implement this fix, I'd like to consider/discuss an
alternative, which doesn't require adding bytecode instructions to
<clinit> or adding a <clinit> method if none exists. Specifically, we
could keep around the ConstantValue with each SootField, and then write
it out to a ConstantValue attribute when we write out bytecode.

In deciding on a solution, it's probably helpful to find out why the
Java specification includes this seemingly redundant thing. I can't
think of a good reason, and I haven't found one in references I've
looked at. Anyone know more?

What bugs me about modifying the <clinit> bytecode is that it seems very
susceptible to various hard-to-find bugs related to the order in which
things are initialized. In particular, <clinit> methods can do just
about anything, including causing other <clinit> methods to be
implicitly called. How do we ensure that we are not changing the order
in which everything gets initialized (when even determing the order
requires careful study of the VM spec)?

On the downside, keeping the ConstantValue around with each field is a
pain. In particular, if we're going to do this, we should probably also
write it out in our IRs somehow. This will likely require a change to
the IR grammars, as well as the Jimple parsing code. Not fun.

Anyway, I don't know that my proposed solution is better than Feng's,
but I do get the feeling that this problem will turn out uglier than it
seems, and so I think we should consider possible solutions carefully
before picking one.

Ondrej

On Mon, Feb 23, 2004 at 11:41:08AM -0500, Feng Qian wrote:
> Hi,
> 
> When reading a paper, I noticed a bug in Soot (or likely in Coffi). I 
> describe it here and if someone is using soot actively, he/she may fix 
> it quickly. (I can do it too, but less efficient than others right now :-P )
> 
> The problem is that, Soot losts the ConstantValue attribute of a static 
> field when transferring a class file to its internal format, this is due 
> to some static fields not initialized in <clinit> explicitly. Example:
> 
> testconstA.java
> public class testconstA {
>   public static z = 7;
> }
> 
> testconst.java
> public class testconst {
>   public static void main(String[] args) {
>     System.out.println(z);
>   }
> }
> 
> We can compile both .java files using javac 1.4.2. Then we change 
> testconstA.java to
> 
> testconstA.java modified
> public class testconstA {
>   public static final z = 7;
> }
> 
> and recompile modified testconstA only (don't recompile testconst.java, 
> you can see the difference by sootify both). The resulted class files 
> are legal. The only difference of testconstA.class after modification is 
> that, there is no <clinit> in the modified version, because 'z' is 
> *final* now, which lets javac compiled '7' to be a ConstantValue 
> attribute of the field *z*.
> 
> If we run > java testcont < now, it gives correct output. But if we 
> sootify *modified* testconstA.class, the ConstantValue attribute of *z* 
> was lost. So far, the problem should be clear.
> 
> The solution is to assign the value of ConstantValue attribute to a 
> static field in <clinit> explicitly (create one if no <clinit> exists) 
> before any other real code in original <clinit>, see JVM spec version 2, 
> Section 4.7.2.
> 
> I already saw ConstantValue attributes were parsed in Coffi, it is only 
> a matter to convert it to an assignment in <clinit>.
> 
> Cheers,
> Feng
> 
> 
>