JDK-4427753 : JDI: two StackFrame methods throw unspecified NullPointerException
  • Type: Bug
  • Component: core-svc
  • Sub-Component: debugger
  • Affected Version: 1.3.1,1.4.0
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: generic
  • CPU: generic
  • Submitted: 2001-03-20
  • Updated: 2001-03-30
  • Resolved: 2001-03-30
Related Reports
Duplicate :  
Description

Name: elR10090			Date: 03/20/2001




The method   
           StackFrame.getValue(LocalVariable variable)

throws unspecified NullPointerException when 
LocalVariable argument is null.


The method   
          StackFrame.getValues(java.util.List variables)

throws unspecified NullPointerException when 
there is the null argument in the List.


NullPointerException is not in the specifications for either of two methods;
the specifications contain the same list of the following Exceptions to be 
thrown:

    java.lang.IllegalArgumentException
    InvalidStackFrameException 
    VMMismatchException


These unspecified results are observed
for JDI versions 1.3.1-rc1-b19 and 1.4.0-beta-b56
when HS 1.3.1-rc1-b19, or HS 1.4.0-beta-b56, is runnning a test program
on the following H/S configurations:

 - SUNW Ultra1: sparc 200MHz, RAM 128Mb;  
   OS: Solaris-8;            
   JVM: Client & Server
 - Intel: two Pentium-III 600MHz processors, RAM 512Mb;  
   OS: Solaris-8;            
   JVM: Client & Server
 - Intel: two Pentium-III 600MHz processors, 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 the debugger
and corresponding logs for the tested cases are below.


Steps to reproduce the bug:
1. cd /net/sqesvr.eng/export/vsn/GammaBase/Bugs/{this bug ID}
2. ksh doit1.sh {JAVA_HOME}  for  StackFrame.getValue()
   or  
2. ksh doit2.sh {JAVA_HOME}  for  StackFrame.getValues()


The tests 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 tests:
    
    nsk/jdi/StackFrame/getValue/getvalue003
    nsk/jdi/StackFrame/getValues/getvalues003



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

// code fragments in the debugger

-------------------------
//StackFrame/getValue/getvalue003


    log2("     enabling breakpRequest2");
    breakpRequest2.enable();

    log2("       forcing the main thread to leave synchronized block");
    pipe.println("continue");
    line = pipe.readln();
    if (!line.equals("docontinue")) {
        log3("ERROR: returned string is not 'docontinue'");
        expresult = returnCode4;
        break label1;
    }

    expresult = breakpoint();
    if (expresult != returnCode0) 
        break label1;

    log2("      the thread2 is at the breakpoint");
    log2("      the check that the thread2 is suspended at the breakpoint");               
    if ( thread2.isSuspended() ) {
        log2("     :   thread2.isSuspended()");
    } else {
        log3("ERROR:  !thread2.isSuspended()");
        expresult = returnCode1;
        break label1;
    }

    log2("      getting current StackFrame");
    try {
        stackFrame = thread2.frame(0);
    } catch ( Exception e ) {
        log3("ERROR: Exception for stackFrame = thread2.frame(0)    :" + e);
        expresult = returnCode1;
        break label1;
    }

    log2("      checking up StackFrame.getValue(null)");
    try {
        Value value = stackFrame.getValue(null);               
        log3("     :  no Exception for: stackFrame.getValue(null);");        
    } catch ( Exception e ) {
        log3("ERROR: Exception for: stackFrame.getValue(null); :" + e);
        expresult = returnCode1;
        break label1;
    }

