This discussion is archived
11 Replies Latest reply: Mar 6, 2009 3:26 AM by 843810 RSS

JVMTI Based Profiler problem

843810 Newbie
Currently Being Moderated
Hi to all,
I am working on a JVMTI based profiler agent library, using this i am trying to achieve the BCI during runtime.
I am using JVMTI's redefine class features and instrumenting the bytecode during runtime.
Now i am facing a realy weird problem consider my first scenario:
1) I run a sample application (consider class A) that prints a simple message inside an infinite loop, this method is called from another threaded class (consider class T).
2) After the sample application (class A) starts up i immediately change its bytecode, redefines the sample loaded class & reloads it.
3) After Reloading the sample class (class A) with instrumented class i got the desired instrumented output.

This is the way i wanted it to always behave, but consider another scenario:

1) I run a sample application (consider class A) that prints a simple message inside an infinite loop, this method is called from another threaded class (consider class T).
2) After the application (class A) starts up, i wait for some time doing nothing and let the application run for quite some time (8-10 minutes).
3) Now change its bytecode, redefines the sample loaded class & reloads it.
4) After Reloading the sample class (class A) with instrumented class what i saw that it still executes the older class only, this is not what i expected it to do.

I can't understand the 2nd scenario behaviour as i already checked the stack overflow during sample method call in my base class, which never occurs.
I use asm classes to invoke the instrumented byte code methods at runtime, which works fine till i instrument the class immediately.
Any help in this regard would be appreciated.

