JDK-8060147 : SIGSEGV in Metadata::mark_on_stack() while marking metadata in ciEnv
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 8u40,9
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2014-10-10
  • Updated: 2016-06-14
  • Resolved: 2014-11-11
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 8 JDK 9
8u40Fixed 9 b42Fixed
Related Reports
Duplicate :  
Relates :  
Description
#
#  SIGSEGV (0xb) at pc=0x00007fad3e410cac, pid=105294, tid=140381245028096
#
# JRE version: OpenJDK Runtime Environment (9.0) (build 1.9.0-internal-vlivanov_2014_09_19_07_15-b00)
# Java VM: OpenJDK 64-Bit Server VM (1.9.0-internal-vlivanov_2014_09_19_07_15-b00 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# V  [libjvm.so+0x819cac]  Metadata::mark_on_stack(Metadata*)+0xc

Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V  [libjvm.so+0x819cac]  Metadata::mark_on_stack(Metadata*)+0xc
V  [libjvm.so+0x41c857]  ciObjectFactory::metadata_do(void (*)(Metadata*))+0x47
V  [libjvm.so+0x9c5e6e]  JavaThread::metadata_do(void (*)(Metadata*))+0x16e
V  [libjvm.so+0x9c5eab]  Threads::metadata_do(void (*)(Metadata*))+0x2b
V  [libjvm.so+0x819bd8]  MetadataOnStackMark::MetadataOnStackMark(bool)+0x28
V  [libjvm.so+0x450034]  ClassLoaderDataGraph::do_unloading(BoolObjectClosure*)+0x44
V  [libjvm.so+0x992e38]  SystemDictionary::do_unloading(BoolObjectClosure*)+0x18
V  [libjvm.so+0x8ea0cf]  PSParallelCompact::marking_phase(ParCompactionManager*, bool, ParallelOldTracer*)+0x53f
V  [libjvm.so+0x8efa06]  PSParallelCompact::invoke_no_policy(bool)+0x476
V  [libjvm.so+0x8f02b4]  PSParallelCompact::invoke(bool)+0x64
V  [libjvm.so+0xa1c50e]  VM_ParallelGCSystemGC::doit()+0x10e
V  [libjvm.so+0xa22bf2]  VM_Operation::evaluate()+0x52
V  [libjvm.so+0xa21121]  VMThread::evaluate_operation(VM_Operation*)+0xb1
V  [libjvm.so+0xa21573]  VMThread::loop()+0x1c3
V  [libjvm.so+0xa21a42]  VMThread::run()+0x72
V  [libjvm.so+0x895642]  java_start(Thread*)+0x122

VM_Operation (0x00007fad0c2507e0): ParallelGCSystemGC, mode: safepoint, requested by thread 0x00007fac20001000

How to reproduce:
  - apply 8060147.jdk.patch (attached); it stresses VM anonymous class unloading
  - run Octane:
     $ java -jar microbenchmarks.jar -f 0 '.*octane.Typescript.*' &
  - stress frequent full GCs:
     $ while sleep 1; do jcmd $! GC.run; done; 
Comments
noreg-hard: compiler thread should use a Metadata* which is unloaded during the same compilation. The failure occurs on the next full GC, if the compilation is still running.
29-10-2014

Yes, I checked that ciObjectFactory isn't pruned during it's lifetime (the whole compilation), so there's no need to associate ciObject w/ ciMetadata. I'll wrap the change into appropriate comments before sending it out for review. Thanks again for your help!
24-10-2014

I think you need to save 'h' above in the ciMetadata object. Or just creating the ciObject puts it into the handle area for the duration of the compilation, so this is fine, right? You'll need some comments around this as it looks like code that doesn't do anything!
24-10-2014

[~coleenp], thanks for the detailed analysis! I've tried the following patch and it fixed the problem: diff --git a/src/share/vm/ci/ciObjectFactory.cpp b/src/share/vm/ci/ciObjectFactory.cpp --- a/src/share/vm/ci/ciObjectFactory.cpp +++ b/src/share/vm/ci/ciObjectFactory.cpp @@ -353,6 +353,22 @@ ciMetadata* ciObjectFactory::create_new_object(Metadata* o) { EXCEPTION_CONTEXT; + if (_initialized) { + Klass* holder; + if (o->is_klass()) { + holder = ((Klass*)o); + } else if (o->is_method()) { + holder = ((Method*)o)->method_holder(); + } else if (o->is_methodData()) { + holder = ((MethodData*)o)->method()->method_holder(); + } else { + ShouldNotReachHere(); + } + if (holder != NULL && holder->klass_holder() != NULL) { + ciObject* h = get(holder->klass_holder()); + } + } + if (o->is_klass()) { KlassHandle h_k(THREAD, (Klass*)o); Klass* k = (Klass*)o;
24-10-2014

The comments in ciObjectFactory.cpp are wrong for ciMetadata and were never updated for permgen elimination. Creating a ciMetadata looks to see if one has already been created, so adding a JNI local handle for the klass_holder() might not be be too inefficient (or you can you look up the ciObject referring to the klass_holder and not have to create a new one?) I can't reproduce this on my machine or I'd try out the suggested fix myself.
15-10-2014

I think this is a compiler bug. When ci_metadata were ci_objects we had to have GC walk these oops. The class_holder (class_loader or mirror for jsr292 classes) should be walked to keep the types in ci_metadata alive. The compiler does this for ci (but I can't find it because it's different than how we keep the holder alive for other metadata). Now I remember. ciObjects use jobject handles, which are local and somehow cleaned up when the compilation is finished (can't find that now). ciMetadata needs to have the holders added as handles in the same way. This was never done. Or something more efficient should be done.
15-10-2014

I've added the following verification when metadata is stored into ciObjectFactory and retrieved for marking [1]. It crashes only during marking. So, when metadata is stored it is correct. It seems that metadata was erroneously unloaded though it is referenced from ciEnv. [1] diff --git a/src/share/vm/ci/ciObjectFactory.cpp b/src/share/vm/ci/ciObjectFactory.cpp --- a/src/share/vm/ci/ciObjectFactory.cpp +++ b/src/share/vm/ci/ciObjectFactory.cpp @@ -267,7 +267,7 @@ // is created. ciMetadata* ciObjectFactory::get_metadata(Metadata* key) { ASSERT_IN_VM; - + assert(key->is_metaspace_object() && key->is_metadata(), ""); #ifdef ASSERT if (CIObjectFactoryVerify) { Metadata* last = NULL; @@ -751,6 +751,7 @@ if (_ci_metadata == NULL) return; for (int j = 0; j< _ci_metadata->length(); j++) { Metadata* o = _ci_metadata->at(j)->constant_encoding(); + assert(o->is_metaspace_object() && o->is_metadata(), ""); f(o); } }
10-10-2014

The crash occurs while processing C1 compiler thread. It compiles some methods from Octane/Nashorn: Stack trace: #0 pthread_cond_wait@@GLIBC_2.3.2 #1 os::PlatformEvent::park #2 ParkCommon #3 Monitor::ILock #4 Monitor::lock_without_safepoint_check #5 Monitor::lock_without_safepoint_check #6 SafepointSynchronize::block #7 JavaThread::check_safepoint_and_suspend_for_native_trans #8 ThreadStateTransition::transition_from_native #9 ThreadStateTransition::trans_from_native #10 ThreadInVMfromNative::ThreadInVMfromNative #11 ciBytecodeStream::get_klass #12 GraphBuilder::check_cast #13 GraphBuilder::iterate_bytecodes_for_block #14 GraphBuilder::iterate_all_blocks #15 GraphBuilder::try_inline_full #16 GraphBuilder::try_inline #17 GraphBuilder::invoke #18 GraphBuilder::iterate_bytecodes_for_block #19 GraphBuilder::iterate_all_blocks #20 GraphBuilder::try_inline_full #21 GraphBuilder::try_inline #22 GraphBuilder::try_method_handle_inline #23 GraphBuilder::try_inline #24 GraphBuilder::invoke #25 GraphBuilder::iterate_bytecodes_for_block #26 GraphBuilder::connect_to_end #27 GraphBuilder::iterate_all_blocks #28 GraphBuilder::try_inline_full #29 GraphBuilder::try_inline #30 GraphBuilder::try_method_handle_inline #31 GraphBuilder::try_inline #32 GraphBuilder::invoke #33 GraphBuilder::iterate_bytecodes_for_block #34 GraphBuilder::iterate_all_blocks #35 GraphBuilder::try_inline_full #36 GraphBuilder::try_inline #37 GraphBuilder::invoke #38 GraphBuilder::iterate_bytecodes_for_block #39 GraphBuilder::connect_to_end #40 GraphBuilder::iterate_all_blocks #41 GraphBuilder::GraphBuilder #42 IRScope::build_graph #43 IRScope::IRScope #44 IR::IR #45 Compilation::build_hir #46 Compilation::compile_java_method #47 Compilation::compile_method #48 Compilation::Compilation #49 Compiler::compile_method #50 CompileBroker::invoke_compiler_on_method #51 CompileBroker::compiler_thread_loop #52 compiler_thread_entry #53 JavaThread::thread_main_inner #54 JavaThread::run
10-10-2014