aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Balao <mbalao@redhat.com>2024-02-21 23:31:47 +0000
committerVitaly Provodin <vitaly.provodin@jetbrains.com>2024-04-19 15:36:04 +0700
commitf2e1645f5083aceb57d59bb43d4247f0539fc20e (patch)
tree66787935637f67228e02f7ecce7394cbf4ee8c6a
parent1c948e7fdef2f52e7de184d46ee7f3f2be3e23f9 (diff)
downloadJetBrainsRuntime-f2e1645f5083aceb57d59bb43d4247f0539fc20e.tar.gz
8319851: Improve exception logging
Reviewed-by: mbaesken Backport-of: 87dfeeb14fdd0fa1648a8bec91b5b713cc2c1b83
-rw-r--r--src/hotspot/share/classfile/javaClasses.cpp29
-rw-r--r--src/hotspot/share/classfile/javaClasses.hpp8
-rw-r--r--src/hotspot/share/classfile/resolutionErrors.cpp23
-rw-r--r--src/hotspot/share/classfile/resolutionErrors.hpp21
-rw-r--r--src/hotspot/share/classfile/systemDictionary.cpp6
-rw-r--r--src/hotspot/share/classfile/systemDictionary.hpp4
-rw-r--r--src/hotspot/share/oops/constantPool.cpp38
-rw-r--r--src/hotspot/share/oops/cpCache.cpp4
-rw-r--r--src/hotspot/share/utilities/exceptions.cpp6
9 files changed, 72 insertions, 67 deletions
diff --git a/src/hotspot/share/classfile/javaClasses.cpp b/src/hotspot/share/classfile/javaClasses.cpp
index ccd3dc4a181..8dd894348c9 100644
--- a/src/hotspot/share/classfile/javaClasses.cpp
+++ b/src/hotspot/share/classfile/javaClasses.cpp
@@ -2079,18 +2079,17 @@ oop java_lang_Throwable::message(oop throwable) {
return throwable->obj_field(_detailMessage_offset);
}
-oop java_lang_Throwable::cause(oop throwable) {
- return throwable->obj_field(_cause_offset);
+const char* java_lang_Throwable::message_as_utf8(oop throwable) {
+ oop msg = java_lang_Throwable::message(throwable);
+ const char* msg_utf8 = nullptr;
+ if (msg != nullptr) {
+ msg_utf8 = java_lang_String::as_utf8_string(msg);
+ }
+ return msg_utf8;
}
-// Return Symbol for detailed_message or NULL
-Symbol* java_lang_Throwable::detail_message(oop throwable) {
- PreserveExceptionMark pm(Thread::current());
- oop detailed_message = java_lang_Throwable::message(throwable);
- if (detailed_message != NULL) {
- return java_lang_String::as_symbol(detailed_message);
- }
- return NULL;
+oop java_lang_Throwable::cause(oop throwable) {
+ return throwable->obj_field(_cause_offset);
}
void java_lang_Throwable::set_message(oop throwable, oop value) {
@@ -2744,15 +2743,19 @@ Handle java_lang_Throwable::create_initialization_error(JavaThread* current, Han
assert(throwable.not_null(), "shouldn't be");
// Now create the message from the original exception and thread name.
- Symbol* message = java_lang_Throwable::detail_message(throwable());
ResourceMark rm(current);
stringStream st;
+ const char *message = nullptr;
+ oop detailed_message = java_lang_Throwable::message(throwable());
+ if (detailed_message != nullptr) {
+ message = java_lang_String::as_utf8_string(detailed_message);
+ }
st.print("Exception %s%s ", throwable()->klass()->name()->as_klass_external_name(),
message == nullptr ? "" : ":");
- if (message == NULL) {
+ if (message == nullptr) {
st.print("[in thread \"%s\"]", current->name());
} else {
- st.print("%s [in thread \"%s\"]", message->as_C_string(), current->name());
+ st.print("%s [in thread \"%s\"]", message, current->name());
}
Symbol* exception_name = vmSymbols::java_lang_ExceptionInInitializerError();
diff --git a/src/hotspot/share/classfile/javaClasses.hpp b/src/hotspot/share/classfile/javaClasses.hpp
index 2f90b54ad36..bce0f5343f7 100644
--- a/src/hotspot/share/classfile/javaClasses.hpp
+++ b/src/hotspot/share/classfile/javaClasses.hpp
@@ -553,12 +553,14 @@ class java_lang_Throwable: AllStatic {
static void set_backtrace(oop throwable, oop value);
static int depth(oop throwable);
static void set_depth(oop throwable, int value);
- static int get_detailMessage_offset() { CHECK_INIT(_detailMessage_offset); }
// Message
+ static int get_detailMessage_offset() { CHECK_INIT(_detailMessage_offset); }
static oop message(oop throwable);
- static oop cause(oop throwable);
+ static const char* message_as_utf8(oop throwable);
static void set_message(oop throwable, oop value);
- static Symbol* detail_message(oop throwable);
+
+ static oop cause(oop throwable);
+
static void print_stack_element(outputStream *st, Method* method, int bci);
static void compute_offsets();
diff --git a/src/hotspot/share/classfile/resolutionErrors.cpp b/src/hotspot/share/classfile/resolutionErrors.cpp
index 24a5bcab3a8..4e647871d2a 100644
--- a/src/hotspot/share/classfile/resolutionErrors.cpp
+++ b/src/hotspot/share/classfile/resolutionErrors.cpp
@@ -36,8 +36,8 @@
// create new error entry
void ResolutionErrorTable::add_entry(int index, unsigned int hash,
const constantPoolHandle& pool, int cp_index,
- Symbol* error, Symbol* message,
- Symbol* cause, Symbol* cause_msg)
+ Symbol* error, const char* message,
+ Symbol* cause, const char* cause_msg)
{
assert_locked_or_safepoint(SystemDictionary_lock);
assert(!pool.is_null() && error != NULL, "adding NULL obj");
@@ -95,11 +95,8 @@ void ResolutionErrorEntry::set_error(Symbol* e) {
}
}
-void ResolutionErrorEntry::set_message(Symbol* c) {
- _message = c;
- if (_message != NULL) {
- _message->increment_refcount();
- }
+void ResolutionErrorEntry::set_message(const char* c) {
+ _message = c != nullptr ? os::strdup(c) : nullptr;
}
void ResolutionErrorEntry::set_cause(Symbol* c) {
@@ -109,13 +106,11 @@ void ResolutionErrorEntry::set_cause(Symbol* c) {
}
}
-void ResolutionErrorEntry::set_cause_msg(Symbol* c) {
- _cause_msg = c;
- if (_cause_msg != NULL) {
- _cause_msg->increment_refcount();
- }
+void ResolutionErrorEntry::set_cause_msg(const char* c) {
+ _cause_msg = c != nullptr ? os::strdup(c) : nullptr;
}
+// The incoming nest host error message is already in the C-Heap.
void ResolutionErrorEntry::set_nest_host_error(const char* message) {
_nest_host_error = message;
}
@@ -126,13 +121,13 @@ void ResolutionErrorTable::free_entry(ResolutionErrorEntry *entry) {
entry->error()->decrement_refcount();
}
if (entry->message() != NULL) {
- entry->message()->decrement_refcount();
+ FREE_C_HEAP_ARRAY(char, entry->message());
}
if (entry->cause() != NULL) {
entry->cause()->decrement_refcount();
}
if (entry->cause_msg() != NULL) {
- entry->cause_msg()->decrement_refcount();
+ FREE_C_HEAP_ARRAY(char, entry->cause_msg());
}
if (entry->nest_host_error() != NULL) {
FREE_C_HEAP_ARRAY(char, entry->nest_host_error());
diff --git a/src/hotspot/share/classfile/resolutionErrors.hpp b/src/hotspot/share/classfile/resolutionErrors.hpp
index 8a9c9951ba1..31a56385860 100644
--- a/src/hotspot/share/classfile/resolutionErrors.hpp
+++ b/src/hotspot/share/classfile/resolutionErrors.hpp
@@ -61,11 +61,11 @@ public:
}
void add_entry(int index, unsigned int hash,
- const constantPoolHandle& pool, int which, Symbol* error, Symbol* message,
- Symbol* cause, Symbol* cause_msg);
+ const constantPoolHandle& pool, int cp_index, Symbol* error, const char* error_msg,
+ Symbol* cause, const char* cause_msg);
void add_entry(int index, unsigned int hash,
- const constantPoolHandle& pool, int which, const char* message);
+ const constantPoolHandle& pool, int cp_index, const char* message);
// find error given the constant pool and constant pool index
ResolutionErrorEntry* find_entry(int index, unsigned int hash,
@@ -96,9 +96,9 @@ class ResolutionErrorEntry : public HashtableEntry<ConstantPool*, mtClass> {
private:
int _cp_index;
Symbol* _error;
- Symbol* _message;
+ const char* _message;
Symbol* _cause;
- Symbol* _cause_msg;
+ const char* _cause_msg;
const char* _nest_host_error;
public:
@@ -110,16 +110,19 @@ class ResolutionErrorEntry : public HashtableEntry<ConstantPool*, mtClass> {
Symbol* error() const { return _error; }
void set_error(Symbol* e);
- Symbol* message() const { return _message; }
- void set_message(Symbol* c);
+ const char* message() const { return _message; }
+ // The incoming message is copied to the C-Heap.
+ void set_message(const char* c);
Symbol* cause() const { return _cause; }
void set_cause(Symbol* c);
- Symbol* cause_msg() const { return _cause_msg; }
- void set_cause_msg(Symbol* c);
+ const char* cause_msg() const { return _cause_msg; }
+ // The incoming cause_msg is copied to the C-Heap.
+ void set_cause_msg(const char* c);
const char* nest_host_error() const { return _nest_host_error; }
+ // The incoming nest host error message is already in the C-Heap.
void set_nest_host_error(const char* message);
ResolutionErrorEntry* next() const {
diff --git a/src/hotspot/share/classfile/systemDictionary.cpp b/src/hotspot/share/classfile/systemDictionary.cpp
index 9af7dd9d1a2..6f02814e146 100644
--- a/src/hotspot/share/classfile/systemDictionary.cpp
+++ b/src/hotspot/share/classfile/systemDictionary.cpp
@@ -1887,8 +1887,8 @@ bool SystemDictionary::add_loader_constraint(Symbol* class_name,
// Add entry to resolution error table to record the error when the first
// attempt to resolve a reference to a class has failed.
void SystemDictionary::add_resolution_error(const constantPoolHandle& pool, int which,
- Symbol* error, Symbol* message,
- Symbol* cause, Symbol* cause_msg) {
+ Symbol* error, const char* message,
+ Symbol* cause, const char* cause_msg) {
unsigned int hash = resolution_errors()->compute_hash(pool, which);
int index = resolution_errors()->hash_to_index(hash);
{
@@ -1907,7 +1907,7 @@ void SystemDictionary::delete_resolution_error(ConstantPool* pool) {
// Lookup resolution error table. Returns error if found, otherwise NULL.
Symbol* SystemDictionary::find_resolution_error(const constantPoolHandle& pool, int which,
- Symbol** message, Symbol** cause, Symbol** cause_msg) {
+ const char** message, Symbol** cause, const char** cause_msg) {
unsigned int hash = resolution_errors()->compute_hash(pool, which);
int index = resolution_errors()->hash_to_index(hash);
{
diff --git a/src/hotspot/share/classfile/systemDictionary.hpp b/src/hotspot/share/classfile/systemDictionary.hpp
index 65185a29b10..4acee8ed389 100644
--- a/src/hotspot/share/classfile/systemDictionary.hpp
+++ b/src/hotspot/share/classfile/systemDictionary.hpp
@@ -288,10 +288,10 @@ public:
// Record the error when the first attempt to resolve a reference from a constant
// pool entry to a class fails.
static void add_resolution_error(const constantPoolHandle& pool, int which, Symbol* error,
- Symbol* message, Symbol* cause = NULL, Symbol* cause_msg = NULL);
+ const char* message, Symbol* cause = NULL, const char* cause_msg = NULL);
static void delete_resolution_error(ConstantPool* pool);
static Symbol* find_resolution_error(const constantPoolHandle& pool, int which,
- Symbol** message, Symbol** cause, Symbol** cause_msg);
+ const char** message, Symbol** cause, const char** cause_msg);
// Record a nest host resolution/validation error
diff --git a/src/hotspot/share/oops/constantPool.cpp b/src/hotspot/share/oops/constantPool.cpp
index a97f2fe8d02..53e166c0c69 100644
--- a/src/hotspot/share/oops/constantPool.cpp
+++ b/src/hotspot/share/oops/constantPool.cpp
@@ -767,13 +767,16 @@ void ConstantPool::resolve_string_constants_impl(const constantPoolHandle& this_
}
}
-static Symbol* exception_message(const constantPoolHandle& this_cp, int which, constantTag tag, oop pending_exception) {
+static const char* exception_message(const constantPoolHandle& this_cp, int which, constantTag tag, oop pending_exception) {
+ // Note: caller needs ResourceMark
+
// Dig out the detailed message to reuse if possible
- Symbol* message = java_lang_Throwable::detail_message(pending_exception);
- if (message != NULL) {
- return message;
+ const char* msg = java_lang_Throwable::message_as_utf8(pending_exception);
+ if (msg != nullptr) {
+ return msg;
}
+ Symbol* message = nullptr;
// Return specific message for the tag
switch (tag.value()) {
case JVM_CONSTANT_UnresolvedClass:
@@ -796,49 +799,48 @@ static Symbol* exception_message(const constantPoolHandle& this_cp, int which, c
ShouldNotReachHere();
}
- return message;
+ return message != nullptr ? message->as_C_string() : nullptr;
}
-static void add_resolution_error(const constantPoolHandle& this_cp, int which,
+static void add_resolution_error(JavaThread* current, const constantPoolHandle& this_cp, int which,
constantTag tag, oop pending_exception) {
+ ResourceMark rm(current);
Symbol* error = pending_exception->klass()->name();
oop cause = java_lang_Throwable::cause(pending_exception);
// Also dig out the exception cause, if present.
Symbol* cause_sym = NULL;
- Symbol* cause_msg = NULL;
+ const char* cause_msg = nullptr;
if (cause != NULL && cause != pending_exception) {
cause_sym = cause->klass()->name();
- cause_msg = java_lang_Throwable::detail_message(cause);
+ cause_msg = java_lang_Throwable::message_as_utf8(cause);
}
- Symbol* message = exception_message(this_cp, which, tag, pending_exception);
+ const char* message = exception_message(this_cp, which, tag, pending_exception);
SystemDictionary::add_resolution_error(this_cp, which, error, message, cause_sym, cause_msg);
}
void ConstantPool::throw_resolution_error(const constantPoolHandle& this_cp, int which, TRAPS) {
ResourceMark rm(THREAD);
- Symbol* message = NULL;
+ const char* message = NULL;
Symbol* cause = NULL;
- Symbol* cause_msg = NULL;
+ const char* cause_msg = NULL;
Symbol* error = SystemDictionary::find_resolution_error(this_cp, which, &message, &cause, &cause_msg);
assert(error != NULL, "checking");
- const char* cause_str = cause_msg != NULL ? cause_msg->as_C_string() : NULL;
CLEAR_PENDING_EXCEPTION;
if (message != NULL) {
- char* msg = message->as_C_string();
if (cause != NULL) {
- Handle h_cause = Exceptions::new_exception(THREAD, cause, cause_str);
- THROW_MSG_CAUSE(error, msg, h_cause);
+ Handle h_cause = Exceptions::new_exception(THREAD, cause, cause_msg);
+ THROW_MSG_CAUSE(error, message, h_cause);
} else {
- THROW_MSG(error, msg);
+ THROW_MSG(error, message);
}
} else {
if (cause != NULL) {
- Handle h_cause = Exceptions::new_exception(THREAD, cause, cause_str);
+ Handle h_cause = Exceptions::new_exception(THREAD, cause, cause_msg);
THROW_CAUSE(error, h_cause);
} else {
THROW(error);
@@ -860,7 +862,7 @@ void ConstantPool::save_and_throw_exception(const constantPoolHandle& this_cp, i
// and OutOfMemoryError, etc, or if the thread was hit by stop()
// Needs clarification to section 5.4.3 of the VM spec (see 6308271)
} else if (this_cp->tag_at(which).value() != error_tag) {
- add_resolution_error(this_cp, which, tag, PENDING_EXCEPTION);
+ add_resolution_error(THREAD, this_cp, which, tag, PENDING_EXCEPTION);
// CAS in the tag. If a thread beat us to registering this error that's fine.
// If another thread resolved the reference, this is a race condition. This
// thread may have had a security manager or something temporary.
diff --git a/src/hotspot/share/oops/cpCache.cpp b/src/hotspot/share/oops/cpCache.cpp
index b0cd727427f..d247b428179 100644
--- a/src/hotspot/share/oops/cpCache.cpp
+++ b/src/hotspot/share/oops/cpCache.cpp
@@ -499,9 +499,9 @@ bool ConstantPoolCacheEntry::save_and_throw_indy_exc(
CLEAR_PENDING_EXCEPTION;
return false;
}
-
+ ResourceMark rm(THREAD);
Symbol* error = PENDING_EXCEPTION->klass()->name();
- Symbol* message = java_lang_Throwable::detail_message(PENDING_EXCEPTION);
+ const char* message = java_lang_Throwable::message_as_utf8(PENDING_EXCEPTION);
SystemDictionary::add_resolution_error(cpool, index, error, message);
set_indy_resolution_failed();
diff --git a/src/hotspot/share/utilities/exceptions.cpp b/src/hotspot/share/utilities/exceptions.cpp
index bd95b8306be..d65f5bcfafd 100644
--- a/src/hotspot/share/utilities/exceptions.cpp
+++ b/src/hotspot/share/utilities/exceptions.cpp
@@ -563,11 +563,11 @@ void Exceptions::debug_check_abort_helper(Handle exception, const char* message)
// for logging exceptions
void Exceptions::log_exception(Handle exception, const char* message) {
ResourceMark rm;
- Symbol* detail_message = java_lang_Throwable::detail_message(exception());
- if (detail_message != NULL) {
+ const char* detail_message = java_lang_Throwable::message_as_utf8(exception());
+ if (detail_message != nullptr) {
log_info(exceptions)("Exception <%s: %s>\n thrown in %s",
exception->print_value_string(),
- detail_message->as_C_string(),
+ detail_message,
message);
} else {
log_info(exceptions)("Exception <%s>\n thrown in %s",