Thanks
bharat...
  • 1. Re: JVMTI Based Profiler problem
    843810 Newbie
    Currently Being Moderated
    bharat,

    I'm trying to understand your scenarios. A couple of questions embedded below.
    bharat.gusain wrote:
    1) I run a sample application (consider class A) that prints a simple message inside an infinite loop, this method is called from another threaded class (consider class T).
    So class T has a method that calls a method in class A. The method
    in class A executes an infinite loop printing a simple message. Just
    to confirm: the method in class T is not calling the method in class A
    from an infinite loop.


    2) After the sample application (class A) starts up i immediately change its bytecode, redefines the sample loaded class & reloads it.
    What do you mean by "starts up"? Do you mean that you redefine
    the sample loaded class before the method with the infinite loop is
    called?


    3) After Reloading the sample class (class A) with instrumented class i got the desired instrumented output.
    So did you get some of the original output followed by the desired
    instrumented output?


    This is the way i wanted it to always behave, but consider another scenario:

    1) I run a sample application (consider class A) that prints a simple message inside an infinite loop, this method is called from another threaded class (consider class T).
    2) After the application (class A) starts up, i wait for some time doing nothing and let the application run for quite some time (8-10 minutes).
    3) Now change its bytecode, redefines the sample loaded class & reloads it.
    4) After Reloading the sample class (class A) with instrumented class what i saw that it still executes the older class only, this is not what i expected it to do.
    In this scenario, the method with the infinite loop is running before the redefine
    and after the redefine, the output doesn't change. Do I have that right?


    I can't understand the 2nd scenario behaviour as i already checked the stack overflow during sample method call in my base class, which never occurs.
    I'm not sure what "stack overflow" has to do with anything. I'm guessing you
    mean that you checked for errors and didn't get any.


    I use asm classes to invoke the instrumented byte code methods at runtime, which works fine till i instrument the class immediately.
    The above sentence doesn't quite match the scenarios described above.
    According to the above, immediate redefinition worked and redefinition
    after a delay did not work.


    Any help in this regard would be appreciated.
    I'm guessing that we'll get to the bottom of this with answers to the above questions.

    Dan
  • 2. Re: JVMTI Based Profiler problem
    843810 Newbie
    Currently Being Moderated
    Hi Dan,
    answers to the questions you asked are below:
    dcubed wrote:bharat,

    I'm trying to understand your scenarios. A couple of questions embedded below.
    bharat.gusain wrote:
    1) I run a sample application (consider class A) that prints a simple message inside an infinite loop, this method is called from another threaded class (consider class T).So class T has a method that calls a method in class A. The method
    in class A executes an infinite loop printing a simple message. Just
    to confirm: the method in class T is not calling the method in class A
    from an infinite loop.
    No Actually the class T runs the infinite loop (inside the run method since its a thread), inside this infinite loop i am calling a method of class A(Which prints the message).
    yes class T's run method is calling from an infinite loop, class A's method.

    2) After the sample application (class A) starts up i immediately change its bytecode, redefines the sample loaded class & reloads it.What do you mean by "starts up"? Do you mean that you redefine
    the sample loaded class before the method with the infinite loop is
    called?
    NO class T started the thread which calls infinitely the class A's method, hence both class T and class A were loaded and executing when i redefined the class A's method.
    3) After Reloading the sample class (class A) with instrumented class i got the desired instrumented output.So did you get some of the original output followed by the desired
    instrumented output?
    Yes, I get the original message followed by the instrumented output.
    This is the way i wanted it to always behave, but consider another scenario:

    1) I run a sample application (consider class A) that prints a simple message inside an infinite loop, this method is called from another threaded class (consider class T).
    2) After the application (class A) starts up, i wait for some time doing nothing and let the application run for quite some time (8-10 minutes).
    3) Now change its bytecode, redefines the sample loaded class & reloads it.
    4) After Reloading the sample class (class A) with instrumented class what i saw that it still executes the older class only, this is not what i expected it to do.
    In this scenario, the method with the infinite loop is running before the redefine and after the redefine, the output doesn't change. Do I have that right?
    Yes the class T's run method is running an infinite loop(which inturn keeps on calling class A's method), i have not redefined the class A yet.
    Now after waiting for 10 minutes i finaly redefines the class A.
    After redefinition the method of class A is still displaying the same old message output, and class T's thread is still running the infinite loop, just i am missing the instrumented output.
    I can't understand the 2nd scenario behaviour as i already checked the stack overflow during sample method call in my base class, which never occurs.I'm not sure what "stack overflow" has to do with anything. I'm guessing you mean that you checked for errors and didn't get any.
    I thought because i am calling the method infinitely after sometime it might happened that stack got full and hence i am getting this weird issue, so now i check for stack overflow exception each time i am calling the class A's method.

    I use asm classes to invoke the instrumented byte code methods at runtime, which works fine till i instrument the class immediately.The above sentence doesn't quite match the scenarios described above.
    According to the above, immediate redefinition worked and redefinition
    after a delay did not work.


    Any help in this regard would be appreciated.I'm guessing that we'll get to the bottom of this with answers to the above questions.
    Dan
    Sorry for misunderstanding... what i meant was, immediate redefinition worked and redefinition
    after a delay did not work.

    Regards
    bharat..

    Edited by: bharat.gusain on Jan 20, 2009 11:47 PM
  • 3. Re: JVMTI Based Profiler problem
    843810 Newbie
    Currently Being Moderated
    bharat, thanks for the additional information. I'll do some investigating and get back to you.
  • 4. Re: JVMTI Based Profiler problem
    843810 Newbie
    Currently Being Moderated
    hi dani,
    did you got anything on this, since i am clue less about this problem. have compared all the logs in both scnario's copared the asm traces as well but found both trace identical.
    Don't know what to do.
    Regards
    bharat
  • 5. Re: JVMTI Based Profiler problem
    843810 Newbie
    Currently Being Moderated
    Sorry for the delay in getting back to you. I was occupied by other issues.
    I'm continuing to investigate this issue. Strangely enough, I got another
    report similar to this one late last night. That report came with a ready to
    run example program attached so I'm able to poke around a live system.

    In that example, like yours, an "obsolete" method was continuing to be
    called when a newer version should have been called instead.
  • 6. Re: JVMTI Based Profiler problem
    843810 Newbie
    Currently Being Moderated
    Thanks for the reply dani!
    i will check the condition whether the called method has become obsolete or not is it is then i will popframe.
    will get back to you.
  • 7. Re: JVMTI Based Profiler problem
    843810 Newbie
    Currently Being Moderated
    hi,
    I just checked for the obsolete method but the method in class A (which is being redefined) is not obsolete.
    so i don't understand where lies the problem.
    Regards
    bharat..
  • 8. Re: JVMTI Based Profiler problem
    843810 Newbie
    Currently Being Moderated
    I think we are not using the same terminology. In the problem that you described,
    an older version of a method was continuing to be executed unexpectedly when
    you expected the latest version to be executed. The older version of the method
    is also known as an "obsolete method".

    Can you tell me more about class A and the method that you are invoking?

    - does class A implement more than one interface?
    - is the method in class A specified by an interface?
    - is the method in class A specified by more than one interface?

    Thanks, in advance, for the additional info.

    Edited by: dcubed on Feb 19, 2009 12:13 PM
  • 9. Re: JVMTI Based Profiler problem
    843810 Newbie
    Currently Being Moderated
    hi,
    Thanks for the reply, find my answers below:

    - does class A implement more than one interface? No it does not implement any interface
    - is the method in class A specified by an interface? No its a plain static method
    - is the method in class A specified by more than one interface? No It doesn't

    the class A is a plain class without any dependency on other class/Interfaces
    between i tested the instrumented class and found that it is being instrumented right (No error while instrumentation) that means this is only the problem of obsolete method continuing the execution.

    Regards
    bharat...
  • 10. Re: JVMTI Based Profiler problem
    843810 Newbie
    Currently Being Moderated
    Do you have a small test program that reproduces this problem? I would like to try and reproduce the problem with a special VM that I have that catches calls to obsolete methods.
  • 11. Re: JVMTI Based Profiler problem
    843810 Newbie
    Currently Being Moderated
    Hi,
    I AM using following three classes :

    1) HelloTest.java

    public class HelloTest extends Thread {

    boolean stop = false;

    public void run() {

    int i = 0;
    while( !stop ) {
    Log.getInstance().report( i++ );
    try {
    sleep(1000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }

    public void setStopFlag(boolean flag) {
    this.stop = flag;
    }
    }

    2) Log.class

    public class Log {

    private static Log log;

    public static Log getInstance() {
    if( log == null ) {
    log = new Log();
    }
    return log;
    }

    public void report(int i) {
    System.out.println("Log " + i );
    }

    }

    3) Main.java

    public class Main {

    public static void main(String[] args)
    {
    // start our logging thread
    HelloTest t = new HelloTest();
    t.start();
    try {
    t.join();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }


    Log.class is being redefined, But only obsolete class is running.

    Sorry for my late reply.


    Regards
    bharat..