@@ -2719,6 +2719,51 @@ void java_lang_Throwable::get_stack_trace_elements(Handle throwable,
27192719 }
27202720}
27212721
2722+ Handle java_lang_Throwable::get_cause_with_stack_trace (Handle throwable, TRAPS) {
2723+ // Call to JVM to fill in the stack trace and clear declaringClassObject to
2724+ // not keep classes alive in the stack trace.
2725+ // call this: public StackTraceElement[] getStackTrace()
2726+ assert (throwable.not_null (), " shouldn't be" );
2727+
2728+ JavaValue result (T_ARRAY);
2729+ JavaCalls::call_virtual (&result, throwable,
2730+ vmClasses::Throwable_klass (),
2731+ vmSymbols::getStackTrace_name (),
2732+ vmSymbols::getStackTrace_signature (),
2733+ CHECK_NH);
2734+ Handle stack_trace (THREAD, result.get_oop ());
2735+ assert (stack_trace->is_objArray (), " Should be an array" );
2736+
2737+ // Throw ExceptionInInitializerError as the cause with this exception in
2738+ // the message and stack trace.
2739+
2740+ // Now create the message with the original exception and thread name.
2741+ Symbol* message = java_lang_Throwable::detail_message (throwable ());
2742+ ResourceMark rm (THREAD);
2743+ stringStream st;
2744+ st.print (" Exception %s%s " , throwable ()->klass ()->name ()->as_klass_external_name (),
2745+ message == nullptr ? " " : " :" );
2746+ if (message == NULL ) {
2747+ st.print (" [in thread \" %s\" ]" , THREAD->name ());
2748+ } else {
2749+ st.print (" %s [in thread \" %s\" ]" , message->as_C_string (), THREAD->name ());
2750+ }
2751+
2752+ Symbol* exception_name = vmSymbols::java_lang_ExceptionInInitializerError ();
2753+ Handle h_cause = Exceptions::new_exception (THREAD, exception_name, st.as_string ());
2754+
2755+ // If new_exception returns a different exception while creating the exception, return null.
2756+ if (h_cause->klass ()->name () != exception_name) {
2757+ log_info (class , init)(" Exception thrown while saving initialization exception %s" ,
2758+ h_cause->klass ()->external_name ());
2759+ return Handle ();
2760+ }
2761+ java_lang_Throwable::set_stacktrace (h_cause (), stack_trace ());
2762+ // Clear backtrace because the stacktrace should be used instead.
2763+ set_backtrace (h_cause (), NULL );
2764+ return h_cause;
2765+ }
2766+
27222767bool java_lang_Throwable::get_top_method_and_bci (oop throwable, Method** method, int * bci) {
27232768 JavaThread* current = JavaThread::current ();
27242769 objArrayHandle result (current, objArrayOop (backtrace (throwable)));
0 commit comments