提交 dac7ba64 编写于 作者: C coleenp

7009923: JSR 292: VM crash in JavaThread::last_frame

Summary: Handle stack overflow before the first frame is called, by printing out the called method and not walking the stack.
Reviewed-by: dholmes, phh, dsamersoff
上级 4a0e64cd
...@@ -1357,7 +1357,7 @@ class BacktraceBuilder: public StackObj { ...@@ -1357,7 +1357,7 @@ class BacktraceBuilder: public StackObj {
}; };
void java_lang_Throwable::fill_in_stack_trace(Handle throwable, TRAPS) { void java_lang_Throwable::fill_in_stack_trace(Handle throwable, methodHandle method, TRAPS) {
if (!StackTraceInThrowable) return; if (!StackTraceInThrowable) return;
ResourceMark rm(THREAD); ResourceMark rm(THREAD);
...@@ -1374,6 +1374,16 @@ void java_lang_Throwable::fill_in_stack_trace(Handle throwable, TRAPS) { ...@@ -1374,6 +1374,16 @@ void java_lang_Throwable::fill_in_stack_trace(Handle throwable, TRAPS) {
JavaThread* thread = (JavaThread*)THREAD; JavaThread* thread = (JavaThread*)THREAD;
BacktraceBuilder bt(CHECK); BacktraceBuilder bt(CHECK);
// If there is no Java frame just return the method that was being called
// with bci 0
if (!thread->has_last_Java_frame()) {
if (max_depth >= 1 && method() != NULL) {
bt.push(method(), 0, CHECK);
set_backtrace(throwable(), bt.backtrace());
}
return;
}
// Instead of using vframe directly, this version of fill_in_stack_trace // Instead of using vframe directly, this version of fill_in_stack_trace
// basically handles everything by hand. This significantly improved the // basically handles everything by hand. This significantly improved the
// speed of this method call up to 28.5% on Solaris sparc. 27.1% on Windows. // speed of this method call up to 28.5% on Solaris sparc. 27.1% on Windows.
...@@ -1477,7 +1487,7 @@ void java_lang_Throwable::fill_in_stack_trace(Handle throwable, TRAPS) { ...@@ -1477,7 +1487,7 @@ void java_lang_Throwable::fill_in_stack_trace(Handle throwable, TRAPS) {
set_backtrace(throwable(), bt.backtrace()); set_backtrace(throwable(), bt.backtrace());
} }
void java_lang_Throwable::fill_in_stack_trace(Handle throwable) { void java_lang_Throwable::fill_in_stack_trace(Handle throwable, methodHandle method) {
// No-op if stack trace is disabled // No-op if stack trace is disabled
if (!StackTraceInThrowable) { if (!StackTraceInThrowable) {
return; return;
...@@ -1491,7 +1501,7 @@ void java_lang_Throwable::fill_in_stack_trace(Handle throwable) { ...@@ -1491,7 +1501,7 @@ void java_lang_Throwable::fill_in_stack_trace(Handle throwable) {
PRESERVE_EXCEPTION_MARK; PRESERVE_EXCEPTION_MARK;
JavaThread* thread = JavaThread::active(); JavaThread* thread = JavaThread::active();
fill_in_stack_trace(throwable, thread); fill_in_stack_trace(throwable, method, thread);
// ignore exceptions thrown during stack trace filling // ignore exceptions thrown during stack trace filling
CLEAR_PENDING_EXCEPTION; CLEAR_PENDING_EXCEPTION;
} }
......
...@@ -440,8 +440,8 @@ class java_lang_Throwable: AllStatic { ...@@ -440,8 +440,8 @@ class java_lang_Throwable: AllStatic {
static void fill_in_stack_trace_of_preallocated_backtrace(Handle throwable); static void fill_in_stack_trace_of_preallocated_backtrace(Handle throwable);
// Fill in current stack trace, can cause GC // Fill in current stack trace, can cause GC
static void fill_in_stack_trace(Handle throwable, TRAPS); static void fill_in_stack_trace(Handle throwable, methodHandle method, TRAPS);
static void fill_in_stack_trace(Handle throwable); static void fill_in_stack_trace(Handle throwable, methodHandle method = methodHandle());
// Programmatic access to stack trace // Programmatic access to stack trace
static oop get_stack_trace_element(oop throwable, int index, TRAPS); static oop get_stack_trace_element(oop throwable, int index, TRAPS);
static int get_stack_trace_depth(oop throwable, TRAPS); static int get_stack_trace_depth(oop throwable, TRAPS);
......
...@@ -389,7 +389,7 @@ void JavaCalls::call_helper(JavaValue* result, methodHandle* m, JavaCallArgument ...@@ -389,7 +389,7 @@ void JavaCalls::call_helper(JavaValue* result, methodHandle* m, JavaCallArgument
// to Java // to Java
if (!os::stack_shadow_pages_available(THREAD, method)) { if (!os::stack_shadow_pages_available(THREAD, method)) {
// Throw stack overflow exception with preinitialized exception. // Throw stack overflow exception with preinitialized exception.
Exceptions::throw_stack_overflow_exception(THREAD, __FILE__, __LINE__); Exceptions::throw_stack_overflow_exception(THREAD, __FILE__, __LINE__, method);
return; return;
} else { } else {
// Touch pages checked if the OS needs them to be touched to be mapped. // Touch pages checked if the OS needs them to be touched to be mapped.
......
...@@ -207,7 +207,7 @@ void Exceptions::_throw_args(Thread* thread, const char* file, int line, Symbol* ...@@ -207,7 +207,7 @@ void Exceptions::_throw_args(Thread* thread, const char* file, int line, Symbol*
} }
void Exceptions::throw_stack_overflow_exception(Thread* THREAD, const char* file, int line) { void Exceptions::throw_stack_overflow_exception(Thread* THREAD, const char* file, int line, methodHandle method) {
Handle exception; Handle exception;
if (!THREAD->has_pending_exception()) { if (!THREAD->has_pending_exception()) {
klassOop k = SystemDictionary::StackOverflowError_klass(); klassOop k = SystemDictionary::StackOverflowError_klass();
...@@ -215,13 +215,13 @@ void Exceptions::throw_stack_overflow_exception(Thread* THREAD, const char* file ...@@ -215,13 +215,13 @@ void Exceptions::throw_stack_overflow_exception(Thread* THREAD, const char* file
exception = Handle(THREAD, e); // fill_in_stack trace does gc exception = Handle(THREAD, e); // fill_in_stack trace does gc
assert(instanceKlass::cast(k)->is_initialized(), "need to increase min_stack_allowed calculation"); assert(instanceKlass::cast(k)->is_initialized(), "need to increase min_stack_allowed calculation");
if (StackTraceInThrowable) { if (StackTraceInThrowable) {
java_lang_Throwable::fill_in_stack_trace(exception); java_lang_Throwable::fill_in_stack_trace(exception, method());
} }
} else { } else {
// if prior exception, throw that one instead // if prior exception, throw that one instead
exception = Handle(THREAD, THREAD->pending_exception()); exception = Handle(THREAD, THREAD->pending_exception());
} }
_throw_oop(THREAD, file, line, exception()); _throw(THREAD, file, line, exception);
} }
void Exceptions::fthrow(Thread* thread, const char* file, int line, Symbol* h_name, const char* format, ...) { void Exceptions::fthrow(Thread* thread, const char* file, int line, Symbol* h_name, const char* format, ...) {
......
...@@ -144,7 +144,7 @@ class Exceptions { ...@@ -144,7 +144,7 @@ class Exceptions {
const char* message, const char* message,
ExceptionMsgToUtf8Mode to_utf8_safe = safe_to_utf8); ExceptionMsgToUtf8Mode to_utf8_safe = safe_to_utf8);
static void throw_stack_overflow_exception(Thread* thread, const char* file, int line); static void throw_stack_overflow_exception(Thread* thread, const char* file, int line, methodHandle method);
// for AbortVMOnException flag // for AbortVMOnException flag
NOT_PRODUCT(static void debug_check_abort(Handle exception, const char* message = NULL);) NOT_PRODUCT(static void debug_check_abort(Handle exception, const char* message = NULL);)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册