@@ -114,15 +114,17 @@ bool Exceptions::special_exception(JavaThread* thread, const char* file, int lin
114
114
#endif // ASSERT
115
115
116
116
if (h_exception.is_null () && !thread->can_call_java ()) {
117
- ResourceMark rm (thread);
118
- const char * exc_value = h_name != nullptr ? h_name->as_C_string () : " null" ;
119
- log_info (exceptions)(" Thread cannot call Java so instead of throwing exception <%.*s%s%.*s> (" PTR_FORMAT " ) \n "
120
- " at [%s, line %d]\n for thread " PTR_FORMAT " ,\n "
121
- " throwing pre-allocated exception: %s" ,
122
- MAX_LEN, exc_value, message ? " : " : " " ,
123
- MAX_LEN, message ? message : " " ,
124
- p2i (h_exception ()), file, line, p2i (thread),
125
- Universe::vm_exception ()->print_value_string ());
117
+ if (log_is_enabled (Info, exceptions)) {
118
+ ResourceMark rm (thread);
119
+ const char * exc_value = h_name != nullptr ? h_name->as_C_string () : " null" ;
120
+ log_info (exceptions)(" Thread cannot call Java so instead of throwing exception <%.*s%s%.*s> (" PTR_FORMAT " ) \n "
121
+ " at [%s, line %d]\n for thread " PTR_FORMAT " ,\n "
122
+ " throwing pre-allocated exception: %s" ,
123
+ MAX_LEN, exc_value, message ? " : " : " " ,
124
+ MAX_LEN, message ? message : " " ,
125
+ p2i (h_exception ()), file, line, p2i (thread),
126
+ Universe::vm_exception ()->print_value_string ());
127
+ }
126
128
// We do not care what kind of exception we get for a thread which
127
129
// is compiling. We just install a dummy exception object
128
130
thread->set_pending_exception (Universe::vm_exception (), file, line);
@@ -152,6 +154,9 @@ void Exceptions::_throw(JavaThread* thread, const char* file, int line, Handle h
152
154
message ? " : " : " " ,
153
155
MAX_LEN, message ? message : " " ,
154
156
p2i (h_exception ()), file, line, p2i (thread));
157
+ if (log_is_enabled (Info, exceptions, stacktrace)) {
158
+ log_exception_stacktrace (h_exception);
159
+ }
155
160
156
161
// for AbortVMOnException flag
157
162
Exceptions::debug_check_abort (h_exception, message);
@@ -609,3 +614,42 @@ void Exceptions::log_exception(Handle exception, const char* message) {
609
614
MAX_LEN, message);
610
615
}
611
616
}
617
+
618
+ // This is called from InterpreterRuntime::exception_handler_for_exception(), which is the only
619
+ // easy way to be notified in the VM that an _athrow bytecode has been executed. (The alternative
620
+ // would be to add hooks into the interpreter and compiler, for all platforms ...).
621
+ //
622
+ // Unfortunately, InterpreterRuntime::exception_handler_for_exception() is called for every level
623
+ // of the Java stack when looking for an exception handler. To avoid excessive output,
624
+ // we print the stack only when the bci points to an _athrow bytecode.
625
+ //
626
+ // NOTE: exceptions that are NOT thrown by _athrow are handled by Exceptions::special_exception()
627
+ // and Exceptions::_throw()).
628
+ void Exceptions::log_exception_stacktrace (Handle exception, methodHandle method, int bci) {
629
+ if (!method->is_native () && (Bytecodes::Code) *method->bcp_from (bci) == Bytecodes::_athrow) {
630
+ // TODO: try to find a way to avoid repeated stacktraces when an exception gets re-thrown
631
+ // by a finally block
632
+ log_exception_stacktrace (exception);
633
+ }
634
+ }
635
+
636
+ // This should be called only from a live Java thread.
637
+ void Exceptions::log_exception_stacktrace (Handle exception) {
638
+ LogStreamHandle (Info, exceptions, stacktrace) st;
639
+ ResourceMark rm;
640
+ const char * detail_message = java_lang_Throwable::message_as_utf8 (exception ());
641
+ if (detail_message != nullptr ) {
642
+ st.print_cr (" Exception <%.*s: %.*s>" ,
643
+ MAX_LEN, exception->print_value_string (),
644
+ MAX_LEN, detail_message);
645
+ } else {
646
+ st.print_cr (" Exception <%.*s>" ,
647
+ MAX_LEN, exception->print_value_string ());
648
+ }
649
+ JavaThread* t = JavaThread::current ();
650
+ if (t->has_last_Java_frame ()) {
651
+ t->print_active_stack_on (&st);
652
+ } else {
653
+ st.print_cr (" (Cannot print stracktrace)" );
654
+ }
655
+ }
0 commit comments