提交 34876602 编写于 作者: A alanb

6529758: JVMTI Waiters demo crashes. Double free.

Reviewed-by: ohair, tbell
上级 eed4dc6a
...@@ -72,36 +72,30 @@ Agent::get_monitor(jvmtiEnv *jvmti, JNIEnv *env, jobject object) ...@@ -72,36 +72,30 @@ Agent::get_monitor(jvmtiEnv *jvmti, JNIEnv *env, jobject object)
{ {
jvmtiError err; jvmtiError err;
Monitor *m; Monitor *m;
jlong tag;
/* We use tags to track these, the tag is the Monitor pointer */ m = NULL;
err = jvmti->RawMonitorEnter(lock); { tag = (jlong)0;
check_jvmti_error(jvmti, err, "raw monitor enter"); err = jvmti->GetTag(object, &tag);
check_jvmti_error(jvmti, err, "get tag");
/* The raw monitor enter/exit protects us from creating two /*LINTED*/
* instances for the same object. m = (Monitor *)(void *)(ptrdiff_t)tag;
*/ if ( m == NULL ) {
jlong tag; m = new Monitor(jvmti, env, object);
/* Save monitor on list */
m = NULL; if (monitor_count == monitor_list_size) {
tag = (jlong)0; monitor_list_size += monitor_list_grow_size;
err = jvmti->GetTag(object, &tag);
check_jvmti_error(jvmti, err, "get tag");
/*LINTED*/
m = (Monitor *)(void *)(ptrdiff_t)tag;
if ( m == NULL ) {
m = new Monitor(jvmti, env, object);
/*LINTED*/
tag = (jlong)(ptrdiff_t)(void *)m;
err = jvmti->SetTag(object, tag);
check_jvmti_error(jvmti, err, "set tag");
/* Save monitor on list */
monitor_list = (Monitor**)realloc((void*)monitor_list, monitor_list = (Monitor**)realloc((void*)monitor_list,
(monitor_count+1)*(int)sizeof(Monitor*)); (monitor_list_size)*(int)sizeof(Monitor*));
monitor_list[monitor_count++] = m;
} }
} err = jvmti->RawMonitorExit(lock); monitor_list[monitor_count] = m;
check_jvmti_error(jvmti, err, "raw monitor exit"); m->set_slot(monitor_count);
monitor_count++;
/*LINTED*/
tag = (jlong)(ptrdiff_t)(void *)m;
err = jvmti->SetTag(object, tag);
check_jvmti_error(jvmti, err, "set tag");
}
return m; return m;
} }
...@@ -112,12 +106,11 @@ Agent::Agent(jvmtiEnv *jvmti, JNIEnv *env, jthread thread) ...@@ -112,12 +106,11 @@ Agent::Agent(jvmtiEnv *jvmti, JNIEnv *env, jthread thread)
stdout_message("Agent created..\n"); stdout_message("Agent created..\n");
stdout_message("VMInit...\n"); stdout_message("VMInit...\n");
/* Create a Monitor lock to use */
err = jvmti->CreateRawMonitor("waiters Agent lock", &lock);
check_jvmti_error(jvmti, err, "create raw monitor");
/* Start monitor list */ /* Start monitor list */
monitor_count = 0; monitor_count = 0;
monitor_list = (Monitor**)malloc((int)sizeof(Monitor*)); monitor_list_size = initial_monitor_list_size;
monitor_list = (Monitor**)
malloc(monitor_list_size*(int)sizeof(Monitor*));
} }
Agent::~Agent() Agent::~Agent()
...@@ -134,9 +127,6 @@ void Agent::vm_death(jvmtiEnv *jvmti, JNIEnv *env) ...@@ -134,9 +127,6 @@ void Agent::vm_death(jvmtiEnv *jvmti, JNIEnv *env)
delete monitor_list[i]; delete monitor_list[i];
} }
free(monitor_list); free(monitor_list);
/* Destroy the Monitor lock to use */
err = jvmti->DestroyRawMonitor(lock);
check_jvmti_error(jvmti, err, "destroy raw monitor");
/* Print death message */ /* Print death message */
stdout_message("VMDeath...\n"); stdout_message("VMDeath...\n");
} }
...@@ -215,8 +205,16 @@ void Agent::object_free(jvmtiEnv* jvmti, jlong tag) ...@@ -215,8 +205,16 @@ void Agent::object_free(jvmtiEnv* jvmti, jlong tag)
/* We just cast the tag to a C++ pointer and delete it. /* We just cast the tag to a C++ pointer and delete it.
* we know it can only be a Monitor *. * we know it can only be a Monitor *.
*/ */
Monitor *m; Monitor *m;
/*LINTED*/ /*LINTED*/
m = (Monitor *)(ptrdiff_t)tag; m = (Monitor *)(ptrdiff_t)tag;
if (monitor_count > 1) {
/* Move the last element to this Monitor's slot */
int slot = m->get_slot();
Monitor *last = monitor_list[monitor_count-1];
monitor_list[slot] = last;
last->set_slot(slot);
}
monitor_count--;
delete m; delete m;
} }
...@@ -34,8 +34,12 @@ ...@@ -34,8 +34,12 @@
class Agent { class Agent {
private: private:
jrawMonitorID lock; enum {
initial_monitor_list_size = 64,
monitor_list_grow_size = 16
};
Monitor **monitor_list; Monitor **monitor_list;
unsigned monitor_list_size;
unsigned monitor_count; unsigned monitor_count;
Thread *get_thread(jvmtiEnv *jvmti, JNIEnv *env, jthread thread); Thread *get_thread(jvmtiEnv *jvmti, JNIEnv *env, jthread thread);
Monitor *get_monitor(jvmtiEnv *jvmti, JNIEnv *env, jobject object); Monitor *get_monitor(jvmtiEnv *jvmti, JNIEnv *env, jobject object);
......
...@@ -73,6 +73,16 @@ Monitor::~Monitor() ...@@ -73,6 +73,16 @@ Monitor::~Monitor()
name, contends, waits, timeouts); name, contends, waits, timeouts);
} }
int Monitor::get_slot()
{
return slot;
}
void Monitor::set_slot(int aslot)
{
slot = aslot;
}
void Monitor::contended() void Monitor::contended()
{ {
contends++; contends++;
......
...@@ -35,6 +35,7 @@ class Monitor { ...@@ -35,6 +35,7 @@ class Monitor {
private: private:
char name[64]; char name[64];
int slot;
unsigned contends; unsigned contends;
unsigned waits; unsigned waits;
unsigned timeouts; unsigned timeouts;
...@@ -42,6 +43,8 @@ class Monitor { ...@@ -42,6 +43,8 @@ class Monitor {
public: public:
Monitor(jvmtiEnv *jvmti, JNIEnv *env, jobject object); Monitor(jvmtiEnv *jvmti, JNIEnv *env, jobject object);
~Monitor(); ~Monitor();
int get_slot();
void set_slot(int i);
void contended(); void contended();
void waited(); void waited();
void timeout(); void timeout();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册