jvmti-int.h (_Jv_ReportJVMTIExceptionThrow): Declare.

* include/jvmti-int.h (_Jv_ReportJVMTIExceptionThrow):
        Declare.
        * interpret.cc (_Jv_ReportJVMTIExceptionThrow): New function.
        (find_catch_location): New function.
        (REPORT_EXCEPTION): New macro.
        (throw_internal_error): Use REPORT_EXCEPTION.
        (throw_incompatible_class_change_error): Likewise.
        (throw_null_pointer_exception): Likewise.
        (throw_class_format_error): Likewise.
        * interpret-run.cc (INTERP_REPORT_EXCEPTION)[DEBUG]: Set
        to REPORT_EXCEPTION.
        (INTERP_REPORT_EXCEPTION)[!DEBUG]: Make nop.
        (insn_new): Use INTERP_REPORT_EXCEPTION.
        (insn_athrow): Likewise.
        Remove previous JVMTI exception notifications.
        Add JVMTI ExceptionCatch notificatin.
        * jni.cc (_Jv_PopSystemFrame): Notify JVMTI clients of
        exception throw.
        * gnu/gcj/jvmti/ExceptionEvent.java: Removed.
        * gnu/gcj/jvmti/ExceptionEvent.h: Removed.
        * classpath/lib/gnu/gcj/jvmti/ExceptionEvent.class: Removed.
        * gnu/classpath/jdwp/natVMVirtualMachine.cc
        (jdwpExceptionCB): New function.
        (jdwpVMInitCB): Set Exception event handler and enable.
        * sources.am: Regenerated.
        * Makefile.in: Regenerated.

