mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-18 11:53:17 +00:00
8247248: JVM TI Monitor queries might create JNI locals in another thread when using handshakes
Reviewed-by: dholmes, dcubed, sspitsyn, ysuenaga
This commit is contained in:
parent
c563c3d15b
commit
6a2e3ca206
@ -1200,6 +1200,7 @@ JvmtiEnv::GetThreadInfo(jthread thread, jvmtiThreadInfo* info_ptr) {
|
||||
jvmtiError
|
||||
JvmtiEnv::GetOwnedMonitorInfo(JavaThread* java_thread, jint* owned_monitor_count_ptr, jobject** owned_monitors_ptr) {
|
||||
jvmtiError err = JVMTI_ERROR_NONE;
|
||||
JavaThread* calling_thread = JavaThread::current();
|
||||
|
||||
// growable array of jvmti monitors info on the C-heap
|
||||
GrowableArray<jvmtiMonitorStackDepthInfo*> *owned_monitors_list =
|
||||
@ -1207,11 +1208,11 @@ JvmtiEnv::GetOwnedMonitorInfo(JavaThread* java_thread, jint* owned_monitor_count
|
||||
|
||||
// It is only safe to perform the direct operation on the current
|
||||
// thread. All other usage needs to use a direct handshake for safety.
|
||||
if (java_thread == JavaThread::current()) {
|
||||
err = get_owned_monitors(java_thread, owned_monitors_list);
|
||||
if (java_thread == calling_thread) {
|
||||
err = get_owned_monitors(calling_thread, java_thread, owned_monitors_list);
|
||||
} else {
|
||||
// get owned monitors info with handshake
|
||||
GetOwnedMonitorInfoClosure op(this, owned_monitors_list);
|
||||
GetOwnedMonitorInfoClosure op(calling_thread, this, owned_monitors_list);
|
||||
Handshake::execute_direct(&op, java_thread);
|
||||
err = op.result();
|
||||
}
|
||||
@ -1244,6 +1245,7 @@ JvmtiEnv::GetOwnedMonitorInfo(JavaThread* java_thread, jint* owned_monitor_count
|
||||
jvmtiError
|
||||
JvmtiEnv::GetOwnedMonitorStackDepthInfo(JavaThread* java_thread, jint* monitor_info_count_ptr, jvmtiMonitorStackDepthInfo** monitor_info_ptr) {
|
||||
jvmtiError err = JVMTI_ERROR_NONE;
|
||||
JavaThread* calling_thread = JavaThread::current();
|
||||
|
||||
// growable array of jvmti monitors info on the C-heap
|
||||
GrowableArray<jvmtiMonitorStackDepthInfo*> *owned_monitors_list =
|
||||
@ -1251,11 +1253,11 @@ JvmtiEnv::GetOwnedMonitorStackDepthInfo(JavaThread* java_thread, jint* monitor_i
|
||||
|
||||
// It is only safe to perform the direct operation on the current
|
||||
// thread. All other usage needs to use a direct handshake for safety.
|
||||
if (java_thread == JavaThread::current()) {
|
||||
err = get_owned_monitors(java_thread, owned_monitors_list);
|
||||
if (java_thread == calling_thread) {
|
||||
err = get_owned_monitors(calling_thread, java_thread, owned_monitors_list);
|
||||
} else {
|
||||
// get owned monitors info with handshake
|
||||
GetOwnedMonitorInfoClosure op(this, owned_monitors_list);
|
||||
GetOwnedMonitorInfoClosure op(calling_thread, this, owned_monitors_list);
|
||||
Handshake::execute_direct(&op, java_thread);
|
||||
err = op.result();
|
||||
}
|
||||
@ -1291,14 +1293,15 @@ JvmtiEnv::GetOwnedMonitorStackDepthInfo(JavaThread* java_thread, jint* monitor_i
|
||||
jvmtiError
|
||||
JvmtiEnv::GetCurrentContendedMonitor(JavaThread* java_thread, jobject* monitor_ptr) {
|
||||
jvmtiError err = JVMTI_ERROR_NONE;
|
||||
JavaThread* calling_thread = JavaThread::current();
|
||||
|
||||
// It is only safe to perform the direct operation on the current
|
||||
// thread. All other usage needs to use a direct handshake for safety.
|
||||
if (java_thread == JavaThread::current()) {
|
||||
err = get_current_contended_monitor(java_thread, monitor_ptr);
|
||||
if (java_thread == calling_thread) {
|
||||
err = get_current_contended_monitor(calling_thread, java_thread, monitor_ptr);
|
||||
} else {
|
||||
// get contended monitor information with handshake
|
||||
GetCurrentContendedMonitorClosure op(this, monitor_ptr);
|
||||
GetCurrentContendedMonitorClosure op(calling_thread, this, monitor_ptr);
|
||||
Handshake::execute_direct(&op, java_thread);
|
||||
err = op.result();
|
||||
}
|
||||
|
||||
@ -647,7 +647,7 @@ JvmtiEnvBase::count_locked_objects(JavaThread *java_thread, Handle hobj) {
|
||||
|
||||
|
||||
jvmtiError
|
||||
JvmtiEnvBase::get_current_contended_monitor(JavaThread *java_thread, jobject *monitor_ptr) {
|
||||
JvmtiEnvBase::get_current_contended_monitor(JavaThread *calling_thread, JavaThread *java_thread, jobject *monitor_ptr) {
|
||||
JavaThread *current_jt = JavaThread::current();
|
||||
assert(current_jt == java_thread ||
|
||||
current_jt == java_thread->active_handshaker(),
|
||||
@ -677,14 +677,14 @@ JvmtiEnvBase::get_current_contended_monitor(JavaThread *java_thread, jobject *mo
|
||||
} else {
|
||||
HandleMark hm;
|
||||
Handle hobj(current_jt, obj);
|
||||
*monitor_ptr = jni_reference(current_jt, hobj);
|
||||
*monitor_ptr = jni_reference(calling_thread, hobj);
|
||||
}
|
||||
return JVMTI_ERROR_NONE;
|
||||
}
|
||||
|
||||
|
||||
jvmtiError
|
||||
JvmtiEnvBase::get_owned_monitors(JavaThread* java_thread,
|
||||
JvmtiEnvBase::get_owned_monitors(JavaThread *calling_thread, JavaThread* java_thread,
|
||||
GrowableArray<jvmtiMonitorStackDepthInfo*> *owned_monitors_list) {
|
||||
jvmtiError err = JVMTI_ERROR_NONE;
|
||||
JavaThread *current_jt = JavaThread::current();
|
||||
@ -702,7 +702,7 @@ JvmtiEnvBase::get_owned_monitors(JavaThread* java_thread,
|
||||
jvf = jvf->java_sender()) {
|
||||
if (MaxJavaStackTraceDepth == 0 || depth++ < MaxJavaStackTraceDepth) { // check for stack too deep
|
||||
// add locked objects for this frame into list
|
||||
err = get_locked_objects_in_frame(current_jt, java_thread, jvf, owned_monitors_list, depth-1);
|
||||
err = get_locked_objects_in_frame(calling_thread, java_thread, jvf, owned_monitors_list, depth-1);
|
||||
if (err != JVMTI_ERROR_NONE) {
|
||||
return err;
|
||||
}
|
||||
@ -711,7 +711,7 @@ JvmtiEnvBase::get_owned_monitors(JavaThread* java_thread,
|
||||
}
|
||||
|
||||
// Get off stack monitors. (e.g. acquired via jni MonitorEnter).
|
||||
JvmtiMonitorClosure jmc(java_thread, current_jt, owned_monitors_list, this);
|
||||
JvmtiMonitorClosure jmc(java_thread, calling_thread, owned_monitors_list, this);
|
||||
ObjectSynchronizer::monitors_iterate(&jmc);
|
||||
err = jmc.error();
|
||||
|
||||
@ -1548,12 +1548,12 @@ VM_SetFramePop::doit() {
|
||||
|
||||
void
|
||||
GetOwnedMonitorInfoClosure::do_thread(Thread *target) {
|
||||
_result = ((JvmtiEnvBase *)_env)->get_owned_monitors((JavaThread *)target, _owned_monitors_list);
|
||||
_result = ((JvmtiEnvBase *)_env)->get_owned_monitors(_calling_thread, (JavaThread *)target, _owned_monitors_list);
|
||||
}
|
||||
|
||||
void
|
||||
GetCurrentContendedMonitorClosure::do_thread(Thread *target) {
|
||||
_result = ((JvmtiEnvBase *)_env)->get_current_contended_monitor((JavaThread *)target, _owned_monitor_ptr);
|
||||
_result = ((JvmtiEnvBase *)_env)->get_current_contended_monitor(_calling_thread, (JavaThread *)target, _owned_monitor_ptr);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@ -302,9 +302,9 @@ class JvmtiEnvBase : public CHeapObj<mtInternal> {
|
||||
jvmtiError get_stack_trace(JavaThread *java_thread,
|
||||
jint stack_depth, jint max_count,
|
||||
jvmtiFrameInfo* frame_buffer, jint* count_ptr);
|
||||
jvmtiError get_current_contended_monitor(JavaThread *java_thread,
|
||||
jvmtiError get_current_contended_monitor(JavaThread *calling_thread, JavaThread *java_thread,
|
||||
jobject *monitor_ptr);
|
||||
jvmtiError get_owned_monitors(JavaThread* java_thread,
|
||||
jvmtiError get_owned_monitors(JavaThread *calling_thread, JavaThread* java_thread,
|
||||
GrowableArray<jvmtiMonitorStackDepthInfo*> *owned_monitors_list);
|
||||
jvmtiError check_top_frame(JavaThread* current_thread, JavaThread* java_thread,
|
||||
jvalue value, TosState tos, Handle* ret_ob_h);
|
||||
@ -376,19 +376,21 @@ public:
|
||||
// HandshakeClosure to get monitor information with stack depth.
|
||||
class GetOwnedMonitorInfoClosure : public HandshakeClosure {
|
||||
private:
|
||||
JavaThread* _calling_thread;
|
||||
JvmtiEnv *_env;
|
||||
jvmtiError _result;
|
||||
GrowableArray<jvmtiMonitorStackDepthInfo*> *_owned_monitors_list;
|
||||
|
||||
public:
|
||||
GetOwnedMonitorInfoClosure(JvmtiEnv* env,
|
||||
GetOwnedMonitorInfoClosure(JavaThread* calling_thread, JvmtiEnv* env,
|
||||
GrowableArray<jvmtiMonitorStackDepthInfo*>* owned_monitor_list)
|
||||
: HandshakeClosure("GetOwnedMonitorInfo"),
|
||||
_calling_thread(calling_thread),
|
||||
_env(env),
|
||||
_result(JVMTI_ERROR_NONE),
|
||||
_owned_monitors_list(owned_monitor_list) {}
|
||||
void do_thread(Thread *target);
|
||||
jvmtiError result() { return _result; }
|
||||
void do_thread(Thread *target);
|
||||
};
|
||||
|
||||
|
||||
@ -419,13 +421,15 @@ public:
|
||||
// HandshakeClosure to get current contended monitor.
|
||||
class GetCurrentContendedMonitorClosure : public HandshakeClosure {
|
||||
private:
|
||||
JavaThread *_calling_thread;
|
||||
JvmtiEnv *_env;
|
||||
jobject *_owned_monitor_ptr;
|
||||
jvmtiError _result;
|
||||
|
||||
public:
|
||||
GetCurrentContendedMonitorClosure(JvmtiEnv *env, jobject *mon_ptr)
|
||||
GetCurrentContendedMonitorClosure(JavaThread* calling_thread, JvmtiEnv *env, jobject *mon_ptr)
|
||||
: HandshakeClosure("GetCurrentContendedMonitor"),
|
||||
_calling_thread(calling_thread),
|
||||
_env(env),
|
||||
_owned_monitor_ptr(mon_ptr),
|
||||
_result(JVMTI_ERROR_THREAD_NOT_ALIVE) {}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user