This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFA/JDWP] Implement several JDWP callbacks


Hi,

This patch implements the JDWP callbacks for the JVMTI events ClassPrepare, ThreadStart, ThreadEnd, and VMDeath. These are all simple callbacks which don't really do much more than send a packet down the wire to the debugger.

Ok?
Keith

ChangeLog
2007-01-25  Keith Seitz  <keiths@redhat.com>

        * gnu/classpath/jdwp/natVMVirtualMachine.cc
        (getAllClassMethods): Move error handling to ...
        (throw_jvmti_error): ... here.
        (jdwpClassPrepareCB): New function.
        (jdwpThreadEndCB): New function.
        (jdwpThreadStartCB): New function.
        (jdwpVMDeathCB): New function.
        (jdwpVMInitCB): Define and enable callbacks for
        ClassPrepare, ThreadEnd, ThreadStart, and VMDeath.

Index: gnu/classpath/jdwp/natVMVirtualMachine.cc
===================================================================
--- gnu/classpath/jdwp/natVMVirtualMachine.cc	(revision 121189)
+++ gnu/classpath/jdwp/natVMVirtualMachine.cc	(working copy)
@@ -28,7 +28,11 @@
 #include <gnu/classpath/jdwp/VMFrame.h>
 #include <gnu/classpath/jdwp/VMMethod.h>
 #include <gnu/classpath/jdwp/VMVirtualMachine.h>
+#include <gnu/classpath/jdwp/event/ClassPrepareEvent.h>
 #include <gnu/classpath/jdwp/event/EventRequest.h>
+#include <gnu/classpath/jdwp/event/ThreadEndEvent.h>
+#include <gnu/classpath/jdwp/event/ThreadStartEvent.h>
+#include <gnu/classpath/jdwp/event/VmDeathEvent.h>
 #include <gnu/classpath/jdwp/event/VmInitEvent.h>
 #include <gnu/classpath/jdwp/exception/InvalidMethodException.h>
 #include <gnu/classpath/jdwp/exception/JdwpInternalErrorException.h>
@@ -39,7 +43,12 @@
 using namespace gnu::classpath::jdwp::util;
 
 // Forward declarations
+static void JNICALL jdwpClassPrepareCB (jvmtiEnv *, JNIEnv *, jthread, jclass);
+static void JNICALL jdwpThreadEndCB (jvmtiEnv *, JNIEnv *, jthread);
+static void JNICALL jdwpThreadStartCB (jvmtiEnv *, JNIEnv *, jthread);
+static void JNICALL jdwpVMDeathCB (jvmtiEnv *, JNIEnv *);
 static void JNICALL jdwpVMInitCB (jvmtiEnv *, JNIEnv *, jthread);
+static void throw_jvmti_error (jvmtiError);
 
 #define DEFINE_CALLBACK(Cb,Event) Cb.Event = jdwp ## Event ## CB
 #define ENABLE_EVENT(Event,Thread)					\
@@ -313,21 +322,8 @@
   jmethodID *methods;
   jvmtiError err = _jdwp_jvmtiEnv->GetClassMethods (klass, &count, &methods);
   if (err != JVMTI_ERROR_NONE)
-    {
-      char *error;
-      jstring msg;
-      if (_jdwp_jvmtiEnv->GetErrorName (err, &error) != JVMTI_ERROR_NONE)
-	{
-	  msg = JvNewStringLatin1 (error);
-	  _jdwp_jvmtiEnv->Deallocate ((unsigned char *) error);
-	}
-      else
-	msg = JvNewStringLatin1 ("out of memory");
+    throw_jvmti_error (err);
 
-      using namespace gnu::classpath::jdwp::exception;
-      throw new JdwpInternalErrorException (msg);
-    }
-
   JArray<VMMethod *> *result
     = (JArray<VMMethod *> *) JvNewObjectArray (count,
 					       &VMMethod::class$, NULL);
@@ -407,10 +403,98 @@
   return NULL;
 }
 