--------------------
//StackFrame/getValues/getvalues003


    log2("     enabling breakpRequest2");
    breakpRequest2.enable();

    log2("       forcing the main thread to leave synchronized block");
    pipe.println("continue");
    line = pipe.readln();
    if (!line.equals("docontinue")) {
        log3("ERROR: returned string is not 'docontinue'");
        expresult = returnCode4;
        break label1;
    }

    expresult = breakpoint();
    if (expresult != returnCode0) 
        break label1;

    log2("      the thread2 is at the breakpoint");
    log2("      the check that the thread2 is suspended at the breakpoint");               
    if ( thread2.isSuspended() ) {
        log2("     :   thread2.isSuspended()");
    } else {
        log3("ERROR:  !thread2.isSuspended()");
        expresult = returnCode1;
        break label1;
    }

    try {
        stackFrame = thread2.frame(0);
    } catch ( Exception e ) {
        log3("ERROR: Exception for stackFrame = thread2.frame(0)    :" + e);
        expresult = returnCode1;
        break label1;
    }

    List testedVars = null;
    
    log2("       executing the following: ");             
    log2("           List testedVars = null;"); 
    log2("           testedVars = stackFrame.visibleVariables();");             
    log2("           testedVars.set(1, null);  // putting null into the list");
    try {
        testedVars = stackFrame.visibleVariables();
        testedVars.set(1, null);
        log2(":       no Exception thrown");
    } catch ( AbsentInformationException e1 ) {
        log3("ERROR: AbsentInformationException for testedVars = 
runMethod.variables()");
        expresult = returnCode1;
        break label1;
    } catch ( Exception e ) {
        log3("ERROR:  Exception :  " + e);            
    }

    log2("     executing the following: "); 
    log2("         Map returnedVars  = stackFrame.getValues(testedVars);");
    try {
        Map returnedVars  = stackFrame.getValues(testedVars);
        log2(":       no Exception thrown");
    } catch ( Exception e ) {
        log3("ERROR: Exception for:  stackFrame.getValues(testedVars);  " + e);            
        expresult = returnCode1;
        break label1;
    }


======================================================
// log with comments


// log for nsk/jdi/StackFrame/getValue/getvalue003


==> nsk/jdi/StackFrame/getValue/getvalue003        TESTING BEGINS
debugee.err> **> mainThread: waiting for an instruction from the debugger ...
debugee.err> **> mainThread:        thread2 is created
debugee.err> **> mainThread:        synchronized (waitnotifyObj) { enter
debugee.err> **> mainThread:        before: test_thread.start()
debugee.err> **> thread2: method 'run' enter
debugee.err> **> mainThread:        before:   waitnotifyObj.wait();
debugee.err> **> thread2: entered into block:  synchronized (waitnotifyObj)
debugee.err> **> thread2: exited from block:  synchronized (waitnotifyObj)
debugee.err> **> mainThread:        after:    waitnotifyObj.wait();

==> nsk/jdi/StackFrame/getValue/getvalue003  new check: #0
--> getvalue003: getting ThreadReference object
--> getvalue003: suspending thread2 to get its StackFrame object
--> getvalue003: setting up breakpoints
--> getvalue003: setting up a breakpoint: method: 'runt1' line: 
breakpointLineNumber1
--> getvalue003:       a breakpoint has been set up
--> getvalue003: setting up a breakpoint: method: 'runt2' line: 
breakpointLineNumber2
--> getvalue003:       a breakpoint has been set up
--> getvalue003:      enabling breakpRequest2
--> getvalue003:        forcing the main thread to leave synchronized block
debugee.err> **> thread2: entered into block:  synchronized (lockingObject)
debugee.err> **> thread2: exited from block:  synchronized (lockingObject)
debugee.err> **> thread2: call to the method 'runt1'
debugee.err> **> thread2: method 'runt1' enter
debugee.err> **> thread2: call to 'runt2' 
debugee.err> **> thread2: method 'runt2' enter
debugee.err> **> mainThread: mainThread is out of: synchronized (lockingObject) 
{
debugee.err> **> mainThread: waiting for an instruction from the debugger ...
--> getvalue003:        waiting for BreakpointEvent
--> getvalue003:        new:  eventSet = eventQueue.remove();
--> getvalue003:      :  eventSet != null;  size == 1
--> getvalue003:       VMStartEvent removed
--> getvalue003:        new:  eventSet = eventQueue.remove();
--> getvalue003:      :  eventSet != null;  size == 1
--> getvalue003:       BreakpointEvent removed
--> getvalue003:      :  eventSet == null:  EventQueue is empty
--> getvalue003:       the thread2 is at the breakpoint
--> getvalue003:       the check that the thread2 is suspended at the breakpoint
--> getvalue003:      :   thread2.isSuspended()
--> getvalue003:       getting current StackFrame
--> getvalue003:       checking up StackFrame.getValue(null)
##> getvalue003: ERROR: Exception for: stackFrame.getValue(null); 
:java.lang.NullPointerException
                 
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
^
                 
                 
--> getvalue003:       resuming the thread2 for case it was suspended but not 
resumed yet
debugee.err> **> thread2: method 'runt2' body
debugee.err> **> thread2: method 'runt2' exit
debugee.err> **> thread2: returned from 'runt2' 
debugee.err> **> thread2: method 'runt1' body
debugee.err> **> thread2: method 'runt1' exit
debugee.err> **> thread2: returned from the method 'runt1'
debugee.err> **> thread2: method 'run' exit
--> getvalue003:      the end of testing
debugee.err> **> mainThread: waiting for an instruction from the debugger ...
--> getvalue003:      : returned string is 'checkend'

==> nsk/jdi/StackFrame/getValue/getvalue003        TESTING ENDS
debugee.err> **> mainThread: 'quit' recieved
--> getvalue003: waiting for the debuggee to finish ...
--> getvalue003: debuggee returned expected exit status: 95 == PASS_BASE
TEST FAILED


--------------
//log for nsk/jdi/StackFrame/getValues/getvalues003 


==> nsk/jdi/StackFrame/getValues/getvalues003        TESTING BEGINS
debugee.err> **> mainThread: waiting for an instruction from the debugger ...
debugee.err> **> mainThread:        thread2 is created
debugee.err> **> mainThread:        synchronized (waitnotifyObj) { enter
debugee.err> **> mainThread:        before: test_thread.start()
debugee.err> **> thread2: method 'run' enter
debugee.err> **> mainThread:        before:   waitnotifyObj.wait();
debugee.err> **> thread2: entered into block:  synchronized (waitnotifyObj)
debugee.err> **> thread2: exited from block:  synchronized (waitnotifyObj)
debugee.err> **> mainThread:        after:    waitnotifyObj.wait();

==> nsk/jdi/StackFrame/getValues/getvalues003  new check: #0
--> debugger: getting ThreadReference object
--> debugger: suspending thread2 to get its StackFrame object
--> debugger: setting up breakpoints
--> debugger: setting up a breakpoint: method: 'runt1' line: 
breakpointLineNumber1
--> debugger:       a breakpoint has been set up
--> debugger: setting up a breakpoint: method: 'runt2' line: 
breakpointLineNumber2
--> debugger:       a breakpoint has been set up
--> debugger:      enabling breakpRequest2
--> debugger:        forcing the main thread to leave synchronized block
debugee.err> **> thread2: entered into block:  synchronized (lockingObject)
debugee.err> **> thread2: exited from block:  synchronized (lockingObject)
debugee.err> **> thread2: call to the method 'runt1'
debugee.err> **> thread2: method 'runt1' enter
debugee.err> **> mainThread: mainThread is out of: synchronized (lockingObject) 
{
debugee.err> **> mainThread: waiting for an instruction from the debugger ...
--> debugger:        waiting for BreakpointEvent
--> debugger:        new:  eventSet = eventQueue.remove();
--> debugger:      :  eventSet != null;  size == 1
--> debugger:       VMStartEvent removed
--> debugger:        new:  eventSet = eventQueue.remove();
--> debugger:      :  eventSet != null;  size == 1
--> debugger:       BreakpointEvent removed
--> debugger:      :  eventSet == null:  EventQueue is empty
--> debugger:       the thread2 is at the breakpoint
--> debugger:       the check that the thread2 is suspended at the breakpoint
--> debugger:      :   thread2.isSuspended()
--> debugger:        executing the following: 
--> debugger:            List testedVars = null;
--> debugger:            testedVars = stackFrame.visibleVariables();
--> debugger:            testedVars.set(1, null);  // putting up null into the 
list
--> debugger: :       no Exception thrown
--> debugger:      executing the following: 
--> debugger:          Map returnedVars  = stackFrame.getValues(testedVars);
##> debugger: ERROR: Exception for:  stackFrame.getValues(testedVars);  
java.lang.NullPointerException
              
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^

--> debugger:       resuming the thread2 for case it was suspended but not 
resumed yet
debugee.err> **> thread2: method 'runt2' enter
debugee.err> **> thread2: method 'runt2' body
debugee.err> **> thread2: method 'runt2' exit
debugee.err> **> thread2: method 'runt1' body
debugee.err> **> thread2: method 'runt1' exit
debugee.err> **> thread2: returned from the method 'runt1'
debugee.err> **> thread2: method 'run' exit
--> debugger:      the end of testing
debugee.err> **> mainThread: waiting for an instruction from the debugger ...
--> debugger:      : returned string is 'checkend'

==> nsk/jdi/StackFrame/getValues/getvalues003        TESTING ENDS
debugee.err> **> mainThread: 'quit' recieved
--> debugger: waiting for the debuggee to finish ...
--> debugger: debuggee returned expected exit status: 95 == PASS_BASE
TEST FAILED

----------------------------------------------------------------------

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

Name: elR10090			Date: 04/27/2001



This bug also affects the following testbase_nsk test:
    
    nsk/jdi/StackFrame/setValue/setvalue005


The tests will be in the release r05 of testbase_nsk.


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

Comments
EVALUATION This is really a far more general issue then these two methods
11-06-2004