From-SVN: r124406
This commit is contained in:
Keith Seitz
2007-05-04 01:04:11 +00:00
committed by Keith Seitz
parent 820b51ae16
commit befd756626
11 changed files with 198 additions and 169 deletions
@@ -21,6 +21,7 @@ details. */
#include <java/lang/String.h>
#include <java/lang/StringBuilder.h>
#include <java/lang/Thread.h>
#include <java/lang/Throwable.h>
#include <java/nio/ByteBuffer.h>
#include <java/nio/ByteBufferImpl.h>
#include <java/util/ArrayList.h>
@@ -37,6 +38,7 @@ details. */
#include <gnu/classpath/jdwp/VMVirtualMachine.h>
#include <gnu/classpath/jdwp/event/BreakpointEvent.h>
#include <gnu/classpath/jdwp/event/ClassPrepareEvent.h>
#include <gnu/classpath/jdwp/event/ExceptionEvent.h>
#include <gnu/classpath/jdwp/event/EventManager.h>
#include <gnu/classpath/jdwp/event/EventRequest.h>
#include <gnu/classpath/jdwp/event/SingleStepEvent.h>
@@ -82,6 +84,9 @@ static void handle_single_step (jvmtiEnv *, struct step_info *, jthread,
static void JNICALL jdwpBreakpointCB (jvmtiEnv *, JNIEnv *, jthread,
jmethodID, jlocation);
static void JNICALL jdwpClassPrepareCB (jvmtiEnv *, JNIEnv *, jthread, jclass);
static void JNICALL jdwpExceptionCB (jvmtiEnv *, JNIEnv *jni_env, jthread,
jmethodID, jlocation, jobject,
jmethodID, jlocation);
static void JNICALL jdwpSingleStepCB (jvmtiEnv *, JNIEnv *, jthread,
jmethodID, jlocation);
static void JNICALL jdwpThreadEndCB (jvmtiEnv *, JNIEnv *, jthread);
@@ -932,6 +937,56 @@ jdwpClassPrepareCB (MAYBE_UNUSED jvmtiEnv *env, MAYBE_UNUSED JNIEnv *jni_env,
Jdwp::notify (event);
}
static void JNICALL
jdwpExceptionCB (jvmtiEnv *env, MAYBE_UNUSED JNIEnv *jni_env, jthread thread,
jmethodID method, jlocation location, jobject exception,
jmethodID catch_method, jlocation catch_location)
{
using namespace gnu::classpath::jdwp;
jclass throw_klass;
jvmtiError err = env->GetMethodDeclaringClass (method, &throw_klass);
if (err != JVMTI_ERROR_NONE)
{
fprintf (stderr, "libgcj: internal error: could not find class for ");
fprintf (stderr, "method throwing exception -- continuing\n");
return;
}
VMMethod *vmmethod = new VMMethod (throw_klass,
reinterpret_cast<jlong> (method));
Location *throw_loc = new Location (vmmethod, location);
Location *catch_loc = NULL;
if (catch_method == 0)
catch_loc = Location::getEmptyLocation ();
else
{
jclass catch_klass;
err = env->GetMethodDeclaringClass (catch_method, &catch_klass);
if (err != JVMTI_ERROR_NONE)
{
fprintf (stderr,
"libgcj: internal error: could not find class for ");
fprintf (stderr,
"method catching exception -- ignoring\n");
}
else
{
vmmethod = new VMMethod (catch_klass,
reinterpret_cast<jlong> (catch_method));
catch_loc = new Location (vmmethod, catch_location);
}
}
_Jv_InterpFrame *iframe
= reinterpret_cast<_Jv_InterpFrame *> (thread->interp_frame);
jobject instance = (iframe == NULL) ? NULL : iframe->get_this_ptr ();
Throwable *throwable = reinterpret_cast<Throwable *> (exception);
event::ExceptionEvent *e = new ExceptionEvent (throwable, thread,
throw_loc, catch_loc,
throw_klass, instance);
Jdwp::notify (e);
}
static void JNICALL
jdwpSingleStepCB (jvmtiEnv *env, JNIEnv *jni_env, jthread thread,
jmethodID method, jlocation location)
@@ -1034,6 +1089,7 @@ jdwpVMInitCB (MAYBE_UNUSED jvmtiEnv *env, MAYBE_UNUSED JNIEnv *jni_env,
jvmtiEventCallbacks callbacks;
DEFINE_CALLBACK (callbacks, Breakpoint);
DEFINE_CALLBACK (callbacks, ClassPrepare);
DEFINE_CALLBACK (callbacks, Exception);
DEFINE_CALLBACK (callbacks, SingleStep);
DEFINE_CALLBACK (callbacks, ThreadEnd);
DEFINE_CALLBACK (callbacks, ThreadStart);
@@ -1043,6 +1099,7 @@ jdwpVMInitCB (MAYBE_UNUSED jvmtiEnv *env, MAYBE_UNUSED JNIEnv *jni_env,
// Enable callbacks
ENABLE_EVENT (BREAKPOINT, NULL);
ENABLE_EVENT (CLASS_PREPARE, NULL);
ENABLE_EVENT (EXCEPTION, NULL);
// SingleStep is enabled only when needed
ENABLE_EVENT (THREAD_END, NULL);
ENABLE_EVENT (THREAD_START, NULL);
-44
View File
@@ -1,44 +0,0 @@
// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
#ifndef __gnu_gcj_jvmti_ExceptionEvent__
#define __gnu_gcj_jvmti_ExceptionEvent__
#pragma interface
#include <java/lang/Object.h>
extern "Java"
{
namespace gnu
{
namespace gcj
{
namespace jvmti
{
class ExceptionEvent;
}
}
}
}
class gnu::gcj::jvmti::ExceptionEvent : public ::java::lang::Object
{
ExceptionEvent(::java::lang::Thread *, jlong, jlong, ::java::lang::Throwable *, jlong, jlong);
public:
static void postExceptionEvent(::java::lang::Thread *, jlong, jlong, ::java::lang::Throwable *, jlong, jlong);
virtual void sendEvent();
virtual void checkCatch();
private:
jlong __attribute__((aligned(__alignof__( ::java::lang::Object)))) _throwMeth;
jlong _throwLoc;
jlong _catchMeth;
jlong _catchLoc;
::java::lang::Thread * _thread;
::java::lang::Throwable * _ex;
static ::java::util::WeakHashMap * _exMap;
public:
static ::java::lang::Class class$;
};
#endif // __gnu_gcj_jvmti_ExceptionEvent__
-96
View File
@@ -1,96 +0,0 @@
// ExceptionEvent - an exception event for JVMTI
/* Copyright (C) 2007 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.jvmti;
import java.util.WeakHashMap;
/**
* Class to create and send JVMTI Exception events
*
* @author Kyle Galloway (kgallowa@redhat.com)
*/
public class ExceptionEvent
{
// Information about where the exception was thrown
private long _throwMeth, _throwLoc;
// Information about where the exception was or can be caught
private long _catchMeth, _catchLoc;
// Thread where the exception occurred
private Thread _thread;
// The exception
private Throwable _ex;
// A hash map of the exceptions we've already seen in a thread's call stack
private static WeakHashMap<Thread, Throwable> _exMap = new WeakHashMap<Thread, Throwable>();
/**
* Constructs a new ExceptionEvent and sends it. If it is not caught
* within the frame where it was thrown (catchMeth and catchLoc are null),
* check_catch will check for a possible catch further up the call stack
* before marking it uncaught.
*
* @param thr the thread where the exception occurred
* @param throwMeth the method of the throw (a jmethodID)
* @param throwLoc the location of the throw (a jlocation)
* @param ex the exception
* @param catchMeth the method of the catch (a jmethodID), null indicates
* that the exception was not caught in the frame where it was thrown
* @param catchLoc the location of the catch (a jlocation), null indicates
* that the exception was not caught in the frame where it was thrown
*/
private ExceptionEvent(Thread thr, long throwMeth, long throwLoc,
Throwable ex, long catchMeth, long catchLoc)
{
this._thread = thr;
this._ex = ex;
this._throwMeth = throwMeth;
this._throwLoc = throwLoc;
this._catchMeth = catchMeth;
this._catchLoc = catchLoc;
}
public static void postExceptionEvent(Thread thr, long throwMeth,
long throwLoc, Throwable ex,
long catchMeth, long catchLoc)
{
// Check to see if there is an entry for this Thread thr in the has map.
// If not, add the thread to the hash map and send an ExceptionEvent.
if (_exMap.containsKey(thr))
{
// Check to see if we are receiving events for the same exception, or a
// new one. If it is not the same exception beign rethrown, send a new
// event.
if (!(_exMap.get(thr) == ex))
{
_exMap.put(thr, ex);
ExceptionEvent event = new ExceptionEvent(thr, throwMeth,
throwLoc, ex, catchMeth,
catchLoc);
event.sendEvent ();
}
}
else
{
_exMap.put(thr, ex);
ExceptionEvent event = new ExceptionEvent(thr, throwMeth,
throwLoc, ex, catchMeth,
catchLoc);
event.sendEvent();
}
}
public native void sendEvent();
public native void checkCatch();
}