6800721: 3/4 JavaThread::jvmti_thread_state() and JvmtiThreadState::state_for() robustness
Check for NULL return values from jvmti_thread_state() and state_for() and return a JVM TI error code as appropriate. Reviewed-by: coleenp, swamyv
This commit is contained in:
parent
74a99e1e82
commit
56fe18e375
@ -99,6 +99,9 @@ JvmtiEnv::SetThreadLocalStorage(JavaThread* java_thread, const void* data) {
|
||||
}
|
||||
// otherwise, create the state
|
||||
state = JvmtiThreadState::state_for(java_thread);
|
||||
if (state == NULL) {
|
||||
return JVMTI_ERROR_THREAD_NOT_ALIVE;
|
||||
}
|
||||
}
|
||||
state->env_thread_state(this)->set_agent_thread_local_storage_data((void*)data);
|
||||
return JVMTI_ERROR_NONE;
|
||||
@ -1308,6 +1311,9 @@ JvmtiEnv::GetFrameCount(JavaThread* java_thread, jint* count_ptr) {
|
||||
|
||||
// retrieve or create JvmtiThreadState.
|
||||
JvmtiThreadState* state = JvmtiThreadState::state_for(java_thread);
|
||||
if (state == NULL) {
|
||||
return JVMTI_ERROR_THREAD_NOT_ALIVE;
|
||||
}
|
||||
uint32_t debug_bits = 0;
|
||||
if (is_thread_fully_suspended(java_thread, true, &debug_bits)) {
|
||||
err = get_frame_count(state, count_ptr);
|
||||
@ -1329,6 +1335,12 @@ JvmtiEnv::PopFrame(JavaThread* java_thread) {
|
||||
HandleMark hm(current_thread);
|
||||
uint32_t debug_bits = 0;
|
||||
|
||||
// retrieve or create the state
|
||||
JvmtiThreadState* state = JvmtiThreadState::state_for(java_thread);
|
||||
if (state == NULL) {
|
||||
return JVMTI_ERROR_THREAD_NOT_ALIVE;
|
||||
}
|
||||
|
||||
// Check if java_thread is fully suspended
|
||||
if (!is_thread_fully_suspended(java_thread, true /* wait for suspend completion */, &debug_bits)) {
|
||||
return JVMTI_ERROR_THREAD_NOT_SUSPENDED;
|
||||
@ -1399,9 +1411,6 @@ JvmtiEnv::PopFrame(JavaThread* java_thread) {
|
||||
// It's fine to update the thread state here because no JVMTI events
|
||||
// shall be posted for this PopFrame.
|
||||
|
||||
// retreive or create the state
|
||||
JvmtiThreadState* state = JvmtiThreadState::state_for(java_thread);
|
||||
|
||||
state->update_for_pop_top_frame();
|
||||
java_thread->set_popframe_condition(JavaThread::popframe_pending_bit);
|
||||
// Set pending step flag for this popframe and it is cleared when next
|
||||
@ -1445,6 +1454,11 @@ JvmtiEnv::NotifyFramePop(JavaThread* java_thread, jint depth) {
|
||||
ResourceMark rm;
|
||||
uint32_t debug_bits = 0;
|
||||
|
||||
JvmtiThreadState *state = JvmtiThreadState::state_for(java_thread);
|
||||
if (state == NULL) {
|
||||
return JVMTI_ERROR_THREAD_NOT_ALIVE;
|
||||
}
|
||||
|
||||
if (!JvmtiEnv::is_thread_fully_suspended(java_thread, true, &debug_bits)) {
|
||||
return JVMTI_ERROR_THREAD_NOT_SUSPENDED;
|
||||
}
|
||||
@ -1464,7 +1478,6 @@ JvmtiEnv::NotifyFramePop(JavaThread* java_thread, jint depth) {
|
||||
|
||||
assert(vf->frame_pointer() != NULL, "frame pointer mustn't be NULL");
|
||||
|
||||
JvmtiThreadState *state = JvmtiThreadState::state_for(java_thread);
|
||||
int frame_number = state->count_frames() - depth;
|
||||
state->env_thread_state(this)->set_frame_pop(frame_number);
|
||||
|
||||
|
@ -1322,6 +1322,12 @@ JvmtiEnvBase::force_early_return(JavaThread* java_thread, jvalue value, TosState
|
||||
HandleMark hm(current_thread);
|
||||
uint32_t debug_bits = 0;
|
||||
|
||||
// retrieve or create the state
|
||||
JvmtiThreadState* state = JvmtiThreadState::state_for(java_thread);
|
||||
if (state == NULL) {
|
||||
return JVMTI_ERROR_THREAD_NOT_ALIVE;
|
||||
}
|
||||
|
||||
// Check if java_thread is fully suspended
|
||||
if (!is_thread_fully_suspended(java_thread,
|
||||
true /* wait for suspend completion */,
|
||||
@ -1329,9 +1335,6 @@ JvmtiEnvBase::force_early_return(JavaThread* java_thread, jvalue value, TosState
|
||||
return JVMTI_ERROR_THREAD_NOT_SUSPENDED;
|
||||
}
|
||||
|
||||
// retreive or create the state
|
||||
JvmtiThreadState* state = JvmtiThreadState::state_for(java_thread);
|
||||
|
||||
// Check to see if a ForceEarlyReturn was already in progress
|
||||
if (state->is_earlyret_pending()) {
|
||||
// Probably possible for JVMTI clients to trigger this, but the
|
||||
|
@ -478,6 +478,11 @@ JvmtiEventControllerPrivate::recompute_env_thread_enabled(JvmtiEnvThreadState* e
|
||||
// set external state accordingly. Only thread-filtered events are included.
|
||||
jlong
|
||||
JvmtiEventControllerPrivate::recompute_thread_enabled(JvmtiThreadState *state) {
|
||||
if (state == NULL) {
|
||||
// associated JavaThread is exiting
|
||||
return (jlong)0;
|
||||
}
|
||||
|
||||
jlong was_any_env_enabled = state->thread_event_enable()->_event_enabled.get_bits();
|
||||
jlong any_env_enabled = 0;
|
||||
|
||||
@ -553,6 +558,7 @@ JvmtiEventControllerPrivate::recompute_enabled() {
|
||||
{
|
||||
MutexLocker mu(Threads_lock); //hold the Threads_lock for the iteration
|
||||
for (JavaThread *tp = Threads::first(); tp != NULL; tp = tp->next()) {
|
||||
// state_for_while_locked() makes tp->is_exiting() check
|
||||
JvmtiThreadState::state_for_while_locked(tp); // create the thread state if missing
|
||||
}
|
||||
}// release Threads_lock
|
||||
|
@ -1872,6 +1872,9 @@ void JvmtiExport::post_dynamic_code_generated_while_holding_locks(const char* na
|
||||
{
|
||||
// register the stub with the current dynamic code event collector
|
||||
JvmtiThreadState* state = JvmtiThreadState::state_for(JavaThread::current());
|
||||
// state can only be NULL if the current thread is exiting which
|
||||
// should not happen since we're trying to post an event
|
||||
guarantee(state != NULL, "attempt to register stub via an exiting thread");
|
||||
JvmtiDynamicCodeEventCollector* collector = state->get_dynamic_code_event_collector();
|
||||
guarantee(collector != NULL, "attempt to register stub without event collector");
|
||||
collector->register_stub(name, code_begin, code_end);
|
||||
@ -2253,6 +2256,9 @@ void JvmtiExport::cms_ref_processing_epilogue() {
|
||||
void JvmtiEventCollector::setup_jvmti_thread_state() {
|
||||
// set this event collector to be the current one.
|
||||
JvmtiThreadState* state = JvmtiThreadState::state_for(JavaThread::current());
|
||||
// state can only be NULL if the current thread is exiting which
|
||||
// should not happen since we're trying to configure for event collection
|
||||
guarantee(state != NULL, "exiting thread called setup_jvmti_thread_state");
|
||||
if (is_vm_object_alloc_event()) {
|
||||
_prev = state->get_vm_object_alloc_event_collector();
|
||||
state->set_vm_object_alloc_event_collector((JvmtiVMObjectAllocEventCollector *)this);
|
||||
|
@ -831,6 +831,9 @@ jvmtiError VM_RedefineClasses::load_new_class_versions(TRAPS) {
|
||||
ResourceMark rm(THREAD);
|
||||
|
||||
JvmtiThreadState *state = JvmtiThreadState::state_for(JavaThread::current());
|
||||
// state can only be NULL if the current thread is exiting which
|
||||
// should not happen since we're trying to do a RedefineClasses
|
||||
guarantee(state != NULL, "exiting thread calling load_new_class_versions");
|
||||
for (int i = 0; i < _class_count; i++) {
|
||||
oop mirror = JNIHandles::resolve_non_null(_class_defs[i].klass);
|
||||
// classes for primitives cannot be redefined
|
||||
|
@ -314,6 +314,7 @@ class JvmtiThreadState : public CHeapObj {
|
||||
void update_for_pop_top_frame();
|
||||
|
||||
// already holding JvmtiThreadState_lock - retrieve or create JvmtiThreadState
|
||||
// Can return NULL if JavaThread is exiting.
|
||||
inline static JvmtiThreadState *state_for_while_locked(JavaThread *thread) {
|
||||
assert(JvmtiThreadState_lock->is_locked(), "sanity check");
|
||||
|
||||
@ -330,6 +331,7 @@ class JvmtiThreadState : public CHeapObj {
|
||||
}
|
||||
|
||||
// retrieve or create JvmtiThreadState
|
||||
// Can return NULL if JavaThread is exiting.
|
||||
inline static JvmtiThreadState *state_for(JavaThread *thread) {
|
||||
JvmtiThreadState *state = thread->jvmti_thread_state();
|
||||
if (state == NULL) {
|
||||
|
@ -1345,6 +1345,13 @@ public:
|
||||
public:
|
||||
// Thread local information maintained by JVMTI.
|
||||
void set_jvmti_thread_state(JvmtiThreadState *value) { _jvmti_thread_state = value; }
|
||||
// A JvmtiThreadState is lazily allocated. This jvmti_thread_state()
|
||||
// getter is used to get this JavaThread's JvmtiThreadState if it has
|
||||
// one which means NULL can be returned. JvmtiThreadState::state_for()
|
||||
// is used to get the specified JavaThread's JvmtiThreadState if it has
|
||||
// one or it allocates a new JvmtiThreadState for the JavaThread and
|
||||
// returns it. JvmtiThreadState::state_for() will return NULL only if
|
||||
// the specified JavaThread is exiting.
|
||||
JvmtiThreadState *jvmti_thread_state() const { return _jvmti_thread_state; }
|
||||
static ByteSize jvmti_thread_state_offset() { return byte_offset_of(JavaThread, _jvmti_thread_state); }
|
||||
void set_jvmti_get_loaded_classes_closure(JvmtiGetLoadedClassesClosure* value) { _jvmti_get_loaded_classes_closure = value; }
|
||||
|
Loading…
x
Reference in New Issue
Block a user