2 Replies Latest reply on Sep 16, 2009 8:10 AM by Stefan Egli

    jvm crash when trying to instrument java.io.FileOutputStream

    Stefan Egli Newbie

      One can arguably challenge whether instrumenting such core methods like java.io.FileOutputStream.write(byte[],int,int) makes sense in the first place. But nonetheless I tried this using the following rule:

      RULE writeBytes
      CLASS java.io.FileOutputStream
      METHOD write(byte[],int,int)
      HELPER org.jboss.byteman.rule.helper.Helper
      AT ENTRY
      BIND len:int=$3
      IF true
      DO debug("Writing "+len+" bytes")
      ENDRULE


      This repetedly produces the following - nice - JVM crash:

      #
      # An unexpected error has been detected by Java Runtime Environment:
      #
      # Internal Error (exceptions.cpp:367), pid=5420, tid=520
      # Error: ExceptionMark destructor expects no pending exceptions
      #
      # Java VM: Java HotSpot(TM) Client VM (10.0-b22 mixed mode windows-x86)
      # An error report file with more information is saved as:
      # C:\eclipse\hs_err_pid5420.log
      #
      # If you would like to submit a bug report, please visit:
      # http://java.sun.com/webapps/bugreport/crash.jsp
      #
      *** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at ../../../src/share/instrument/JPLISAgent.c line: 806
      *** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at ../../../src/share/instrument/JPLISAgent.c line: 806
      *** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at ../../../src/share/instrument/JPLISAgent.c line: 806
      *** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at ../../../src/share/instrument/JPLISAgent.c line: 806
      *** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at ../../../src/share/instrument/JPLISAgent.c line: 806
      *** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at ../../../src/share/instrument/JPLISAgent.c line: 806
      *** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at ../../../src/share/instrument/JPLISAgent.c line: 806
      *** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at ../../../src/share/instrument/JPLISAgent.c line: 806


      My first guess would be that we have a conflict here between the instrumentation code trying to change a class' bytecode and probably writing something somewhere using FileOutputStream.

      I tried both with and without org.jboss.byteman.compileToBytecode - no help there.


      On another note: Tried instrumenting those native methods of FileOutputStream but saw no effect. Can you instrument native methods at all? (using AT ENTRY for example)

        • 1. Re: jvm crash when trying to instrument java.io.FileOutputSt
          Andrew Dinn Master

          Hi Stefan,


          One can arguably challenge whether instrumenting such core methods like
          java.io.FileOutputStream.write(byte[],int,int) makes sense in the first place. But
          nonetheless I tried this using the following rule:
          RULE writeBytes
          CLASS java.io.FileOutputStream
          METHOD write(byte[],int,int)
          HELPER org.jboss.byteman.rule.helper.Helper
          AT ENTRY
          BIND len:int=$3
          IF true
          DO debug("Writing "+len+" bytes")
          ENDRULE
          



          Well, nice try but it's no surprise this ain't gonna work. Your debug code is going to end up triggering the rule you have just injected because debug calls FileOutputStream.write to do its job. So your crash is probably due to a stack overflow.

          If your rule did something else other than trace then it might work but what does and does not work depends entirely upon what triggers/calls what. This is not an unexpected situation (welcome to the world of rule languages). Identification of infinite triggering paths in (ECA and other) rule systems is a well-known topic for research and the upshot is that there is no simple way to deal with the potential for problems. It all depends upon how you want your rule language to behave.

          You might be able to avoid this problem by adding a suitable condition test. However, any solution along these lines is going to be rather ad hoc and it may or may not be possible to identify a suitable condition.

          Now, arguably, it might make sense for Byteman to disable rule triggering when it is executing rule actions, thereby avoiding this sort of infinite triggering loop. That's a moot point though since it is takes the most extreme approach, disabling infinite recursion in triggering by disallowing any recursive triggering.

          With different cases recursive triggering might be desired. Imagine that a rule side effect includes invocation of an application method in order to simulate some desired event during the test run,. It might be necessary to trigger rules under this call, say to maintain the validity of counters which track the valid progress of the application.

          I have chosen to allow recursive triggering in the current version of Byteman. It would be possible to provide an option either to disable it or to limit it so that it was disabled for certain rules or certain target classes (e.g. no recursive triggering under calls to bootstrap loader classes/java.* classes etc). I'd be happy to consider implementing something along these lines if you want to submit it as a feature request.


          • 2. Re: jvm crash when trying to instrument java.io.FileOutputSt
            Stefan Egli Newbie

            Tricky one, you're absolutely right. I caused a stack overflow. Might be an idea to have that recursiveness configurable yeah. But currently I'll work around it. Thanks!