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]

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)

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