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:
parent
820b51ae16
commit
befd756626
11 changed files with 198 additions and 169 deletions
|
@ -1,3 +1,32 @@
|
|||
2007-05-03 Keith Seitz <keiths@redhat.com>
|
||||
|
||||
* 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.
|
||||
|
||||
2007-05-03 Thomas Fitzsimmons <fitzsim@redhat.com>
|
||||
|
||||
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=237304
|
||||
|
|
|
@ -1349,7 +1349,6 @@ gnu_gcj_io_header_files = $(patsubst %.java,%.h,$(gnu_gcj_io_source_files))
|
|||
gnu_gcj_jvmti_source_files = \
|
||||
gnu/gcj/jvmti/Breakpoint.java \
|
||||
gnu/gcj/jvmti/BreakpointManager.java \
|
||||
gnu/gcj/jvmti/ExceptionEvent.java \
|
||||
gnu/gcj/jvmti/Location.java
|
||||
|
||||
gnu_gcj_jvmti_header_files = $(patsubst %.java,%.h,$(gnu_gcj_jvmti_source_files))
|
||||
|
|
Binary file not shown.
|
@ -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);
|
||||
|
|
|
@ -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__
|
|
@ -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();
|
||||
}
|
|
@ -89,4 +89,6 @@ extern void _Jv_JVMTI_PostEvent (jvmtiEvent type, jthread event_thread, ...)
|
|||
// Returns the jvmtiEnv used by the JDWP backend
|
||||
extern jvmtiEnv *_Jv_GetJDWP_JVMTIEnv (void);
|
||||
|
||||
// Reports JVMTI excpetions
|
||||
extern void _Jv_ReportJVMTIExceptionThrow (jthrowable);
|
||||
#endif /* __GCJ_JVMTI_INT_H__ */
|
||||
|
|
|
@ -377,7 +377,9 @@ details. */
|
|||
} \
|
||||
while (0)
|
||||
|
||||
#else
|
||||
#undef INTERP_REPORT_EXCEPTION
|
||||
#define INTERP_REPORT_EXCEPTION(Jthrowable) REPORT_EXCEPTION (Jthrowable)
|
||||
#else // !DEBUG
|
||||
#undef NEXT_INSN
|
||||
#define NEXT_INSN goto *((pc++)->insn)
|
||||
#define REWRITE_INSN(INSN,SLOT,VALUE) \
|
||||
|
@ -386,7 +388,10 @@ details. */
|
|||
pc[-1].SLOT = VALUE; \
|
||||
} \
|
||||
while (0)
|
||||
#endif
|
||||
|
||||
#undef INTERP_REPORT_EXCEPTION
|
||||
#define INTERP_REPORT_EXCEPTION(Jthrowable) /* not needed when not debugging */
|
||||
#endif // !DEBUG
|
||||
|
||||
#define INTVAL() ((pc++)->int_val)
|
||||
#define AVAL() ((pc++)->datum)
|
||||
|
@ -2355,7 +2360,11 @@ details. */
|
|||
/* VM spec, section 3.11.5 */
|
||||
if ((klass->getModifiers() & Modifier::ABSTRACT)
|
||||
|| klass->isInterface())
|
||||
throw new java::lang::InstantiationException;
|
||||
{
|
||||
jthrowable t = new java::lang::InstantiationException;
|
||||
INTERP_REPORT_EXCEPTION (t);
|
||||
throw t;
|
||||
}
|
||||
jobject res = _Jv_AllocObject (klass);
|
||||
PUSHA (res);
|
||||
|
||||
|
@ -2422,7 +2431,9 @@ details. */
|
|||
insn_athrow:
|
||||
{
|
||||
jobject value = POPA();
|
||||
throw static_cast<jthrowable>(value);
|
||||
jthrowable t = static_cast<jthrowable> (value);
|
||||
INTERP_REPORT_EXCEPTION (t);
|
||||
throw t;
|
||||
}
|
||||
NEXT_INSN;
|
||||
|
||||
|
@ -2639,10 +2650,6 @@ details. */
|
|||
}
|
||||
catch (java::lang::Throwable *ex)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
// This needs to be done before the pc is changed.
|
||||
jlong throw_loc = meth->insn_index (pc);
|
||||
#endif
|
||||
// Check if the exception is handled and, if so, set the pc to the start
|
||||
// of the appropriate catch block.
|
||||
if (meth->check_handler (&pc, meth, ex))
|
||||
|
@ -2650,27 +2657,19 @@ details. */
|
|||
sp = stack;
|
||||
sp++->o = ex; // Push exception.
|
||||
#ifdef DEBUG
|
||||
if (JVMTI_REQUESTED_EVENT (Exception))
|
||||
if (JVMTI_REQUESTED_EVENT (ExceptionCatch))
|
||||
{
|
||||
using namespace gnu::gcj::jvmti;
|
||||
jlong throw_meth = reinterpret_cast<jlong> (meth->get_method ());
|
||||
jlong catch_meth = reinterpret_cast<jlong> (meth->get_method ());
|
||||
jlong catch_loc = meth->insn_index (pc);
|
||||
ExceptionEvent::postExceptionEvent (thread, throw_meth,
|
||||
throw_loc, ex, throw_meth,
|
||||
catch_loc);
|
||||
_Jv_JVMTI_PostEvent (JVMTI_EVENT_EXCEPTION_CATCH, thread,
|
||||
_Jv_GetCurrentJNIEnv (), catch_meth,
|
||||
catch_loc, ex);
|
||||
}
|
||||
#endif
|
||||
NEXT_INSN;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
if (JVMTI_REQUESTED_EVENT (Exception))
|
||||
{
|
||||
using namespace gnu::gcj::jvmti;
|
||||
jlong throw_meth = reinterpret_cast<jlong> (meth->get_method ());
|
||||
ExceptionEvent::postExceptionEvent (thread, throw_meth, throw_loc,
|
||||
ex, NULL, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
// No handler, so re-throw.
|
||||
throw ex;
|
||||
}
|
||||
|
|
|
@ -40,7 +40,6 @@ details. */
|
|||
#include <jvmti.h>
|
||||
#include "jvmti-int.h"
|
||||
|
||||
#include <gnu/classpath/jdwp/Jdwp.h>
|
||||
#include <gnu/gcj/jvmti/Breakpoint.h>
|
||||
#include <gnu/gcj/jvmti/BreakpointManager.h>
|
||||
#include <gnu/gcj/jvmti/ExceptionEvent.h>
|
||||
|
@ -66,6 +65,16 @@ static void throw_class_format_error (jstring msg)
|
|||
static void throw_class_format_error (const char *msg)
|
||||
__attribute__ ((__noreturn__));
|
||||
|
||||
static void find_catch_location (jthrowable, jthread, jmethodID *, jlong *);
|
||||
|
||||
// A macro to facilitate JVMTI exception reporting
|
||||
#define REPORT_EXCEPTION(Jthrowable) \
|
||||
do { \
|
||||
if (JVMTI_REQUESTED_EVENT (Exception)) \
|
||||
_Jv_ReportJVMTIExceptionThrow (Jthrowable); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#ifdef DIRECT_THREADED
|
||||
// Lock to ensure that methods are not compiled concurrently.
|
||||
// We could use a finer-grained lock here, however it is not safe to use
|
||||
|
@ -956,19 +965,25 @@ _Jv_InterpMethod::run_debug (void *retp, ffi_raw *args, _Jv_InterpMethod *meth)
|
|||
static void
|
||||
throw_internal_error (const char *msg)
|
||||
{
|
||||
throw new java::lang::InternalError (JvNewStringLatin1 (msg));
|
||||
jthrowable t = new java::lang::InternalError (JvNewStringLatin1 (msg));
|
||||
REPORT_EXCEPTION (t);
|
||||
throw t;
|
||||
}
|
||||
|
||||
static void
|
||||
throw_incompatible_class_change_error (jstring msg)
|
||||
{
|
||||
throw new java::lang::IncompatibleClassChangeError (msg);
|
||||
jthrowable t = new java::lang::IncompatibleClassChangeError (msg);
|
||||
REPORT_EXCEPTION (t);
|
||||
throw t;
|
||||
}
|
||||
|
||||
static void
|
||||
throw_null_pointer_exception ()
|
||||
{
|
||||
throw new java::lang::NullPointerException;
|
||||
jthrowable t = new java::lang::NullPointerException;
|
||||
REPORT_EXCEPTION (t);
|
||||
throw t;
|
||||
}
|
||||
|
||||
/* Look up source code line number for given bytecode (or direct threaded
|
||||
|
@ -1613,9 +1628,11 @@ _Jv_JNIMethod::ncode (jclass klass)
|
|||
static void
|
||||
throw_class_format_error (jstring msg)
|
||||
{
|
||||
throw (msg
|
||||
jthrowable t = (msg
|
||||
? new java::lang::ClassFormatError (msg)
|
||||
: new java::lang::ClassFormatError);
|
||||
REPORT_EXCEPTION (t);
|
||||
throw t;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1624,6 +1641,70 @@ throw_class_format_error (const char *msg)
|
|||
throw_class_format_error (JvNewStringLatin1 (msg));
|
||||
}
|
||||
|
||||
/* This function finds the method and location where the exception EXC
|
||||
is caught in the stack frame. On return, it sets CATCH_METHOD and
|
||||
CATCH_LOCATION with the method and location where the catch will
|
||||
occur. If the exception is not caught, these are set to 0.
|
||||
|
||||
This function should only be used with the DEBUG interpreter. */
|
||||
static void
|
||||
find_catch_location (::java::lang::Throwable *exc, jthread thread,
|
||||
jmethodID *catch_method, jlong *catch_loc)
|
||||
{
|
||||
*catch_method = 0;
|
||||
*catch_loc = 0;
|
||||
|
||||
_Jv_InterpFrame *frame
|
||||
= reinterpret_cast<_Jv_InterpFrame *> (thread->interp_frame);
|
||||
while (frame != NULL)
|
||||
{
|
||||
pc_t pc = frame->get_pc ();
|
||||
_Jv_InterpMethod *imeth
|
||||
= reinterpret_cast<_Jv_InterpMethod *> (frame->self);
|
||||
if (imeth->check_handler (&pc, imeth, exc))
|
||||
{
|
||||
// This method handles the exception.
|
||||
*catch_method = imeth->get_method ();
|
||||
*catch_loc = imeth->insn_index (pc);
|
||||
return;
|
||||
}
|
||||
|
||||
frame = frame->next_interp;
|
||||
}
|
||||
}
|
||||
|
||||
/* This method handles JVMTI notifications of thrown exceptions. It
|
||||
calls find_catch_location to figure out where the exception is
|
||||
caught (if it is caught).
|
||||
|
||||
Like find_catch_location, this should only be called with the
|
||||
DEBUG interpreter. Since a few exceptions occur outside the
|
||||
interpreter proper, it is important to not call this function
|
||||
without checking JVMTI_REQUESTED_EVENT(Exception) first. */
|
||||
void
|
||||
_Jv_ReportJVMTIExceptionThrow (jthrowable ex)
|
||||
{
|
||||
jthread thread = ::java::lang::Thread::currentThread ();
|
||||
_Jv_Frame *frame = reinterpret_cast<_Jv_Frame *> (thread->frame);
|
||||
jmethodID throw_meth = frame->self->get_method ();
|
||||
jlocation throw_loc = -1;
|
||||
if (frame->frame_type == frame_interpreter)
|
||||
{
|
||||
_Jv_InterpFrame * iframe
|
||||
= reinterpret_cast<_Jv_InterpFrame *> (frame);
|
||||
_Jv_InterpMethod *imeth
|
||||
= reinterpret_cast<_Jv_InterpMethod *> (frame->self);
|
||||
throw_loc = imeth->insn_index (iframe->get_pc ());
|
||||
}
|
||||
|
||||
jlong catch_loc;
|
||||
jmethodID catch_method;
|
||||
find_catch_location (ex, thread, &catch_method, &catch_loc);
|
||||
_Jv_JVMTI_PostEvent (JVMTI_EVENT_EXCEPTION, thread,
|
||||
_Jv_GetCurrentJNIEnv (), throw_meth, throw_loc,
|
||||
ex, catch_method, catch_loc);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
|
|
|
@ -23,6 +23,7 @@ details. */
|
|||
#include <jvmpi.h>
|
||||
#endif
|
||||
#include <jvmti.h>
|
||||
#include "jvmti-int.h"
|
||||
|
||||
#include <java/lang/Class.h>
|
||||
#include <java/lang/ClassLoader.h>
|
||||
|
@ -456,6 +457,8 @@ _Jv_JNI_PopSystemFrame (JNIEnv *env)
|
|||
{
|
||||
jthrowable t = env->ex;
|
||||
env->ex = NULL;
|
||||
if (JVMTI_REQUESTED_EVENT (Exception))
|
||||
_Jv_ReportJVMTIExceptionThrow (t);
|
||||
throw t;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -538,7 +538,6 @@ gnu/gcj/io.list: $(gnu_gcj_io_source_files)
|
|||
gnu_gcj_jvmti_source_files = \
|
||||
gnu/gcj/jvmti/Breakpoint.java \
|
||||
gnu/gcj/jvmti/BreakpointManager.java \
|
||||
gnu/gcj/jvmti/ExceptionEvent.java \
|
||||
gnu/gcj/jvmti/Location.java
|
||||
|
||||
gnu_gcj_jvmti_header_files = $(patsubst %.java,%.h,$(gnu_gcj_jvmti_source_files))
|
||||
|
|
Loading…
Add table
Reference in a new issue