home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Geek Gadgets 1
/
ADE-1.bin
/
ade-dist
/
kaffe-0.5p4-src.tgz
/
tar.out
/
contrib
/
kaffe
/
kaffevm
/
jit
/
exception.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-09-28
|
6KB
|
252 lines
/*
* exception.c
* Handle exceptions for the translator.
*
* Copyright (c) 1996 Systems Architecture Research Centre,
* City University, London, UK.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* Written by Tim Wilkinson <tim@sarc.city.ac.uk>, June 1996.
*/
#include "config.h"
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <signal.h>
#include "gtypes.h"
#include "access.h"
#include "object.h"
#include "constants.h"
#include "classMethod.h"
#include "exception.h"
#include "baseClasses.h"
#include "lookup.h"
#include "thread.h"
#include "itypes.h"
#include "md.h"
object* ClassFormatError;
object* LinkageError;
object* ClassNotFoundException;
object* NoSuchFieldError;
object* NoSuchMethodError;
object* OutOfMemoryError;
object* UnsatisfiedLinkError;
object* VirtualMachineError;
object* ClassCircularityError;
object* NegativeArraySizeException;
object* ClassCastException;
object* IllegalMonitorStateException;
object* NullPointerException;
object* ArithmeticException;
object* ArrayIndexOutOfBoundsException;
extern object* exceptionObject;
static void dispatchException(throwable*, exceptionFrame*);
static void nullException(EXCEPTIONPROTO);
static void arithmeticException(EXCEPTIONPROTO);
object* buildStackTrace(exceptionFrame*);
/*
* Setup the internal exceptions.
*/
void
initExceptions(void)
{
#define EXCEPTION(s) alloc_object(lookupClass(addString(#s)), true)
ClassFormatError = EXCEPTION(java/lang/ClassFormatError);
LinkageError = EXCEPTION(java/lang/LinkageError);
ClassNotFoundException = EXCEPTION(java/lang/ClassNotFoundException);
NoSuchFieldError = EXCEPTION(java/lang/NoSuchFieldError);
NoSuchMethodError = EXCEPTION(java/lang/NoSuchMethodError);
OutOfMemoryError = EXCEPTION(java/lang/OutOfMemoryError);
UnsatisfiedLinkError = EXCEPTION(java/lang/UnsatisfiedLinkError);
VirtualMachineError = EXCEPTION(java/lang/VirtualMachineError);
ClassCircularityError = EXCEPTION(java/lang/ClassCircularityError);
NegativeArraySizeException = EXCEPTION(java/lang/NegativeArraySizeException);
ClassCastException = EXCEPTION(java/lang/ClassCastException);
IllegalMonitorStateException = EXCEPTION(java/lang/IllegalMonitorStateException);
NullPointerException = EXCEPTION(java/lang/NullPointerException);
ArithmeticException = EXCEPTION(java/lang/ArithmeticException);
ArrayIndexOutOfBoundsException = EXCEPTION(java/lang/ArrayIndexOutOfBoundsException);
initClasses();
#if !defined(DEBUG)
/* Catch signal we need to convert to exceptions */
#if defined(SIGSEGV)
signal(SIGSEGV, (SIG_T)nullException);
#endif
#if defined(SIGBUS)
signal(SIGBUS, (SIG_T)nullException);
#endif
#if defined(SIGFPE)
signal(SIGFPE, (SIG_T)arithmeticException);
#endif
#if defined(SIGPIPE)
signal(SIGPIPE, SIG_IGN);
#endif
#endif
}
/*
* Throw an internal exception.
*/
void
throwException(object* eobj)
{
((throwable*)eobj)->backtrace = buildStackTrace(0);
throwExternalException(eobj);
}
/*
* Throw an external exception.
*/
void
throwExternalException(object* eobj)
{
exceptionFrame frame;
if (eobj == 0) {
fprintf(stderr, "Exception thrown on null object ... aborting\n");
abort();
exit(1);
}
FIRSTFRAME(frame, eobj);
dispatchException((throwable*)eobj, &frame);
}
/*
* Search for a matching exception.
*/
static
void
dispatchException(throwable* eobj, exceptionFrame* baseframe)
{
exceptionInfo einfo;
classes* class;
exceptionFrame* frame;
object* str;
int i;
class = eobj->head.dtable->class;
for (frame = baseframe; FRAMEOKAY(frame); frame = NEXTFRAME(frame)) {
findExceptionInMethod(PCFRAME(frame), class, &einfo);
if (einfo.handler != 0) {
CALL_KAFFE_EXCEPTION(frame, einfo, eobj);
}
}
fprintf(stderr, "%s\n", eobj->head.dtable->class->name);
fflush(stderr);
if (eobj->backtrace != 0) {
for (i = 0; i < eobj->backtrace->size; i++) {
str = ((object**)(eobj->backtrace+1))[i];
if (str != 0) {
fprintf(stderr, "%s\n", (char*)(str+1));
}
}
}
else {
fprintf(stderr, "\t[no backtrace available]\n");
}
exit(1);
}
/*
* Build an array of char[] for the current stack backtrace.
*/
object*
buildStackTrace(exceptionFrame* base)
{
char buf[100];
exceptionFrame nframe;
exceptionFrame* frame;
methods* meth;
object* str;
object* strarray;
int cnt;
int i;
int len;
if (base == 0) {
FIRSTFRAME(nframe, base);
base = &nframe;
}
/* First count the stack frames */
cnt = 0;
for (frame = base; FRAMEOKAY(frame); frame = NEXTFRAME(frame)) {
cnt++;
}
/* Build an array of strings */
strarray = alloc_objectarray(cnt, "[[C");
assert(strarray != 0);
cnt = 0;
for (frame = base; FRAMEOKAY(frame); frame = NEXTFRAME(frame)) {
meth = findMethodFromPC(PCFRAME(frame));
if (meth != 0) {
sprintf(buf, "\tat %s.%s(0x%x)",
meth->class->name,
meth->pair->s1,
PCFRAME(frame));
len = strlen(buf);
str = alloc_array(len, TYPE_Char);
assert(str != 0);
strncpy((char*)(str+1), buf, len);
}
else {
str = 0;
}
((object**)(strarray+1))[cnt] = str;
cnt++;
}
return (strarray);
}
/*
* Null exception - catches bad memory accesses.
*/
static
void
nullException(EXCEPTIONPROTO)
{
exceptionFrame frame;
#if !defined(DEBUG)
/* Reset signal handler - necessary for SysV, does no harm for BSD */
signal(sig, (SIG_T)nullException);
#endif
EXCEPTIONFRAME(frame, ctx);
((throwable*)NullPointerException)->backtrace = buildStackTrace(&frame);
dispatchException((throwable*)NullPointerException, &frame);
}
/*
* Division by zero.
*/
static
void
arithmeticException(EXCEPTIONPROTO)
{
exceptionFrame frame;
#if !defined(DEBUG)
/* Reset signal handler - necessary for SysV, does no harm for BSD */
signal(sig, (SIG_T)arithmeticException);
#endif
EXCEPTIONFRAME(frame, ctx);
((throwable*)ArithmeticException)->backtrace = buildStackTrace(&frame);
dispatchException((throwable*)ArithmeticException, &frame);
}