mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 07:14:30 +02:00
8308151: [JVMCI] capture JVMCI exceptions in hs-err
Reviewed-by: never
This commit is contained in:
parent
beb75e651f
commit
05c095cf39
12 changed files with 400 additions and 70 deletions
|
@ -311,25 +311,138 @@ void JVMCIEnv::init(JavaThread* thread, bool is_hotspot, bool jni_enomem_is_fata
|
|||
}
|
||||
}
|
||||
|
||||
// Prints a pending exception (if any) and its stack trace.
|
||||
void JVMCIEnv::describe_pending_exception(bool clear) {
|
||||
JavaThread* THREAD = JavaThread::current(); // For exception macros.
|
||||
if (!is_hotspot()) {
|
||||
JNIAccessMark jni(this, THREAD);
|
||||
if (jni()->ExceptionCheck()) {
|
||||
jthrowable ex = !clear ? jni()->ExceptionOccurred() : nullptr;
|
||||
jni()->ExceptionDescribe();
|
||||
if (ex != nullptr) {
|
||||
jni()->Throw(ex);
|
||||
// Prints a pending exception (if any) and its stack trace to st.
|
||||
// Also partially logs the stack trace to the JVMCI event log.
|
||||
void JVMCIEnv::describe_pending_exception(outputStream* st) {
|
||||
ResourceMark rm;
|
||||
char* stack_trace = nullptr;
|
||||
if (pending_exception_as_string(nullptr, (const char**) &stack_trace)) {
|
||||
st->print_raw_cr(stack_trace);
|
||||
|
||||
// Use up to half the lines of the JVMCI event log to
|
||||
// show the stack trace.
|
||||
char* cursor = stack_trace;
|
||||
int line = 0;
|
||||
const int max_lines = LogEventsBufferEntries / 2;
|
||||
char* last_line = nullptr;
|
||||
while (*cursor != '\0') {
|
||||
char* eol = strchr(cursor, '\n');
|
||||
if (eol == nullptr) {
|
||||
if (line == max_lines - 1) {
|
||||
last_line = cursor;
|
||||
} else if (line < max_lines) {
|
||||
JVMCI_event_1("%s", cursor);
|
||||
}
|
||||
cursor = cursor + strlen(cursor);
|
||||
} else {
|
||||
*eol = '\0';
|
||||
if (line == max_lines - 1) {
|
||||
last_line = cursor;
|
||||
} else if (line < max_lines) {
|
||||
JVMCI_event_1("%s", cursor);
|
||||
}
|
||||
cursor = eol + 1;
|
||||
}
|
||||
line++;
|
||||
}
|
||||
} else {
|
||||
if (HAS_PENDING_EXCEPTION) {
|
||||
JVMCIRuntime::describe_pending_hotspot_exception(THREAD, clear);
|
||||
if (last_line != nullptr) {
|
||||
if (line > max_lines) {
|
||||
JVMCI_event_1("%s [elided %d more stack trace lines]", last_line, line - max_lines);
|
||||
} else {
|
||||
JVMCI_event_1("%s", last_line);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool JVMCIEnv::pending_exception_as_string(const char** to_string, const char** stack_trace) {
|
||||
JavaThread* THREAD = JavaThread::current(); // For exception macros.
|
||||
JVMCIObject to_string_obj;
|
||||
JVMCIObject stack_trace_obj;
|
||||
bool had_nested_exception = false;
|
||||
if (!is_hotspot()) {
|
||||
JNIAccessMark jni(this, THREAD);
|
||||
jthrowable ex = jni()->ExceptionOccurred();
|
||||
if (ex != NULL) {
|
||||
jni()->ExceptionClear();
|
||||
jobjectArray pair = (jobjectArray) jni()->CallStaticObjectMethod(
|
||||
JNIJVMCI::HotSpotJVMCIRuntime::clazz(),
|
||||
JNIJVMCI::HotSpotJVMCIRuntime::exceptionToString_method(),
|
||||
ex, to_string != nullptr, stack_trace != nullptr);
|
||||
if (jni()->ExceptionCheck()) {
|
||||
// As last resort, dump nested exception
|
||||
jni()->ExceptionDescribe();
|
||||
had_nested_exception = true;
|
||||
} else {
|
||||
guarantee(pair != nullptr, "pair is null");
|
||||
int len = jni()->GetArrayLength(pair);
|
||||
guarantee(len == 2, "bad len is %d", len);
|
||||
if (to_string != nullptr) {
|
||||
to_string_obj = JVMCIObject::create(jni()->GetObjectArrayElement(pair, 0), false);
|
||||
}
|
||||
if (stack_trace != nullptr) {
|
||||
stack_trace_obj = JVMCIObject::create(jni()->GetObjectArrayElement(pair, 1), false);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (HAS_PENDING_EXCEPTION) {
|
||||
Handle exception(THREAD, PENDING_EXCEPTION);
|
||||
CLEAR_PENDING_EXCEPTION;
|
||||
JavaCallArguments jargs;
|
||||
jargs.push_oop(exception);
|
||||
jargs.push_int(to_string != nullptr);
|
||||
jargs.push_int(stack_trace != nullptr);
|
||||
JavaValue result(T_OBJECT);
|
||||
JavaCalls::call_static(&result,
|
||||
HotSpotJVMCI::HotSpotJVMCIRuntime::klass(),
|
||||
vmSymbols::exceptionToString_name(),
|
||||
vmSymbols::exceptionToString_signature(), &jargs, THREAD);
|
||||
if (HAS_PENDING_EXCEPTION) {
|
||||
Handle nested_exception(THREAD, PENDING_EXCEPTION);
|
||||
CLEAR_PENDING_EXCEPTION;
|
||||
java_lang_Throwable::print_stack_trace(nested_exception, tty);
|
||||
// Clear and ignore any exceptions raised during printing
|
||||
CLEAR_PENDING_EXCEPTION;
|
||||
had_nested_exception = true;
|
||||
} else {
|
||||
oop pair = result.get_oop();
|
||||
guarantee(pair->is_objArray(), "must be");
|
||||
objArrayOop pair_arr = objArrayOop(pair);
|
||||
int len = pair_arr->length();
|
||||
guarantee(len == 2, "bad len is %d", len);
|
||||
if (to_string != nullptr) {
|
||||
to_string_obj = HotSpotJVMCI::wrap(pair_arr->obj_at(0));
|
||||
}
|
||||
if (stack_trace != nullptr) {
|
||||
stack_trace_obj = HotSpotJVMCI::wrap(pair_arr->obj_at(1));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (had_nested_exception) {
|
||||
if (to_string != nullptr) {
|
||||
*to_string = "nested exception occurred converting exception to string";
|
||||
}
|
||||
if (stack_trace != nullptr) {
|
||||
*stack_trace = "nested exception occurred converting exception stack to string";
|
||||
}
|
||||
} else {
|
||||
if (to_string_obj.is_non_null()) {
|
||||
*to_string = as_utf8_string(to_string_obj);
|
||||
}
|
||||
if (stack_trace_obj.is_non_null()) {
|
||||
*stack_trace = as_utf8_string(stack_trace_obj);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Shared code for translating an exception from HotSpot to libjvmci or vice versa.
|
||||
class ExceptionTranslation: public StackObj {
|
||||
protected:
|
||||
|
@ -771,10 +884,11 @@ const char* JVMCIEnv::as_utf8_string(JVMCIObject str) {
|
|||
return java_lang_String::as_utf8_string(HotSpotJVMCI::resolve(str));
|
||||
} else {
|
||||
JNIAccessMark jni(this);
|
||||
int length = jni()->GetStringLength(str.as_jstring());
|
||||
int utf8_length = jni()->GetStringUTFLength(str.as_jstring());
|
||||
jstring jstr = str.as_jstring();
|
||||
int length = jni()->GetStringLength(jstr);
|
||||
int utf8_length = jni()->GetStringUTFLength(jstr);
|
||||
char* result = NEW_RESOURCE_ARRAY(char, utf8_length + 1);
|
||||
jni()->GetStringUTFRegion(str.as_jstring(), 0, length, result);
|
||||
jni()->GetStringUTFRegion(jstr, 0, length, result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -904,7 +1018,7 @@ void JVMCIEnv::call_HotSpotJVMCIRuntime_shutdown (JVMCIObject runtime) {
|
|||
if (has_pending_exception()) {
|
||||
// This should never happen as HotSpotJVMCIRuntime.shutdown() should
|
||||
// handle all exceptions.
|
||||
describe_pending_exception(true);
|
||||
describe_pending_exception(tty);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -960,30 +1074,6 @@ JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_getCompiler (JVMCIObject runtime,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_callToString(JVMCIObject object, JVMCIEnv* JVMCIENV) {
|
||||
JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.
|
||||
if (is_hotspot()) {
|
||||
JavaCallArguments jargs;
|
||||
jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(object)));
|
||||
JavaValue result(T_OBJECT);
|
||||
JavaCalls::call_static(&result,
|
||||
HotSpotJVMCI::HotSpotJVMCIRuntime::klass(),
|
||||
vmSymbols::callToString_name(),
|
||||
vmSymbols::callToString_signature(), &jargs, CHECK_(JVMCIObject()));
|
||||
return wrap(result.get_oop());
|
||||
} else {
|
||||
JNIAccessMark jni(this, THREAD);
|
||||
jobject result = (jstring) jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotJVMCIRuntime::clazz(),
|
||||
JNIJVMCI::HotSpotJVMCIRuntime::callToString_method(),
|
||||
object.as_jobject());
|
||||
if (jni()->ExceptionCheck()) {
|
||||
return JVMCIObject();
|
||||
}
|
||||
return wrap(result);
|
||||
}
|
||||
}
|
||||
|
||||
void JVMCIEnv::call_HotSpotJVMCIRuntime_postTranslation(JVMCIObject object, JVMCIEnv* JVMCIENV) {
|
||||
JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.
|
||||
if (is_hotspot()) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue