rohanpadhye/JQF

Reading Janala insturmentation does not preserve the method type

sohah opened this issue · 3 comments

sohah commented

Hi,

I see a discrepancy between the signature of a method and the actual type passed to METHOD_BEGIN inside SingleSnoop.java. More specifically, I am trying to use the CalendarGenerator from the wiki. I use -Djanala.instrumentationCacheDir=insturmentationFiles to dump the instrumented classes.

A snippt of the insturmented class for the CalendarGenerator is as follows:

public GregorianCalendar generate(SourceOfRandomness random, GenerationStatus var2) {
    SingleSnoop.METHOD_BEGIN("edu/berkeley/cs/jqf/examples/calendar/CalendarGenerator", "generate", "(Lcom/pholser/junit/quickcheck/random/SourceOfRandomness;Lcom/pholser/junit/quickcheck/generator/GenerationStatus;)Ljava/util/GregorianCalendar;");

    try {
      GregorianCalendar var10000 = new GregorianCalendar;
      GregorianCalendar var10001 = var10000;
      SingleSnoop.INVOKESPECIAL(830480385, 21, "java/util/GregorianCalendar", "<init>", "()V");

As you can see the line with SingleSnoop.METHOD_BEGIN uses the right signature and, in particular, the right return type of the generate method. However, this information is somehow lost when the SingleSnoop.METHOD_BEGIN is actually invoked. What we see at this point for the desc argument is (Lcom/pholser/junit/quickcheck/random/SourceOfRandomness;Lcom/pholser/junit/quickcheck/generator/GenerationStatus;)Ljava/lang/Object; instead of (Lcom/pholser/junit/quickcheck/random/SourceOfRandomness;Lcom/pholser/junit/quickcheck/generator/GenerationStatus;)Ljava/util/GregorianCalendar;, the insturmented value.

Not sure why the return type is bounded to the Object type instead of its actual type, any reason why this happens? I am thinking this might have to do with how Janala works, but I am not sure. Is there any easy way to fix it?

I appreciate your support and insight. Many thanks,

That's very interesting. I can't think of why it would be doing that, especially when this is a string that contains the information 🤔

I'm traveling this week so won't have time to reproduce and debug for some time. The only remotely plausible hunch I have right now is whether it has anything to do with SafeClassWriter, which tries to compute the common superclass of A and B without actually loading A and B (this is needed when determining the type of slots on the operand stack which could be A on one path and B on on the other, but we can't do getSuperClass() on either A or B because they haven't been loaded/instrumented yet)---I think there are corner cases where this could conservatively return a java/lang/Object. But, I can't think of why this would change the string in this example.

sohah commented

Thank you for the directions. I think I found out what was going on. There isn't a bug or anything. I think what is happening is that that type is the type resultant from the invocation of the generate method from within the lambda expression from here which binds to a return type of an Object type. This invocation is later dynamically dispatched to the right generate method inside the Calendar class. So in fact, we see two generate methods being invoked. The dumping of the instrumentation does not show the rewriting part so it is a bit confusing at first to figure out what is going on; but certainly there is nothing wrong in the code.

Thank you again for helping out. I'll be closing this issue now.

Ahh, alright. I was indeed confused as to how strings could suddenly get replaced :-) It makes much more sense that these are two separate method description strings corresponding to different methods (one of them dynamically generated).

Thanks for diagnosing and reporting back.