Erik Corry wrote:
On Wed, Feb 18, 2004 at 10:28:52AM -0700, Andrew Huntwork wrote:

There are a couple things you could do, one of which may be easy.

First, you could make the instrumentation method you're calling static. I assume the verifier error you're getting is that you're trying to do a virtual method call on an uninitialized object. Calling a static method won't call a method on an object, so you'll be fine.


No, that doesn't work either.  It's a different problem to the one
you think.  See VM spec section 4.9.4:

   "a special type is created and pushed on the verifier's
    model of the operand stack as the result of the Java virtual
    machine instruction new. The special type indicates the
    instruction by which the class instance was created and
    the type of the uninitialized class instance created"

The only thing you can do with that object is call the <init>
(contstructor) method.  You can't pass it as a parameter to a
profiling routine.

It's quite an irritating restriction.

Right, you won't be able to make 'this' a parameter to the static function, but you can still call the static function. Depending on what kind of instrumentation you want to do, this is sufficient. For example, if you just want to know a complete call trace, you can insert the bytecode equivalent of the following at every method entry and exit:


log("entering/leaving foo.bar()V");



Second, you could do some pretty complicated stack and control flow analysis. Here's something that's legal in bytecode but not in java:

if(...)
 super(foo);
else
 super(bar);


Are you sure that's legal? The VM spec says:

    "If a constructor body does not begin with an explicit
    constructor invocation and the constructor being declared
    is not part of the primordial class Object, then the
    constructor body is implicitly assumed by the compiler to
    begin with a superclass constructor invocation "super();",
    an invocation of the constructor of the direct superclass
    that takes no arguments."

Does you example begin with an explicit constructor invocation?
I don't think it does.  Is it allowed to call two different
constructors for the same class on an object?

As I say, not legal in Java (which your passage refers to), but totally legal in bytecode. The attached class has this <init>:


Method test()
   0 iconst_0
   1 ifeq 11
   4 aload_0
   5 invokespecial #10 <Method java.lang.Object()>
   8 goto 15
  11 aload_0
  12 invokespecial #10 <Method java.lang.Object()>
  15 return

it verifies just fine



and here's something else that's legal in bytecode

void <init>(Object foo) {
aload_0
aload_1
astore_0
dup
invokespecial <init>()V
astore_1
return
}


Does anyone do that?


I don't know what kind of optimizations BLOAT,soot,dasho, or any of the other bytecode optimizers do, but some kind of register allocation optimization could do something similar under some circumstances. Also, there are several bytecode obfuscators out there, including sandmark. If some kind of reverse engineering tool depended on lv 0 always being 'this', i'm sure several groups would generate this kind of code just to screw that tool up.


In general, you'd be surprised how many sources of bytecode there are besides javac, so you'll eventually suffer if you concentrate too much on handling just that kind of code.

--
"I say to you that the VCR is to the American film
producer and the American public as the Boston
strangler is to the woman home alone."
        -Jack Valenti, President, Motion Picture
         Association of America, Inc., before
         The House Subcommittee on Courts, Civil
         Liberties, and The Administration of
         Justice, August, 1982,
         http://cryptome.org/hrcw-hear.htm

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to