Skip to content

Commit da7bcfc

Browse files
committedNov 29, 2023
8319935: Ensure only one JvmtiThreadState is created for one JavaThread associated with attached native thread
Reviewed-by: manc, dholmes, sspitsyn
1 parent a2c5f1f commit da7bcfc

File tree

2 files changed

+24
-6
lines changed

2 files changed

+24
-6
lines changed
 

‎src/hotspot/share/prims/jvmtiExport.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -3139,6 +3139,13 @@ bool JvmtiSampledObjectAllocEventCollector::object_alloc_is_safe_to_sample() {
31393139
return false;
31403140
}
31413141

3142+
// If the current thread is attaching from native and its Java thread object
3143+
// is being allocated, things are not ready for allocation sampling.
3144+
JavaThread* jt = JavaThread::cast(thread);
3145+
if (jt->is_attaching_via_jni() && jt->threadObj() == nullptr) {
3146+
return false;
3147+
}
3148+
31423149
if (MultiArray_lock->owner() == thread) {
31433150
return false;
31443151
}

‎src/hotspot/share/prims/jvmtiThreadState.inline.hpp

+17-6
Original file line numberDiff line numberDiff line change
@@ -78,17 +78,27 @@ inline JvmtiThreadState* JvmtiThreadState::state_for_while_locked(JavaThread *th
7878

7979
NoSafepointVerifier nsv; // oop is safe to use.
8080

81-
if (thread_oop == nullptr) { // Then thread should not be null (see assert above).
82-
thread_oop = thread->jvmti_vthread() != nullptr ? thread->jvmti_vthread() : thread->threadObj();
83-
}
84-
8581
// In a case of unmounted virtual thread the thread can be null.
8682
JvmtiThreadState *state = thread == nullptr ? nullptr : thread->jvmti_thread_state();
8783

88-
if (state == nullptr && thread != nullptr && thread->is_exiting()) {
89-
// Don't add a JvmtiThreadState to a thread that is exiting.
84+
if (state == nullptr && thread != nullptr &&
85+
(thread->is_exiting() || thread->is_attaching_via_jni())) {
86+
// Don't add a JvmtiThreadState to a thread that is exiting or is attaching.
87+
// When a thread is attaching, it may not have a Java level thread object
88+
// created yet.
9089
return nullptr;
9190
}
91+
92+
// Make sure we don't see an incomplete state. An incomplete state can cause
93+
// a duplicate JvmtiThreadState being created below and bound to the 'thread'
94+
// incorrectly, which leads to stale JavaThread* from the JvmtiThreadState
95+
// after the thread exits.
96+
assert(state == nullptr || state->get_thread_oop() != nullptr,
97+
"incomplete state");
98+
99+
if (thread_oop == nullptr) { // Then thread should not be null (see assert above).
100+
thread_oop = thread->jvmti_vthread() != nullptr ? thread->jvmti_vthread() : thread->threadObj();
101+
}
92102
if (state == nullptr || state->get_thread_oop() != thread_oop) {
93103
// Check if java_lang_Thread already has a link to the JvmtiThreadState.
94104
if (thread_oop != nullptr) { // thread_oop can be null during early VMStart.
@@ -98,6 +108,7 @@ inline JvmtiThreadState* JvmtiThreadState::state_for_while_locked(JavaThread *th
98108
state = new JvmtiThreadState(thread, thread_oop);
99109
}
100110
}
111+
assert(state != nullptr, "sanity check");
101112
return state;
102113
}
103114

0 commit comments

Comments
 (0)
Please sign in to comment.