Eric Bodden wrote:
> The problem now arises at label 2: Because the trap starts *before*
> the new-statement, Soot assumes that it could be the case that we
> reach label 2 without having executed "x = new O;". Hence, our
> must-alias analysis returns "UNKNOWN" for x at this location. However,
> actually a new-statement can never fail (except probably with an
> OutOfMemoryError in which the program will crash anyway?), so x is
> always going to be non-null at label2. Hence I thought it might be
> sound to have the shadow (and hence the trap) begin *after* the
> new-statement. However, that seems to break certain assumptions during
> weaving (or at execution time?).
I don't understand why this is a problem. If new statements can fail
(with OOME), as I think they can, then the simple fact is that x is
*NOT* definitely initialised in an exceptional branch away from the new
statement. And programs don't generally crash when an OOME occurs, they
throw an OOME which can be caught and handled gracefully like any other
throwable (think Eclipse). The fact that many of the failures are
VerifyErrors suggests that soot requires the newStmt and the call to
init to be immediately next to each other, which makes sense (and sounds
familiar -- I seem to recall being told that this is how it should be,
though I'm not sure). If that's the case, and weaving splits the two up,
you'll always have unverifiable code.
In fact, brief experimentation confirms that adding other code (e.g. an
AssignStatement) in between the newStmt and the init call results in
unverifiable bytecode.
> Does anybody see a good solution to this? In general I find that it's
> an interesting question what state a (bound) target object should be
> in if its constructor threw an advice, anyway.
In Jimple (at least correctly generated Jimple), the result of the
newInst is assigned to a new local, and init is immediately called on
it. If we get an OOME or an exception during construction, we branch out
and the local remains undefined. Indeed, in my experiments even just
trying to access the local which holds the result of the newStmt after
the constructor threw an exception gave a VerifyError. Note that this is
consistent with the fact that in AspectJ you get the newly constructed
object "after returning" from a constructor call, but not just "after" one.
To refine my statement at the start: If an exception occurs during the
(newStmt, init-call) pair, then x is not only "not definitely
initialised", but in fact "definitely not initialised". In other words,
the behaviour you tried to fix appears to me to be correct.
Cheers,
- P
PS: Did you run the harness before checking in?
Received on Wed Jul 11 11:18:51 2007
This archive was generated by hypermail 2.1.8 : Wed Jul 11 2007 - 15:00:09 BST