mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-16 10:53:31 +00:00
8283849: AsyncGetCallTrace may crash JVM on guarantee
Reviewed-by: dholmes, stuefe
This commit is contained in:
parent
ab144190c9
commit
93c88690a1
@ -684,14 +684,23 @@ bool CodeCache::contains(nmethod *nm) {
|
||||
return contains((void *)nm);
|
||||
}
|
||||
|
||||
static bool is_in_asgct() {
|
||||
Thread* current_thread = Thread::current_or_null_safe();
|
||||
return current_thread != NULL && current_thread->is_Java_thread() && JavaThread::cast(current_thread)->in_asgct();
|
||||
}
|
||||
|
||||
// This method is safe to call without holding the CodeCache_lock, as long as a dead CodeBlob is not
|
||||
// looked up (i.e., one that has been marked for deletion). It only depends on the _segmap to contain
|
||||
// valid indices, which it will always do, as long as the CodeBlob is not in the process of being recycled.
|
||||
CodeBlob* CodeCache::find_blob(void* start) {
|
||||
CodeBlob* result = find_blob_unsafe(start);
|
||||
// We could potentially look up non_entrant methods
|
||||
guarantee(result == NULL || !result->is_zombie() || result->is_locked_by_vm() || VMError::is_error_reported(), "unsafe access to zombie method");
|
||||
return result;
|
||||
bool is_zombie = result != NULL && result->is_zombie();
|
||||
bool is_result_safe = !is_zombie || result->is_locked_by_vm() || VMError::is_error_reported();
|
||||
guarantee(is_result_safe || is_in_asgct(), "unsafe access to zombie method");
|
||||
// When in ASGCT the previous gurantee will pass for a zombie method but we still don't want that code blob returned in order
|
||||
// to minimize the chance of accessing dead memory
|
||||
return is_result_safe ? result : NULL;
|
||||
}
|
||||
|
||||
// Lookup that does not fail if you lookup a zombie method (if you call this, be sure to know
|
||||
|
||||
@ -596,6 +596,9 @@ void AsyncGetCallTrace(ASGCT_CallTrace *trace, jint depth, void* ucontext) {
|
||||
return;
|
||||
}
|
||||
|
||||
// !important! make sure all to call thread->set_in_asgct(false) before every return
|
||||
thread->set_in_asgct(true);
|
||||
|
||||
switch (thread->thread_state()) {
|
||||
case _thread_new:
|
||||
case _thread_uninitialized:
|
||||
@ -653,6 +656,7 @@ void AsyncGetCallTrace(ASGCT_CallTrace *trace, jint depth, void* ucontext) {
|
||||
trace->num_frames = ticks_unknown_state; // -7
|
||||
break;
|
||||
}
|
||||
thread->set_in_asgct(false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1011,6 +1011,7 @@ void JavaThread::check_for_valid_safepoint_state() {
|
||||
JavaThread::JavaThread() :
|
||||
// Initialize fields
|
||||
|
||||
_in_asgct(false),
|
||||
_on_thread_list(false),
|
||||
DEBUG_ONLY(_java_call_counter(0) COMMA)
|
||||
_entry_point(nullptr),
|
||||
|
||||
@ -703,6 +703,7 @@ class JavaThread: public Thread {
|
||||
friend class HandshakeState;
|
||||
friend class Continuation;
|
||||
private:
|
||||
bool _in_asgct; // Is set when this JavaThread is handling ASGCT call
|
||||
bool _on_thread_list; // Is set when this JavaThread is added to the Threads list
|
||||
OopHandle _threadObj; // The Java level thread object
|
||||
OopHandle _vthread; // the value returned by Thread.currentThread(): the virtual thread, if mounted, otherwise _threadObj
|
||||
@ -1759,6 +1760,10 @@ public:
|
||||
// Helper function to do vm_exit_on_initialization for osthread
|
||||
// resource allocation failure.
|
||||
static void vm_exit_on_osthread_failure(JavaThread* thread);
|
||||
|
||||
// AsyncGetCallTrace support
|
||||
inline bool in_asgct(void) {return _in_asgct;}
|
||||
inline void set_in_asgct(bool value) {_in_asgct = value;}
|
||||
};
|
||||
|
||||
inline JavaThread* JavaThread::current_or_null() {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user