JDK-6453681 : AsyncGetCallTrace and CLASS_UNLOAD event reveal bad memory delete
  • Type: Bug
  • Component: vm-legacy
  • Sub-Component: jvmpi
  • Affected Version: 6
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2006-07-27
  • Updated: 2010-04-02
  • Resolved: 2006-08-10
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 b95Fixed
Related Reports
Relates :  
Relates :  
Description
During stress testing of the fix for the following bug:

    6432598 3/3 SEGV in forte backtrace walker under collect command

the fastdebug bits failed the following assertion:

#  Internal Error (src/share/vm/memory/allocation.cpp, 44 [ Patched ]), pid=14601, tid=3
#
# Java VM: Java HotSpot(TM) Client VM (mustang-fastdebug-debug mixed mode)
#
# Error: assert(((ResourceObj *)p)->allocated_on_C_heap(),"delete only allowed for C_HEAP objects")

Here is the relevant part of the stack trace:

  [6] report_assertion_failure(file_name = ???, line_no = ???, message = ???) (optimized), at 0xfdbba220 (line ~210) in "debug.cpp"
  [7] ResourceObj::operator delete(p = ???) (optimized), at 0xfd861b88 (line ~44) in "allocation.cpp"
  [8] jvmpi::post_class_unload_events() (optimized), at 0xfdf45e20 (line ~942) in "jvmpi.cpp"
  [9] GenCollectedHeap::do_collection(this = ???, full = ???, clear_all_soft_refs = ???, size = ???, is_tlab = ???, max_level = ???) (optimized), at 0xfdc3331c
(line ~609) in "genCollectedHeap.cpp"
  [10] GenCollectedHeap::do_full_collection(this = ???, clear_all_soft_refs = ???, max_level = ???) (optimized), at 0xfdc34c40 (line ~810) in "genCollectedHeap.cpp"
  [11] VM_GenCollectFull::doit(this = ???) (optimized), at 0xfe5a4188 (line ~117) in "vmGCOperations.cpp"
  [12] VM_Operation::evaluate(this = ???) (optimized), at 0xfe5cc06c (line ~25)
in "vm_operations.cpp"
  [13] VMThread::evaluate_operation(this = ???, op = ???) (optimized), at 0xfe5ca274 (line ~314) in "vmThread.cpp"
  [14] VMThread::loop(this = ???) (optimized), at 0xfe5caa64 (line ~423) in "vmThread.cpp"
  [15] VMThread::run(this = ???) (optimized), at 0xfe5c9d74 (line ~227) in "vmThread.cpp"

I have attached the complete thread dump as threads.log.9.

Comments
SUGGESTED FIX Here is the context diff for the proposed fix: ------- src/share/vm/prims/jvmpi.cpp ------- *** /tmp/sccs.nba46Y Thu Jul 27 11:13:05 2006 --- jvmpi.cpp Thu Jul 27 11:12:59 2006 *************** *** 955,961 **** if (unloaded_classes == NULL) { // first unloaded class so setup initial space for the events ! unloaded_classes = new GrowableArray<JVMPI_Event*>(5); } unloaded_classes->append(ev); } --- 955,962 ---- if (unloaded_classes == NULL) { // first unloaded class so setup initial space for the events ! unloaded_classes = ! new (ResourceObj::C_HEAP) GrowableArray<JVMPI_Event*>(5, true); } unloaded_classes->append(ev); }
27-07-2006

EVALUATION The CLASS_UNLOAD event info is stored on the side during GC and then the events are posted when it is safe to do so. 834 // List of classes unloaded for the duration of the CLASS_UNLOAD event 835 // handler. Populated by save_class_unload_event_info(), queried by both 836 // post_class_load_event() and post_class_unload_events(), and cleaned 837 // up by post_class_unload_events(). 838 static GrowableArray<JVMPI_Event*>* unloaded_classes = NULL; <snip> 948 // GC has caused a class to be unloaded so save CLASS_LOAD information 949 // just in case there is a RequestEvent(CLASS_LOAD) call from the 950 // CLASS_UNLOAD event handler. 951 void jvmpi::save_class_unload_event_info(oop k) { 952 JVMPI_Event *ev = new JVMPI_Event(); 953 fillin_class_load_event(k, ev, false /* don't fillin JNI id values */); 954 ev->event_type |= JVMPI_REQUESTED_EVENT; 955 956 if (unloaded_classes == NULL) { 957 // first unloaded class so setup initial space for the events 958 unloaded_classes = new GrowableArray<JVMPI_Event*>(5); 959 } 960 unloaded_classes->append(ev); 961 } The GrowableArray elements are allocated on line 958, but they allocated as a ResourceObj instead of on the C-heap. Oops. The line should look like this: unloaded_classes = new (ResourceObj::C_HEAP) GrowableArray<JVMPI_Event*>(5, true);
27-07-2006