Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4548917

StepRequest.addClassFilter(ReferenceType) doesn't comply with specification

XMLWordPrintable

    • generic
    • generic



      Name: abR10010 Date: 12/05/2001


      The part of the specification for the interface EventRequest
      related to filters, states the following:

          The number of events generated for an event request can be controlled through filters.
          Filters provide additional constraints that an event must satisfy
          before it is placed on the event queue.
          Multiple filters can be used by making multiple calls to filter addition methods
          such as ExceptionRequest.addClassFilter(java.lang.String classPattern).
          Filters are added to an event one at a time only while the event is disabled.
          Multiple filters are applied with CUT-OFF AND,
          in the order it was added to the request.
          Only events that satisfy all filters are placed in the event queue.


      The specification for the method
          EventRequestManager.createStepRequest(ThreadReference, int, int)
      contains the following clause:

          The returned request will control stepping only in the specified thread;
          all other threads will be unaffected.


      However, a test against the method StepRequest.addClassFilter(ReferenceType refType)
      shows that if

          - two StepRequsts are created in two different threads in a debuggee,
            thread1 and thread2;
          - to first StepRequest, the method is applied two times,
            both with the same ReferenceType object as arguments,
            hence, a corresponding event, event1, should be received;
          - to second StepRequest, the method is also applied two times,
            but with different ReferenceType objects as arguments,
            hence, a corresponding event, event2, should not be received;
          - the method EventRequest.enabled() is applied to both requests;
      !!! - the thread1 dies first;

      the event1 is NOT received too.

      Hence, there is no complience with the above statement:

          The returned request will control stepping only in the specified thread;
          all other threads will be unaffected.

      Note.
      If the test gets a modification resulting in the thread2 dies first,
      the event1 is received.


      This unspecified result is observed
      when HS 1.4.0-rc-b88 is runnning a test program
      on the following H/S configurations:

       - SUNW Ultra1: sparc 200MHz, RAM 128Mb;
         OS: Solaris-8;
         JVM: Client & Server
       - Intel: 2-processor i686 600MHz processor, RAM 512Mb;
         OS: Solaris-8;
         JVM: Client & Server
       - Intel: 2-processor i686 600MHz processor, RAM 512Mb;
         OS: Linux/RedHat6.2;
         JVM: Client & Server
       - Intel: Pentium-II 350MHz, RAM 128Mb;
         OS: WinNT/4-Workstation;
         JVM: Client & Server


      Corresponding code fragments in a debugger and a debuggee and two logs,
      for the cases with two and one enabled request accordingly,
      are below.


      Steps to reproduce the bug:
      1. cd /net/sqesvr.sfbay/export/vsn/GammaBase/Bugs/{this bug ID}
      2. sh doit1.sh {JAVA_HOME}

      To reproduce the case without the error, the step 2 is:
      2. sh doit2.sh {JAVA_HOME}


          This bug affects the following testbase_nsk tests:
          
          nsk/jdi/StepRequest/addClassFilter_rt/filter_rt003


      The tests will be in the next release of testbase_nsk;
      the current release of testbase_nsk (1.4) is accessible through:

          /net/sqesvr.sfbay/export/vsn/VM/testbase/testbase_nsk.v14


      ///////////////////////////////////////////////////////////////////////

      ///////////// code fragments in the debugger: filter_rt003.java


          private String debuggeeName =
              "nsk.jdi.StepRequest.addClassFilter_rt.filter_rt003a";
              
          private String testedClassName10 =
              "nsk.jdi.StepRequest.addClassFilter_rt.TestClass10";
              
          private String testedClassName20 =
              "nsk.jdi.StepRequest.addClassFilter_rt.TestClass20";

      //////

              log1(" TESTING BEGINS");

              EventRequest eventRequest1 = null;
              EventRequest eventRequest2 = null;

              String property1 = "StepRequest1";
              String property2 = "StepRequest2";

              ReferenceType testClassReference10 = null;
              ReferenceType testClassReference20 = null;

              ThreadReference thread1 = null;
              String threadName1 = "thread1";

              ThreadReference thread2 = null;
              String threadName2 = "thread2";

      int errorFlag = 0;

      vm.resume(); // !!
      for (int i = 0; ; i++) {

      if (errorFlag == 0)

                  breakpointForCommunication();

                  int instruction = ((IntegerValue)
                                     
      (debuggeeClass.getValue(debuggeeClass.fieldByName("instruction")))).value();

                  if (instruction == 0) {
                      vm.resume();
                      break;
                  }

                  log1(":::::: case: # " + i);

              //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ variable part

              switch (i) {

              case 0:
              testClassReference10 =
                                 (ReferenceType) vm.classesByName(testedClassName10).get(0);

              testClassReference20 =
                                 (ReferenceType) vm.classesByName(testedClassName20).get(0);

              thread1 = threadByName(threadName1);
              thread2 = threadByName(threadName2);

              eventRequest1 = setting21StepRequest(thread1, testClassReference10,
                                                         EventRequest.SUSPEND_NONE, property1);

              eventRequest2 = setting21StepRequest(thread2, testClassReference10,
                                                         EventRequest.SUSPEND_NONE, property2);

                            ((StepRequest) eventRequest1).addClassFilter(testClassReference10);
                            ((StepRequest) eventRequest2).addClassFilter(testClassReference20);

                            eventRequest1.enable();
                            eventRequest2.enable();


                            mainThread.resume();

                            log2("......waiting for StepEvent in expected thread");
                            getEventSet();

                            Event newEvent = eventIterator.nextEvent();
                                if ( !(newEvent instanceof StepEvent)) {
                                log3("ERROR: new event is not StepEvent");
                                testExitCode = FAILED;

      if (newEvent instanceof BreakpointEvent) {
          log3("ERROR: new event is BreakpointEvent");
          errorFlag = 1;
          break;
      }

                            } else {

                                String property = (String) newEvent.request().getProperty("number");
                                log2(" got new StepEvent with propety 'number' == " + property);
                      
                                if ( !property.equals(property1) ) {
                                    log3("ERROR: property is not : " + property1);
                                    testExitCode = FAILED;
                                }
                                if (eventSet.size() != 1) {
                                    log3("ERROR: eventSet.size() != 1 : " + eventSet.size());
                                    testExitCode = FAILED;
                                }
                            }
                            break;

                    default:
                            throw new JDITestRuntimeException("** default case 2 **");
                  }

      //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
              }
      log1(" TESTING ENDS");



      ///////////// code fragments in the debuggee


          static Thread1filter_rt003a thread1 = null;
          static Thread2filter_rt003a thread2 = null;

          static TestClass10 obj10 = new TestClass10();
          static TestClass20 obj20 = new TestClass20();

          //------------------------------------------------------ common section

          static int exitCode = PASSED;

          static int instruction = 1;
          static int end = 0;
                                         // static int quit = 0;
                                         // static int continue = 2;
          static int maxInstr = 1; // 2;

          static int lineForComm = 2;
          
          private static void methodForCommunication() {
              int i1 = instruction;
              int i2 = i1;
              int i3 = i2;
          }
          //---------------------------------------------------- main method
          
          public static void main (String argv[]) {

              argHandler = new ArgumentHandler(argv);
              log = argHandler.createDebugeeLog();

              log1("debuggee started!");

                  for (int i = 0; ; i++) {


                      if (instruction > maxInstr) {
      logErr("ERROR: unexpected instruction: " + instruction);
                          exitCode = FAILED;
      break ;
      }
       
                      switch (i) {

          //------------------------------------------------------ section tested
                          case 0:
                                  thread1 = new Thread1filter_rt003a("thread1");
                                  thread2 = new Thread2filter_rt003a("thread2");

         synchronized (lockObj2) {
         synchronized (lockObj1) {
                           threadStart(thread1);
                           threadStart(thread2);
                           log1("methodForCommunication();----1");
                           methodForCommunication();
                           }
                           try {
                           thread1.join();
                           } catch ( InterruptedException e ) {
                           }
                           }
                           try {
                           thread2.join();
                           } catch ( InterruptedException e ) {
                           }

          //------------------------------------------------- standard end section

                          default:
         instruction = end;
                           break;
                      }

                      log1("methodForCommunication();");
                      methodForCommunication();
                      if (instruction == end)
                          break;
                  }

              log1("debuggee exits");
              System.exit(exitCode + PASS_BASE);
          }

          static Object lockObj1 = new Object();
          static Object lockObj2 = new Object();
          static Object waitnotifyObj = new Object();

          static int threadStart(Thread t) {
              synchronized (waitnotifyObj) {
                  t.start();
                  try {
                      waitnotifyObj.wait();
                  } catch ( Exception e) {
                      exitCode = FAILED;
                      logErr(" Exception : " + e );
                      return FAILED;
                  }
              }
              return PASSED;
          }
      }

      class TestClass10{
          static void m10() {
              filter_rt003a.log1("entered: m10");
          }
      }
      class TestClass11 extends TestClass10{
          static void m11() {
              filter_rt003a.log1("entered: m11");
              TestClass10.m10();
          }
      }

      class Thread1filter_rt003a extends Thread {

          String tName = null;
       
          public Thread1filter_rt003a(String threadName) {
              super(threadName);
              tName = threadName;
          }
          
          public void run() {
              filter_rt003a.log1(" 'run': enter :: threadName == " + tName);
              synchronized(filter_rt003a.waitnotifyObj) {
                  filter_rt003a.waitnotifyObj.notify();
              }
              synchronized(filter_rt003a.lockObj1) {
                  TestClass11.m11();
              }
              filter_rt003a.log1(" 'run': exit :: threadName == " + tName);
              return;
          }
      }

      class TestClass20{
          static void m20() {
              filter_rt003a.log1("entered: m20");
          }
      }
      class TestClass21 extends TestClass20{
          static void m21() {
              filter_rt003a.log1("entered: m21");
              TestClass20.m20();
          }
      }

      class Thread2filter_rt003a extends Thread {

          String tName = null;
       
          public Thread2filter_rt003a(String threadName) {
              super(threadName);
              tName = threadName;
          }
          
          public void run() {
              filter_rt003a.log1(" 'run': enter :: threadName == " + tName);
              synchronized(filter_rt003a.waitnotifyObj) {
                  filter_rt003a.waitnotifyObj.notify();
              }
              synchronized(filter_rt003a.lockObj2) {
                  TestClass21.m21();
              }
              filter_rt003a.log1(" 'run': exit :: threadName == " + tName);
              return;
          }
      }


      ======================================================

      // log


      ==> nsk/jdi/StepRequest/addClassFilter_rt/filter_rt003 TESTING BEGINS
      --> debugger: breakpointForCommunication
      debugee.stderr> **> debuggee: debuggee started!
      debugee.stderr> **> debuggee: 'run': enter :: threadName == thread1
      debugee.stderr> **> debuggee: 'run': enter :: threadName == thread2
      debugee.stderr> **> debuggee: methodForCommunication();----1

      ==> nsk/jdi/StepRequest/addClassFilter_rt/filter_rt003 :::::: case: # 0
      --> debugger: ......setting up StepRequest:
      --> debugger: thread: instance of
      nsk.jdi.StepRequest.addClassFilter_rt.Thread1filter_rt003a(name='thread1', id=75); property:
      StepRequest1
      --> debugger: StepRequest has been set up
      --> debugger: ......setting up StepRequest:
      --> debugger: thread: instance of
      nsk.jdi.StepRequest.addClassFilter_rt.Thread2filter_rt003a(name='thread2', id=74); property:
      StepRequest2
      --> debugger: StepRequest has been set up
      --> debugger: ......waiting for StepEvent in expected thread
      debugee.stderr> **> debuggee: entered: m11
      debugee.stderr> **> debuggee: entered: m10
      debugee.stderr> **> debuggee: 'run': exit :: threadName == thread1
      debugee.stderr> **> debuggee: entered: m21
      debugee.stderr> **> debuggee: entered: m20
      debugee.stderr> **> debuggee: 'run': exit :: threadName == thread2
      debugee.stderr> **> debuggee: methodForCommunication();
      # ERROR: ##> debugger: ERROR: new event is not StepEvent
      # ERROR: ##> debugger: ERROR: new event is BreakpointEvent
      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

      debugee.stderr> **> debuggee: debuggee exits

      ==> nsk/jdi/StepRequest/addClassFilter_rt/filter_rt003 TESTING ENDS

      ----------------------------------------------------------------------
      ======================================================================

            swamyv Swamy Venkataramanappa
            bondsunw Bond Bond (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: