JDK-4890957 : VM resumes on request to step-over in NPE location
  • Type: Bug
  • Component: vm-legacy
  • Sub-Component: jvmdi
  • Affected Version: 6
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic,solaris_9,windows_2000
  • CPU: generic,x86,sparc
  • Submitted: 2003-07-15
  • Updated: 2004-08-30
  • Resolved: 2004-08-30
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6
6 mustangFixed
Related Reports
Relates :  
Description

Name: tb29552			Date: 07/15/2003


FULL PRODUCT VERSION :
java version "1.4.2"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2-b28)
Java HotSpot(TM) Client VM (build 1.4.2-b28, mixed mode)

A DESCRIPTION OF THE PROBLEM :
When debugging the following sample program (using Eclipse JDI debugger), a breakpoint is placed on a line that will cause an NullPointerException to be generated. The line is then stepped over. The step request never completes - instead the VM resumes execution. The problem appears to occurr on 1.3.1 and 1.4.1 VMs as well as 1.4.2 VMs (does work on 1.2.2). The problem does not occurr with IBM VMs (1.3.1 and higher).

Sample program (breakpoint on line 11, as indicated).

public class StepOver {
  public static void main(String[] args) {
    try {
      foo();
    } catch (Exception e) {
    }
    while (true);
  }
  private static void foo() {
    String s= null;
    s.charAt(0);      // <-- breakpoint here
  }
}
 


REPRODUCIBILITY :
This bug can be reproduced always.
(Review ID: 190900) 
======================================================================

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: mustang FIXED IN: mustang INTEGRATED IN: mustang
31-08-2004

EVALUATION ###@###.### 2003-11-20 Not enough time to fix for tiger. Name: dd4877 Date: 07/28/2004 daniel.daugherty@Sun 2004-07-28 InterpreterRuntime::resolve_invoke() & InterpreterRuntime::resolve_get_put() are used to resolve methods and non-primitive fields. Bytecodes executed during the resolution process are considered "internal" by the debugger and are not interesting to the regular debugger user. For example: String s = "Random String"; s.charAt(0); If I'm using the debugger to step over the above code fragment, then the virtual method resolution process necessary to resolve s.charAt into a method that can be called is not very interesting to me as a debugger user. The solution is to hide single stepping events for such "internal bytecodes". This solution was implemented in the following delta: src/share/vm/interpreter/interpreterRuntime.cpp: D 1.351 00/05/22 17:46:37 dcubed 724 722 00021/00005/00662 MRs: ====================================================================== Name: dd4877 Date: 07/28/2004 daniel.daugherty@Sun 2004-07-28 (update 1) The previous entry got truncated. This solution was implemented in the following delta: src/share/vm/interpreter/interpreterRuntime.cpp: D 1.351 00/05/22 17:46:37 dcubed 724 722 00021/00005/00662 MRs: <delta>COMMENTS: 4331369 - Need to track event type in compare_and_set_current_location(). Resolve_get_put() and resolve_invoke() need to hide single stepping when Java code is called on the caller's behalf. 4337667 - Restore interpreter's _breakpoint() function; looping breakpoint fix needs to be done in compare_and_set_current_location(). The relevant bug is: 4331369 2/5 jdb: it needs to call 'step' twice to step from brkpoint in main The fix for 4331369 is incomplete. It is possible for resolution to throw an exception and that code path is not covered by the hide_single_stepping flag support that I added in 4331369. ======================================================================
31-08-2004

SUGGESTED FIX Name: dd4877 Date: 07/28/2004 daniel.daugherty@Sun 2004-07-28 Here are the context diffs for the suggested fix: ------- src/share/vm/prims/jvmtiExport.hpp ------- *** /tmp/sccs.kjaqSQ Wed Jul 28 10:57:39 2004 --- jvmtiExport.hpp Tue Jul 27 22:20:15 2004 *************** *** 531,534 **** --- 531,560 ---- } }; + + // JvmtiHideSingleStepping is a helper class for hiding + // internal single step events. + class JvmtiHideSingleStepping : public StackObj { + private: + bool _single_step_hidden; + JavaThread * _thread; + + public: + JvmtiHideSingleStepping(JavaThread * thread) { + assert(thread != NULL, "sanity check"); + + _single_step_hidden = false; + _thread = thread; + if (JvmtiExport::should_post_single_step()) { + _single_step_hidden = JvmtiExport::hide_single_stepping(_thread); + } + } + + ~JvmtiHideSingleStepping() { + if (_single_step_hidden) { + JvmtiExport::expose_single_stepping(_thread); + } + } + }; + #endif /* _JAVA_JVMTIEXPORT_H_ */ Note: in the following diff I ignored whitespace changes ------- src/share/vm/interpreter/interpreterRuntime.cpp ------- *** /tmp/sccs.RnaWsR Wed Jul 28 10:58:32 2004 --- interpreterRuntime.cpp Wed Jul 28 08:33:49 2004 *************** *** 402,416 **** FieldAccessInfo info; constantPoolHandle pool(thread, method(thread)->constants()); bool is_static = (bytecode == Bytecodes::_getstatic || bytecode == Bytecodes::_putstatic); - bool single_step_hidden = false; - if (JvmtiExport::should_post_single_step()) { - single_step_hidden = JvmtiExport::hide_single_stepping(thread); - } - LinkResolver::resolve_field(info, pool, two_byte_index(thread), bytecode, false, CHECK); - if (single_step_hidden) { - JvmtiExport::expose_single_stepping(thread); - } // check if link resolution caused cpCache to be updated if (already_resolved(thread)) return; --- 402,414 ---- FieldAccessInfo info; constantPoolHandle pool(thread, method(thread)->constants()); bool is_static = (bytecode == Bytecodes::_getstatic || bytecode == Bytecodes::_putstatic); + { + JvmtiHideSingleStepping jhss(thread); + LinkResolver::resolve_field(info, pool, two_byte_index(thread), + bytecode, false, CHECK); + } // end JvmtiHideSingleStepping + // check if link resolution caused cpCache to be updated if (already_resolved(thread)) return; *************** *** 559,568 **** CallInfo info; constantPoolHandle pool(thread, method(thread)->constants()); ! bool single_step_hidden = false; ! if (JvmtiExport::should_post_single_step()) { ! single_step_hidden = JvmtiExport::hide_single_stepping(thread); ! } LinkResolver::resolve_invoke(info, receiver, pool, two_byte_index(thread), bytecode, CHECK); if (JvmtiExport::can_hotswap_or_post_breakpoint()) { --- 557,564 ---- CallInfo info; constantPoolHandle pool(thread, method(thread)->constants()); ! { ! JvmtiHideSingleStepping jhss(thread); LinkResolver::resolve_invoke(info, receiver, pool, two_byte_index(thread), bytecode, CHECK); if (JvmtiExport::can_hotswap_or_post_breakpoint()) { *************** *** 578,587 **** two_byte_index(thread), bytecode, CHECK); } } - if (single_step_hidden) { - JvmtiExport::expose_single_stepping(thread); - } // check if link resolution caused cpCache to be updated if (already_resolved(thread)) return; --- 574,581 ---- two_byte_index(thread), bytecode, CHECK); } } + } // end JvmtiHideSingleStepping // check if link resolution caused cpCache to be updated if (already_resolved(thread)) return; ======================================================================
31-08-2004

PUBLIC COMMENTS .
31-08-2004