This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
RFC: JDWP ExceptionEvent Notification
- From: Kyle Galloway <kgallowa at redhat dot com>
- To: java-patches at gcc dot gnu dot org
- Date: Wed, 30 Aug 2006 16:48:33 -0400
- Subject: RFC: JDWP ExceptionEvent Notification
This patch implements JDWP notification for Exception Events that occurr
in interpreted code. I uses a a manager class ExceptionManager to
record exceptions and whether or not they are caught. As the exception
moves up the call stack, if it is caught the manager is notified and
generates an appropriate JDWP event. If the exception is never caught,
the manager is notified and again send an appropriate JDWP event. This
code is ifdefed in so that the code is only executed inside
_Jv_InterpMethod::run_debug and not when debugging is disabled.
Comments, or can I commit this?
Thanks,
Kyle
2006-08-30 Kyle Galloway <kgallowa@redhat.com>
* interpret.cc: Added #includes for JDWP.
* interpret-run.cc: Added exception event notification code for caught
and uncaught exceptions.
* gnu/gcj/jdwp/ExceptionManager.java: New file.
* include/java-interp.h (_Jv_InterpMethod): Made class method insn_index
public.
* java/lang/natThread.cc (_Jv_ThreadRun): Added code to notify if an
exception remains uncaught.
Index: /notnfs/kgallowa/gcc-svn/libjava/gnu/gcj/jdwp/ExceptionManager.java
===================================================================
--- /notnfs/kgallowa/gcc-svn/libjava/gnu/gcj/jdwp/ExceptionManager.java (revision 0)
+++ /notnfs/kgallowa/gcc-svn/libjava/gnu/gcj/jdwp/ExceptionManager.java (revision 0)
@@ -0,0 +1,93 @@
+/* ExceptiontManager.java -
+
+ Copyright (C) 2006 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package gnu.gcj.jdwp;
+
+import java.lang.Thread;
+import java.util.ArrayList;
+
+import gnu.classpath.jdwp.Jdwp;
+import gnu.classpath.jdwp.event.Event;
+import gnu.classpath.jdwp.event.ExceptionEvent;
+import gnu.classpath.jdwp.util.Location;
+
+/**
+ * This class manages exceptions generated in code as it is interpreted by the
+ * VM. It keeps track of any exceptions thus far uncaught, and when they are
+ * either caught somewhere on the call stack or thrown up to the general handler
+ * and therefore ruled uncaught it dispatches the appropriate event using
+ * Jdwp.notify(Event event);
+ *
+ * @author Kyle Galloway (kgallowa@redhat.com)
+ */
+public class ExceptionManager
+{
+ //The actual ExceptionManager instance
+ private static ExceptionManager _exMan = null;
+
+ //List to hold throwables
+ private ArrayList tList = null;
+
+ //List to hold events(needed to keep track of other data)
+ private ArrayList evList = null;
+
+ //initial list size
+ private final int LIST_SIZE = 3;
+
+ private ExceptionManager()
+ {
+ //this holds the references to the throwables
+ tList = new ArrayList(LIST_SIZE);
+ //this holds the correponding events
+ evList = new ArrayList(LIST_SIZE);
+ }
+
+ public static ExceptionManager getDefault()
+ {
+ if (_exMan == null)
+ _exMan = new ExceptionManager();
+ return _exMan;
+ }
+
+ public void add(Throwable t, Thread thread, Location loc, Class clazz, Object instance)
+ {
+ System.out.println("EventManager Add: " + t);
+ tList.add(t);
+ ExceptionEvent exEvent = new ExceptionEvent(t, thread, loc, null, clazz, instance);
+ evList.add(exEvent);
+ }
+
+ public void caughtThrow(Throwable t, Thread thread, Location catchLoc)
+ {
+ System.out.println("EventManager caughtThrow " + t);
+ int index = tList.indexOf(t);
+ tList.remove(index);
+ ExceptionEvent exEvent = (ExceptionEvent) evList.remove(index);
+ exEvent.setCatchLoc(catchLoc);
+ Jdwp.notify(exEvent);
+ }
+
+ public void uncaughtThrow(Throwable t, Thread thread)
+ {
+ System.out.println("EventManager uncaughtThrow " + t);
+ int index = tList.indexOf(t);
+ tList.remove(index);
+ ExceptionEvent exEvent = (ExceptionEvent) evList.remove(index);
+ Location catchLoc = Location.getEmptyLocation();
+ exEvent.setCatchLoc(catchLoc);
+ Jdwp.notify(exEvent);
+ }
+
+ public boolean isManaged(Throwable t, Thread thread)
+ {
+ System.out.println("EventManager isManaged " + t);
+ return tList.contains(t);
+ }
+}
Index: /notnfs/kgallowa/gcc-svn/libjava/include/java-interp.h
===================================================================
--- /notnfs/kgallowa/gcc-svn/libjava/include/java-interp.h (revision 116385)
+++ /notnfs/kgallowa/gcc-svn/libjava/include/java-interp.h (working copy)
@@ -191,7 +191,7 @@
// number info is unavailable.
int get_source_line(pc_t mpc);
-
+public:
#ifdef DIRECT_THREADED
// Convenience function for indexing bytecode PC/insn slots in
@@ -198,8 +198,7 @@
// line tables for JDWP
jlong insn_index (pc_t pc);
#endif
-
- public:
+
/* Get the line table for this method.
* start is the lowest index in the method
Index: /notnfs/kgallowa/gcc-svn/libjava/interpret-run.cc
===================================================================
--- /notnfs/kgallowa/gcc-svn/libjava/interpret-run.cc (revision 116385)
+++ /notnfs/kgallowa/gcc-svn/libjava/interpret-run.cc (working copy)
@@ -2489,7 +2495,35 @@
#endif /* DIRECT_THREADED */
if (handler == NULL || handler->isAssignableFrom (exc_class))
- {
+ {
+#ifdef DEBUG
+ if (::gnu::classpath::jdwp::Jdwp::isDebugging)
+ {
+ using namespace gnu::classpath::jdwp;
+ jlong methodId = reinterpret_cast<jlong> (meth->self);
+ VMMethod* method
+ = VMVirtualMachine::getClassMethod (meth->defining_class, methodId);
+ util::Location* loc
+ = new util::Location (method, meth->insn_index ((insn_slot*)logical_pc));
+ util::Location* catchLoc
+ = new util::Location (method, meth->insn_index (PCVAL((insn_slot*)exc[i].handler_pc)));
+ using namespace gnu::gcj::jdwp;
+ ExceptionManager* exM = ExceptionManager::getDefault();
+ jobject objectref = NULL;
+ if(_Jv_isVirtualMethod(meth->get_method()))
+ objectref = (jobject) args[0].ptr;
+ if(exM->isManaged(ex, thread))
+ {
+ exM->caughtThrow(ex, thread, catchLoc);
+ }
+ else
+ {
+ event::ExceptionEvent* exEvent
+ = new event::ExceptionEvent (ex, thread, loc, catchLoc, meth->defining_class, objectref);
+ Jdwp::notify (exEvent);
+ }
+ }
+#endif
#ifdef DIRECT_THREADED
pc = (insn_slot *) exc[i].handler_pc.p;
@@ -2503,6 +2537,28 @@
}
}
+#ifdef DEBUG
+ //report the uncaught exception
+ if (::gnu::classpath::jdwp::Jdwp::isDebugging)
+ {
+ using namespace ::gnu::classpath::jdwp;
+ jlong methodId = reinterpret_cast<jlong> (meth->self);
+ VMMethod* method
+ = VMVirtualMachine::getClassMethod (meth->defining_class, methodId);
+ util::Location* loc
+ = new util::Location(method, meth->insn_index ((insn_slot*)logical_pc));
+ using namespace gnu::gcj::jdwp;
+ ExceptionManager* exM = ExceptionManager::getDefault();
+ jobject objectref = NULL;
+ if(_Jv_isVirtualMethod(meth->get_method()))
+ objectref = (jobject) args[0].ptr;
+ if(!exM->isManaged(ex, thread))
+ {
+ exM->add(ex, thread, loc, meth->defining_class, objectref);
+ }
+ }
+#endif
+
// No handler, so re-throw.
throw ex;
}
Index: /notnfs/kgallowa/gcc-svn/libjava/interpret.cc
===================================================================
--- /notnfs/kgallowa/gcc-svn/libjava/interpret.cc (revision 116385)
+++ /notnfs/kgallowa/gcc-svn/libjava/interpret.cc (working copy)
@@ -16,6 +16,7 @@
#pragma implementation "java-interp.h"
#include <jvm.h>
+#include <jvmti.h>
#include <java-cpool.h>
#include <java-interp.h>
#include <java/lang/System.h>
@@ -38,6 +39,12 @@
#include <java/lang/reflect/Modifier.h>
#include <gnu/classpath/jdwp/Jdwp.h>
+#include <gnu/classpath/jdwp/VMMethod.h>
+#include <gnu/classpath/jdwp/VMVirtualMachine.h>
+#include <gnu/classpath/jdwp/event/ExceptionEvent.h>
+#include <gnu/classpath/jdwp/exception/JdwpInternalErrorException.h>
+#include <gnu/classpath/jdwp/util/Location.h>
+#include <gnu/gcj/jdwp/ExceptionManager.h>
#ifdef INTERPRETER
Index: /notnfs/kgallowa/gcc-svn/libjava/java/lang/natThread.cc
===================================================================
--- /notnfs/kgallowa/gcc-svn/libjava/java/lang/natThread.cc (revision 116385)
+++ /notnfs/kgallowa/gcc-svn/libjava/java/lang/natThread.cc (working copy)
@@ -24,6 +24,9 @@
#include <java/lang/InterruptedException.h>
#include <java/lang/NullPointerException.h>
+#include <gnu/classpath/jdwp/Jdwp.h>
+#include <gnu/gcj/jdwp/ExceptionManager.h>
+
#include <jni.h>
#ifdef ENABLE_JVMPI
@@ -307,6 +310,15 @@
// this results in an uncaught exception, that is ignored.
try
{
+
+ //Report the uncaught exception if debugging
+ if (::gnu::classpath::jdwp::Jdwp::isDebugging)
+ {
+ using namespace gnu::gcj::jdwp;
+ ExceptionManager* exM = ExceptionManager::getDefault();
+ exM->uncaughtThrow(t, thread);
+ }
+
thread->group->uncaughtException (thread, t);
}
catch (java::lang::Throwable *f)