diff --git a/src/hotspot/share/utilities/exceptions.cpp b/src/hotspot/share/utilities/exceptions.cpp index 3e0683999e1..e11b55b84a2 100644 --- a/src/hotspot/share/utilities/exceptions.cpp +++ b/src/hotspot/share/utilities/exceptions.cpp @@ -139,17 +139,37 @@ void Exceptions::_throw_oop(JavaThread* thread, const char* file, int line, oop _throw(thread, file, line, h_exception); } +static void dump_oome_native_stack(Handle& exception, outputStream& st, Thread* thread) { + if (exception->klass() == vmClasses::OutOfMemoryError_klass()) { + st.print_cr("\n"); + char buf[O_BUFLEN]; + address lastpc = nullptr; + if (os::platform_print_native_stack(&st, nullptr, buf, O_BUFLEN, lastpc)) { + // We have printed the native stack in platform-specific code, + // so nothing else to do in this case. + } else { + frame f = os::current_frame(); + VMError::print_native_stack(&st, f, thread, true /*print_source_info */, + -1 /* max stack_stream */, buf, O_BUFLEN); + } + } +} + void Exceptions::_throw(JavaThread* thread, const char* file, int line, Handle h_exception, const char* message) { ResourceMark rm(thread); assert(h_exception() != nullptr, "exception should not be null"); // tracing (do this up front - so it works during boot strapping) // Note, the print_value_string() argument is not called unless logging is enabled! + + stringStream stack_stream; + dump_oome_native_stack(h_exception, stack_stream, thread); + log_info(exceptions)("Exception <%s%s%s> (" PTR_FORMAT ") \n" - "thrown [%s, line %d]\nfor thread " PTR_FORMAT, + "thrown [%s, line %d]\nfor thread " PTR_FORMAT "%s", h_exception->print_value_string(), message ? ": " : "", message ? message : "", - p2i(h_exception()), file, line, p2i(thread)); + p2i(h_exception()), file, line, p2i(thread), stack_stream.as_string()); // for AbortVMOnException flag Exceptions::debug_check_abort(h_exception, message); @@ -567,14 +587,18 @@ void Exceptions::debug_check_abort_helper(Handle exception, const char* message) void Exceptions::log_exception(Handle exception, const char* message) { ResourceMark rm; Symbol* detail_message = java_lang_Throwable::detail_message(exception()); + + stringStream stack_stream; + dump_oome_native_stack(exception, stack_stream, Thread::current()); + if (detail_message != nullptr) { - log_info(exceptions)("Exception <%s: %s>\n thrown in %s", + log_info(exceptions)("Exception <%s: %s>\n thrown in %s%s", exception->print_value_string(), detail_message->as_C_string(), - message); + message, stack_stream.as_string()); } else { - log_info(exceptions)("Exception <%s>\n thrown in %s", + log_info(exceptions)("Exception <%s>\n thrown in %s%s", exception->print_value_string(), - message); + message, stack_stream.as_string()); } }