11 Replies Latest reply: Mar 6, 2009 5:26 AM by 843810 RSS

    JVMTI Based Profiler problem

    843810
      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
          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
            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
              bharat, thanks for the additional information. I'll do some investigating and get back to you.
              • 4. Re: JVMTI Based Profiler problem
                843810
                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
                  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
                    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
                      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
                        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
                          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
                            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
                              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..