+static void
+throw_jvmti_error (jvmtiError err)
+{
+  char *error;
+  jstring msg;
+  if (_jdwp_jvmtiEnv->GetErrorName (err, &error) == JVMTI_ERROR_NONE)
+    {
+      msg = JvNewStringLatin1 (error);
+      _jdwp_jvmtiEnv->Deallocate ((unsigned char *) error);
+    }
+  else
+    msg = JvNewStringLatin1 ("out of memory");
+
+  using namespace gnu::classpath::jdwp::exception;
+  throw new JdwpInternalErrorException (msg);
+}
+
 static void JNICALL
+jdwpClassPrepareCB (jvmtiEnv *env, MAYBE_UNUSED JNIEnv *jni_env,
+		    jthread thread, jclass klass)
+{
+  using namespace gnu::classpath::jdwp;
+
+  Thread *t = reinterpret_cast<Thread *> (thread);
+  jint flags = 0;
+  jvmtiError err = env->GetClassStatus (klass, &flags);
+  if (err != JVMTI_ERROR_NONE)
+    throw_jvmti_error (err);
+
+  using namespace gnu::classpath::jdwp::event;
+  jint status = 0;
+  if (flags & JVMTI_CLASS_STATUS_VERIFIED)
+    status |= ClassPrepareEvent::STATUS_VERIFIED;
+  if (flags & JVMTI_CLASS_STATUS_PREPARED)
+    status |= ClassPrepareEvent::STATUS_PREPARED;
+  if (flags & JVMTI_CLASS_STATUS_ERROR)
+    status |= ClassPrepareEvent::STATUS_ERROR;
+  if (flags & JVMTI_CLASS_STATUS_INITIALIZED)
+    status |= ClassPrepareEvent::STATUS_INITIALIZED;
+
+  event::ClassPrepareEvent *event
+    = new event::ClassPrepareEvent (t, klass, status);
+  Jdwp::notify (event);
+}
+
+static void JNICALL
+jdwpThreadEndCB (MAYBE_UNUSED jvmtiEnv *env, MAYBE_UNUSED JNIEnv *jni_env,
+		 jthread thread)
+{
+  using namespace gnu::classpath::jdwp::event;
+
+  Thread *t = reinterpret_cast<Thread *> (thread);
+  ThreadEndEvent *e = new ThreadEndEvent (t);
+  gnu::classpath::jdwp::Jdwp::notify (e);
+}
+
+static void JNICALL
+jdwpThreadStartCB (MAYBE_UNUSED jvmtiEnv *env, MAYBE_UNUSED JNIEnv *jni_env,
+		   jthread thread)
+{
+  using namespace gnu::classpath::jdwp::event;
+
+  Thread *t = reinterpret_cast<Thread *> (thread);
+  ThreadStartEvent *e = new ThreadStartEvent (t);
+  gnu::classpath::jdwp::Jdwp::notify (e);
+}
+
+static void JNICALL
+jdwpVMDeathCB (MAYBE_UNUSED jvmtiEnv *env, MAYBE_UNUSED JNIEnv *jni_env)
+{
+  using namespace gnu::classpath::jdwp::event;
+  gnu::classpath::jdwp::Jdwp::notify (new VmDeathEvent ());
+}
+
+static void JNICALL
 jdwpVMInitCB (MAYBE_UNUSED jvmtiEnv *env, MAYBE_UNUSED JNIEnv *jni_env,
 	      jthread thread)
 {
+  // The VM is now initialized, add our callbacks
+  jvmtiEventCallbacks callbacks;
+  DEFINE_CALLBACK (callbacks, ClassPrepare);
+  DEFINE_CALLBACK (callbacks, ThreadEnd);
+  DEFINE_CALLBACK (callbacks, ThreadStart);
+  DEFINE_CALLBACK (callbacks, VMDeath);
+  _jdwp_jvmtiEnv->SetEventCallbacks (&callbacks, sizeof (callbacks));
+
+  // Enable callbacks
+  ENABLE_EVENT (CLASS_PREPARE, NULL);
+  ENABLE_EVENT (THREAD_END, NULL);
+  ENABLE_EVENT (THREAD_START, NULL);
+  ENABLE_EVENT (VM_DEATH, NULL);
+
   // Send JDWP VMInit
   using namespace gnu::classpath::jdwp::event;
   Thread *init_thread = reinterpret_cast<Thread *> (thread);

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]