4 Replies Latest reply on Nov 21, 2019 9:41 AM by adinn

    bmcheck returns NullPointerException to a file with two rules

    yusuke.sato.zz

      I am using byteman to trace call stack in JGit on Windows 10.

       

      First I wrote a byteman rule to trace start of a method. bmckeck reported no error with this script.

      RULE CheckoutCommand Start
      CLASS org.eclipse.jgit.api.CheckoutCommand
      METHOD call
      AT ENTRY
      IF true
      DO
        traceOpen("log","D:/tmp/byteman.log");
        traceln("log", "[Start][checkout] Start checkout branch: " + $0.name);
        traceClose("log");
      ENDRULE

       

      Then I wrote another byteman rule to trace end of the same method. bmckeck reported no error with this script too.

      RULE CheckoutCommand End
      CLASS org.eclipse.jgit.api.CheckoutCommand
      METHOD call
      AT EXIT
      IF true
      DO
        traceOpen("log","D:/tmp/byteman.log");
        traceln("log", "[End][checkout] Checkouted branch successfully: " + $0.name);
        traceClose("log");
      ENDRULE

       

      But when I joint these two rules into one rule file (JGit.btm), bmckeck returns NullPointerException.

      RULE CheckoutCommand Start
      CLASS org.eclipse.jgit.api.CheckoutCommand
      METHOD call
      AT ENTRY
      IF true
      DO
        traceOpen("log","D:/tmp/byteman.log");
        traceln("log", "[Start][checkout] Start checkout branch: " + $0.name);
        traceClose("log");
      ENDRULE
      
      
      RULE CheckoutCommand End
      CLASS org.eclipse.jgit.api.CheckoutCommand
      METHOD call
      AT EXIT
      IF true
      DO
        traceOpen("log","D:/tmp/byteman.log");
        traceln("log", "[End][checkout] Checkouted branch successfully: " + $0.name);
        traceClose("log");
      ENDRULE

       

      The error looks like this:

      PS C:\home\satob> C:\opt\byteman\bin\bmcheck.bat -cp C:\opt\pleiades\eclipse\plugins\org.eclipse.jgit_5.1.0.201809111528-r.jar .\JGit.btm
      Checking rule CheckoutCommand Start against class org.eclipse.jgit.api.CheckoutCommand
      Parsed rule "CheckoutCommand Start" for class org.eclipse.jgit.api.CheckoutCommand
      Type checked rule "CheckoutCommand Start"
      
      
      Checking rule CheckoutCommand End against class org.eclipse.jgit.api.CheckoutCommand
      Exception in thread "main" java.lang.NullPointerException
              at org.jboss.byteman.check.RuleCheck.checkRules(RuleCheck.java:234)
              at org.jboss.byteman.check.TestScript.main(TestScript.java:74)

       

      Why bmcheck returned NullPointerException to this file?

        • 1. Re: bmcheck returns NullPointerException to a file with two rules
          adinn

          Hi Yusuko,

           

          Thank you very much for reporting this problem.

           

          I'm not sure what is happening here. It would be helpful if you could tell me which version of Byteman you are using and also your Java version.

           

          I have not been able to reproduce the problem with my current setup but that is different to yours. I successfully checked your combined script using bmcheck on my Linux machine as follows:

           

          [adinn@localhost jgit]$ bmcheck.sh -cp jgit.jar rules.btm
          Checking rule CheckoutCommand Start against class org.eclipse.jgit.api.CheckoutCommand
          Parsed rule "CheckoutCommand Start" for class org.eclipse.jgit.api.CheckoutCommand
          Type checked rule "CheckoutCommand Start"
          
          Checking rule CheckoutCommand End against class org.eclipse.jgit.api.CheckoutCommand
          Parsed rule "CheckoutCommand End" for class org.eclipse.jgit.api.CheckoutCommand
          Type checked rule "CheckoutCommand End"
          
          TestScript: no errors

           

          I am using the latest release (4.0.8) and OpenJDK 1.8.0_222-b10.

           

          One thing that would also help is to enable verbose trace when running bmcheck. That will show more detailed info about what is happening up to the point where the exception is thrown (see below). If you try that and can copy the output for me to see that might make it clearer what is happening.

           

          bmcheck -cp jgit.jar -Dorg.jboss.byteman.verbose rules.btm
          AccessManager:init Initialising default AccessManager
          AccessManager:init Initialising default AccessManager
          Checking rule CheckoutCommand Start against class org.eclipse.jgit.api.CheckoutCommand
          org.jboss.byteman.agent.Transformer : possible trigger for rule CheckoutCommand Start in class org.eclipse.jgit.api.CheckoutCommand
          RuleTriggerMethodAdapter.injectTriggerPoint : inserting trigger into org.eclipse.jgit.api.CheckoutCommand.call() org.eclipse.jgit.lib.Ref for rule CheckoutCommand Start
          org.jboss.byteman.agent.Transformer : inserted trigger for CheckoutCommand Start in class org.eclipse.jgit.api.CheckoutCommand
          . . .
          
          TestScript: no errors

           

          It is hard to be sure what is going wrong until I know exactly which version of Byteman you are using but the source line reported in the exception trace is for this call in method RuleCheck.checkRules():

           

                          info("Checking rule " + script.getName() + " against class " + targetClass.getName());
               ==>        bytes = transformer.transform(script, loader, targetClass.getName(), bytes);

           

          This is the point where Byteman hands over the bytecode to its transformer in order to try to modify the bytecode. The fact that the error happens on this line suggests that it is transformer or targetClass which is null. Neither of those makes much sense :-)

           

          Sorry, for not being able to help right away. If you can provide a bit more info that may make ti easier.

           

          regards,

           

           

          Andrew Dinn

          • 2. Re: bmcheck returns NullPointerException to a file with two rules
            jaikiran

            adinn  wrote:

             


             

                            info("Checking rule " + script.getName() + " against class " + targetClass.getName());      ==>        bytes = transformer.transform(script, loader, targetClass.getName(), bytes);

             

            This is the point where Byteman hands over the bytecode to its transformer in order to try to modify the bytecode. The fact that the error happens on this line suggests that it is transformer or targetClass which is null. Neither of those makes much sense :-)

             

            Hello Andrew,

             

            Looking a few lines above those 2 lines, in RuleCheck.checkRules(), we have this byteman/RuleCheck.java at master · bytemanproject/byteman · GitHub . There's a catch block which catches Exception and moves on. It does have a comment which says the Exception shouldn't really happen, but looking at the constructor of Transformer byteman/Transformer.java at master · bytemanproject/byteman · GitHub  it does a bunch of things which can potentially throw (Runtime)Exceptions (for example setAgentVersion has some logic which throws exceptions). That still doesn't explain why adding more than one rule into that file is triggering this issue, but at least there's a chance that the "transformer" instance is indeed null.

            • 3. Re: bmcheck returns NullPointerException to a file with two rules
              yusuke.sato.zz

              Andrew,

               

              Thank you for your advice.

              I am using Byteman 4.0.8.

              This is the result of "java -version":

              openjdk version "1.8.0_212"
              OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_212-b04)
              OpenJDK 64-Bit Server VM (AdoptOpenJDK)(build 25.212-b04, mixed mode)

               

              And with -Dorg.jboss.byteman.verbose, the result is like this:

              C:\home\satob\>set BYTEMAN_JAVA_OPTS=-Dorg.jboss.byteman.verbose
              
              C:\home\satob\>C:\opt\byteman\bin\bmcheck.bat -cp C:\opt\pleiades\eclipse\plugins\org.eclipse.jgit_5.1.0.201809111528-r.jar .\JGit.btm
              AccessManager:init Initialising default AccessManager
              AccessManager:init Initialising default AccessManager
              Checking rule CheckoutCommand Start against class org.eclipse.jgit.api.CheckoutCommand
              org.jboss.byteman.agent.Transformer : possible trigger for rule CheckoutCommand Start in class org.eclipse.jgit.api.CheckoutCommand
              RuleTriggerMethodAdapter.injectTriggerPoint : inserting trigger into org.eclipse.jgit.api.CheckoutCommand.call() org.eclipse.jgit.lib.Ref for rule CheckoutCommand Start
              org.jboss.byteman.agent.Transformer : inserted trigger for CheckoutCommand Start in class org.eclipse.jgit.api.CheckoutCommand
              Parsed rule "CheckoutCommand Start" for class org.eclipse.jgit.api.CheckoutCommand
              Type checked rule "CheckoutCommand Start"
              
              AccessManager:init Initialising default AccessManager
              Checking rule CheckoutCommand End against class org.eclipse.jgit.api.CheckoutCommand
              Exception in thread "main" java.lang.NullPointerException
                      at org.jboss.byteman.check.RuleCheck.checkRules(RuleCheck.java:234)
                      at org.jboss.byteman.check.TestScript.main(TestScript.java:74)
              • 4. Re: bmcheck returns NullPointerException to a file with two rules
                adinn

                Hi Yusuke,

                 

                Apologies for the delay in replying to this -- I am afraid I have been very busy with other Byteman and non-Byteman tasks.

                 

                I identified the problem and as Jaikiran predicted it is caused by an error when creating the Transformer instance. I have raised BYTEMAN-391 and pushed a fix for it. The fix will be available in the next Byteman release (4.0.10).

                 

                Thank you for reporting this bug and helping me to fix it.