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

JDI: StackFrame.getValue() swap bytes of long value

XMLWordPrintable

    • sparc
    • solaris_8



      Name: elR10090 Date: 02/27/2001




      The method StackFrame.getValue()
      returns incorrect value of a tested instance field
      when it is applied to a long type variable of a method.

      This incorrect returned result is observed
      for JDI version 1.3.1-rc1-b17
      when HS 1.3.1-rc1-b17 is runnning a test program
      on the following H/S configurations:

          SUNW Ultra1: sparc 200MHz, RAM 128Mb;
          OS: Solaris-8;
          JVM: Client & Server


      Since access to instance fields of methods is possible
      if debuggee method's thread has been suspended by an event,
      a special test program implementing such suspension is used
      to test values returned by the method StackFrame.getValue().

      When a tested instance field is a long variable
      a value returned by the method is not
      as it must be in big-endian order, high_bytes first then low_bytes,
      but as it has been read in reverse, small-endian order,
      low_bytes then high_bytes.

      Below, there are corresponding code fragments
      in the debugger and debuggee,
      and corresponding log for two tested long values

          long ln1 = 0, ln2 = 0x1234567890abcdefL;


      The log shows as follows.

      Step1:
      Action: The tested value ln2 is read from the debuggee
              into the debugger first time,
              into the LocalVariable lnv2.
      Result: The value in the debugger is:

                       lnv2= 0x90abcdef12345678
                       
              that is equal to 32-bit swap.

      Step2:
      Action: The value having read in the step1,
              is written back into the debugger,
              into the method variable ln1.
      Result: The value in the debuggee is:

                       ln1= 0x90abcdef12345678
              
              Hence, the value is written back correctly.

      Step3:
      Action: The above value ln1 is read from the debuggee
              into the debugger second time,
              into the LocalVariable lnv1.
      Result: The value in the debugger is:

                       lnv1= 0xffffffff90abcdef

              The swap occurs second time,.
              However, there is some additional side effect
              because one of two 32-bit words changes values of its bits.

      Thus, in Steps 1 and 3 when a value has been read from the debuggee,
      a source and result values didn't match each other.



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



      The test will be in the next release of testbase_nsk
      which is accessable through:

          /net/sqesvr.eng/export/vsn/VM/testbase/testbase_nsk


          This bug affects the following testbase_nsk test:
          
          nsk/jdi/StackFrame/getValue/getvalue001
          nsk/jdi/StackFrame/setValue/setvalue001


      ======================================================================
      // the testing code in the debugger:

      case 6: LongValue lnv1 = null;
              LongValue lnv2 = null;
          
              locvar1 = stackFrame.visibleVariableByName(ln1);
              locvar2 = stackFrame.visibleVariableByName(ln2);
              if (locvar1 == null || locvar2 == null) {
                  log3("ERROR: 'locvar1 == null || locvar2 == null' for Long");
                  expresult = 1;
                  break;
              }

              lnv2 = (LongValue) stackFrame.getValue(locvar2);
              lnv1 = (LongValue) stackFrame.getValue(locvar1);
              log2("1 : lnv1= 0x" + Long.toHexString(lnv1.value())
                          + " lnv2= 0x" + Long.toHexString(lnv2.value()) );

              stackFrame.setValue(locvar1, lnv2);

              lnv1 = (LongValue) stackFrame.getValue(locvar1);
              log2("2 : lnv1= 0x" + Long.toHexString(lnv1.value())
                          + " lnv2= 0x" + Long.toHexString(lnv2.value()));
              if (lnv1.value() != 0x1234567890abcdefL) {
                  log3("ERROR: lnv1 != 0x1234567890abcdefL : "
                             + Long.toHexString(lnv1.value()) );
                  expresult = 1;
              }

              break


      ---------------
      //the method runt() with the tested code in the debuggee:
         
          public void runt() {
              
              boolean bl1 = true, bl2 = false;
              byte bt1 = 0, bt2 = 1;
              char ch1 = 0, ch2 = 1;
              double db1 = 0.0d, db2 = 1111111111.0d;
              float fl1 = 0.0f, fl2 = 1111111111.0f;
              int in1 = 0, in2 = 1;
              long ln1 = 0, ln2 = 0x1234567890abcdefL;
              short sh1 = 0, sh2 = 1;
                  
              setvalue001a.log1("method 'runt' enter");
              setvalue001a.log1("1 : ln1= 0x" + Long.toHexString(ln1) + " ln2=
      0x" + Long.toHexString(ln2));
              setvalue001a.log1("method 'runt' body");
              setvalue001a.log1("2 : ln1= 0x" + Long.toHexString(ln1) + " ln2=
      0x" + Long.toHexString(ln2));
              setvalue001a.log1("method 'runt' exit");

              return;
          }
      ---------------
      // log:

      **> setvalue001a: method 'runt' enter

      **> setvalue001a: 1 : ln1= 0x0 ln2= 0x1234567890abcdef
                                                  ^^^^^^^^^^^^^^^^^^
                                                initial value in the debuggee
                                              
      **> setvalue001a: method 'runt' body
      **> setvalue001a: waiting for an instruction from the debugger ...
      --> setvalue001: 44444444444444
      --> setvalue001: 44444444 threadRef.isSuspended

      --> setvalue001: 1 : lnv1= 0x0 lnv2= 0x90abcdef12345678
                                                   ^^^^^^^^^^^^^^^^^^
                                        Step1: value read into the debugger first
      time

      --> setvalue001: 2 : lnv1= 0xffffffff90abcdef lnv2= 0x90abcdef12345678
                                        ^^^^^^^^^^^^^^^^^^
                               Step3: value read into the debugger second time
                                                   
      ##> setvalue001: ERROR: lnv1 != 0x1234567890abcdefL : ffffffff90abcdef
      --> setvalue001: 5555555555555555

      **> setvalue001a: 2 : ln1= 0x90abcdef12345678 ln2= 0x1234567890abcdef
                                        ^^^^^^^^^^^^^^^^^^
                               Step2: value written back into the debuggee
       
      **> setvalue001a: method 'runt' exit




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

            Unassigned Unassigned
            latkinsunw Latkin Latkin (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: