6529758: JVMTI Waiters demo crashes. Double free.
Reviewed-by: ohair, tbell
--- a/jdk/src/share/demo/jvmti/waiters/Agent.cpp Sat Sep 12 15:30:13 2009 -0700
+++ b/jdk/src/share/demo/jvmti/waiters/Agent.cpp Mon Sep 14 15:29:13 2009 +0100
@@ -72,36 +72,30 @@
{
jvmtiError err;
Monitor *m;
-
- /* We use tags to track these, the tag is the Monitor pointer */
- err = jvmti->RawMonitorEnter(lock); {
- check_jvmti_error(jvmti, err, "raw monitor enter");
+ jlong tag;
- /* The raw monitor enter/exit protects us from creating two
- * instances for the same object.
- */
- jlong tag;
-
- m = NULL;
- tag = (jlong)0;
- err = jvmti->GetTag(object, &tag);
- check_jvmti_error(jvmti, err, "get tag");
+ m = NULL;
+ tag = (jlong)0;
+ 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);
+ /* Save monitor on list */
+ if (monitor_count == monitor_list_size) {
+ monitor_list_size += monitor_list_grow_size;
+ monitor_list = (Monitor**)realloc((void*)monitor_list,
+ (monitor_list_size)*(int)sizeof(Monitor*));
+ }
+ monitor_list[monitor_count] = m;
+ m->set_slot(monitor_count);
+ monitor_count++;
/*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_count+1)*(int)sizeof(Monitor*));
- monitor_list[monitor_count++] = m;
- }
- } err = jvmti->RawMonitorExit(lock);
- check_jvmti_error(jvmti, err, "raw monitor exit");
-
+ tag = (jlong)(ptrdiff_t)(void *)m;
+ err = jvmti->SetTag(object, tag);
+ check_jvmti_error(jvmti, err, "set tag");
+ }
return m;
}
@@ -112,12 +106,11 @@
stdout_message("Agent created..\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 */
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()
@@ -134,9 +127,6 @@
delete monitor_list[i];
}
free(monitor_list);
- /* Destroy the Monitor lock to use */
- err = jvmti->DestroyRawMonitor(lock);
- check_jvmti_error(jvmti, err, "destroy raw monitor");
/* Print death message */
stdout_message("VMDeath...\n");
}
@@ -215,8 +205,16 @@
/* We just cast the tag to a C++ pointer and delete it.
* we know it can only be a Monitor *.
*/
- Monitor *m;
+ Monitor *m;
/*LINTED*/
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;
}
--- a/jdk/src/share/demo/jvmti/waiters/Agent.hpp Sat Sep 12 15:30:13 2009 -0700
+++ b/jdk/src/share/demo/jvmti/waiters/Agent.hpp Mon Sep 14 15:29:13 2009 +0100
@@ -34,8 +34,12 @@
class Agent {
private:
- jrawMonitorID lock;
+ enum {
+ initial_monitor_list_size = 64,
+ monitor_list_grow_size = 16
+ };
Monitor **monitor_list;
+ unsigned monitor_list_size;
unsigned monitor_count;
Thread *get_thread(jvmtiEnv *jvmti, JNIEnv *env, jthread thread);
Monitor *get_monitor(jvmtiEnv *jvmti, JNIEnv *env, jobject object);
--- a/jdk/src/share/demo/jvmti/waiters/Monitor.cpp Sat Sep 12 15:30:13 2009 -0700
+++ b/jdk/src/share/demo/jvmti/waiters/Monitor.cpp Mon Sep 14 15:29:13 2009 +0100
@@ -73,6 +73,16 @@
name, contends, waits, timeouts);
}
+int Monitor::get_slot()
+{
+ return slot;
+}
+
+void Monitor::set_slot(int aslot)
+{
+ slot = aslot;
+}
+
void Monitor::contended()
{
contends++;
--- a/jdk/src/share/demo/jvmti/waiters/Monitor.hpp Sat Sep 12 15:30:13 2009 -0700
+++ b/jdk/src/share/demo/jvmti/waiters/Monitor.hpp Mon Sep 14 15:29:13 2009 +0100
@@ -35,6 +35,7 @@
private:
char name[64];
+ int slot;
unsigned contends;
unsigned waits;
unsigned timeouts;
@@ -42,6 +43,8 @@
public:
Monitor(jvmtiEnv *jvmti, JNIEnv *env, jobject object);
~Monitor();
+ int get_slot();
+ void set_slot(int i);
void contended();
void waited();
void timeout();