From 11948ddbe7c903a0483f43a06141bc9acda18fca Mon Sep 17 00:00:00 2001 From: twisti Date: Wed, 28 Mar 2007 13:29:09 +0000 Subject: [PATCH] * src/vm/exceptions.c (throw_exception_exit_intern): Removed. (throw_exception): Likewise. (throw_exception_exit): Likewise. (throw_main_exception): Likewise. (throw_main_exception_exit): Likewise. (throw_cacao_exception_exit): Likewise. (exceptions_print_stacktrace): New function. * src/vm/exceptions.h: Likewise. * src/vm/vm.c (vm_create): Use vm_abort or exceptions_print_stacktrace instead of throw_main_exception_exit. (vm_run): Likewise. (vm_exit): Likewise. (vm_get_mainclass_from_jar): Likewise. * src/threads/native/threads.c (threads_init): Use return instead of throw_exception_exit. (threads_startup_thread): Use vm_abort. --- src/threads/native/threads.c | 8 +- src/vm/exceptions.c | 207 +++++++++++++---------------------- src/vm/exceptions.h | 16 +-- src/vm/vm.c | 150 +++++++++++++++---------- src/vmcore/options.c | 2 +- src/vmcore/options.h | 2 +- 6 files changed, 174 insertions(+), 211 deletions(-) diff --git a/src/threads/native/threads.c b/src/threads/native/threads.c index 2eecb4cf1..5a83a152f 100644 --- a/src/threads/native/threads.c +++ b/src/threads/native/threads.c @@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: threads.c 7549 2007-03-21 13:27:14Z twisti $ + $Id: threads.c 7587 2007-03-28 13:29:09Z twisti $ */ @@ -823,7 +823,7 @@ bool threads_init(void) native_new_and_init(class_java_lang_ThreadGroup); if (threadgroup == NULL) - throw_exception_exit(); + return false; #endif #if defined(WITH_CLASSPATH_GNU) @@ -832,7 +832,7 @@ bool threads_init(void) vmt = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread); if (vmt == NULL) - throw_exception_exit(); + return false; /* set the thread */ @@ -1148,7 +1148,7 @@ static void *threads_startup_thread(void *t) m = class_resolveclassmethod(c, utf_run, utf_void__void, c, true); if (m == NULL) - throw_exception(); + vm_abort("threads_startup_thread: run() method not found in class"); /* set ThreadMXBean variables */ diff --git a/src/vm/exceptions.c b/src/vm/exceptions.c index 00a719fda..f0ea89d83 100644 --- a/src/vm/exceptions.c +++ b/src/vm/exceptions.c @@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: exceptions.c 7534 2007-03-16 23:00:18Z pm $ + $Id: exceptions.c 7587 2007-03-28 13:29:09Z twisti $ */ @@ -169,137 +169,6 @@ bool exceptions_init(void) } -static void throw_exception_exit_intern(bool doexit) -{ - java_objectheader *xptr; - classinfo *c; - methodinfo *pss; - - xptr = *exceptionptr; - - if (xptr) { - /* clear exception, because we are calling jit code again */ - *exceptionptr = NULL; - - c = xptr->vftbl->class; - - pss = class_resolveclassmethod(c, - utf_printStackTrace, - utf_void__void, - class_java_lang_Object, - false); - - /* print the stacktrace */ - - if (pss) { - (void) vm_call_method(pss, xptr); - - /* This normally means, we are EXTREMLY out of memory or have a */ - /* serious problem while printStackTrace. But may be another */ - /* exception, so print it. */ - - if (*exceptionptr) { - java_lang_Throwable *t; - - t = (java_lang_Throwable *) *exceptionptr; - - fprintf(stderr, "Exception while printStackTrace(): "); - utf_fprint_printable_ascii_classname(stderr, t->header.vftbl->class->name); - - if (t->detailMessage) { - char *buf; - - buf = javastring_tochar((java_objectheader *) t->detailMessage); - fprintf(stderr, ": %s", buf); - MFREE(buf, char, strlen(buf)); - } - - fprintf(stderr, "\n"); - } - - } else { - utf_fprint_printable_ascii_classname(stderr, c->name); - fprintf(stderr, ": printStackTrace()V not found!\n"); - } - - fflush(stderr); - - /* good bye! */ - - if (doexit) - exit(1); - } -} - - -void throw_exception(void) -{ - throw_exception_exit_intern(false); -} - - -void throw_exception_exit(void) -{ - throw_exception_exit_intern(true); -} - - -void throw_main_exception(void) -{ - fprintf(stderr, "Exception in thread \"main\" "); - fflush(stderr); - - throw_exception_exit_intern(false); -} - - -void throw_main_exception_exit(void) -{ - fprintf(stderr, "Exception in thread \"main\" "); - fflush(stderr); - - throw_exception_exit_intern(true); -} - - -void throw_cacao_exception_exit(const char *exception, const char *message, ...) -{ - s4 i; - char *tmp; - s4 len; - va_list ap; - - len = strlen(exception); - tmp = MNEW(char, len + 1); - strncpy(tmp, exception, len); - tmp[len] = '\0'; - - /* convert to classname */ - - for (i = len - 1; i >= 0; i--) - if (tmp[i] == '/') tmp[i] = '.'; - - fprintf(stderr, "Exception in thread \"main\" %s", tmp); - - MFREE(tmp, char, len); - - if (strlen(message) > 0) { - fprintf(stderr, ": "); - - va_start(ap, message); - vfprintf(stderr, message, ap); - va_end(ap); - } - - fprintf(stderr, "\n"); - fflush(stderr); - - /* good bye! */ - - exit(1); -} - - /* exceptions_new_class ******************************************************** Creates an exception object from the given class and initalizes it. @@ -1946,6 +1815,80 @@ void exceptions_print_current_exception(void) } +/* exceptions_print_stacktrace ************************************************* + + Prints a pending exception with Throwable.printStackTrace(). If + there happens an exception during printStackTrace(), we print the + thrown exception and the original one. + + NOTE: This function calls Java code. + +*******************************************************************************/ + +void exceptions_print_stacktrace(void) +{ + java_objectheader *oxptr; + java_objectheader *xptr; + classinfo *c; + methodinfo *m; + + /* get original exception */ + + oxptr = *exceptionptr; + + if (oxptr == NULL) + vm_abort("exceptions_print_stacktrace: no exception thrown"); + + /* clear exception, because we are calling jit code again */ + + *exceptionptr = NULL; + + c = oxptr->vftbl->class; + + /* find the printStackTrace() method */ + + m = class_resolveclassmethod(c, + utf_printStackTrace, + utf_void__void, + class_java_lang_Object, + false); + + if (m == NULL) + vm_abort("exceptions_print_stacktrace: printStackTrace()V not found"); + + /* print compatibility message */ + + fprintf(stderr, "Exception in thread \"main\" "); + + /* print the stacktrace */ + + (void) vm_call_method(m, oxptr); + + /* This normally means, we are EXTREMLY out of memory or + have a serious problem while printStackTrace. But may + be another exception, so print it. */ + + xptr = *exceptionptr; + + if (xptr != NULL) { + fprintf(stderr, "Exception while printStackTrace(): "); + + /* now print original exception */ + + exceptions_print_exception(xptr); + stacktrace_print_trace(xptr); + + /* now print original exception */ + + fprintf(stderr, "Original exception was: "); + exceptions_print_exception(oxptr); + stacktrace_print_trace(oxptr); + } + + fflush(stderr); +} + + /* * These are local overrides for various environment variables in Emacs. * Please do not remove this and leave it at the end of the file, where diff --git a/src/vm/exceptions.h b/src/vm/exceptions.h index c3539cb4c..557a33989 100644 --- a/src/vm/exceptions.h +++ b/src/vm/exceptions.h @@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: exceptions.h 7261 2007-01-31 10:00:12Z twisti $ + $Id: exceptions.h 7587 2007-03-28 13:29:09Z twisti $ */ @@ -65,19 +65,6 @@ /* load and link exceptions used in the system */ bool exceptions_init(void); - -/* exception throwing functions */ - -void throw_exception(void); -void throw_exception_exit(void); - -void throw_main_exception(void); -void throw_main_exception_exit(void); - -void throw_cacao_exception_exit(const char *exception, - const char *message, ...); - - /* initialize new exceptions */ java_objectheader *new_exception_utfmessage(const char *classname, @@ -141,6 +128,7 @@ java_objectheader *exceptions_get_and_clear_exception(void); void exceptions_print_exception(java_objectheader *xptr); void exceptions_print_current_exception(void); +void exceptions_print_stacktrace(void); #endif /* _EXCEPTIONS_H */ diff --git a/src/vm/vm.c b/src/vm/vm.c index e781fec15..e169b9b1e 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -1474,17 +1474,17 @@ bool vm_create(JavaVMInitArgs *vm_args) /* AFTER: threads_preinit */ if (!string_init()) - throw_main_exception_exit(); + vm_abort("vm_create: string_init failed"); /* AFTER: threads_preinit */ if (!utf8_init()) - throw_main_exception_exit(); + vm_abort("vm_create: utf8_init failed"); /* AFTER: thread_preinit */ if (!suck_init()) - throw_main_exception_exit(); + vm_abort("vm_create: suck_init failed"); suck_add_from_property("java.endorsed.dirs"); @@ -1508,25 +1508,25 @@ bool vm_create(JavaVMInitArgs *vm_args) _Jv_bootclasspath pointer. */ if (!properties_postinit()) - vm_abort("properties_postinit failed"); + vm_abort("vm_create: properties_postinit failed"); /* initialize the classcache hashtable stuff: lock, hashtable (must be done _after_ threads_preinit) */ if (!classcache_init()) - throw_main_exception_exit(); + vm_abort("vm_create: classcache_init failed"); /* initialize the memory subsystem (must be done _after_ threads_preinit) */ if (!memory_init()) - throw_main_exception_exit(); + vm_abort("vm_create: memory_init failed"); /* initialize the finalizer stuff (must be done _after_ threads_preinit) */ if (!finalizer_init()) - throw_main_exception_exit(); + vm_abort("vm_create: finalizer_init failed"); /* install architecture dependent signal handlers */ @@ -1557,19 +1557,19 @@ bool vm_create(JavaVMInitArgs *vm_args) classcache_init) */ if (!loader_init()) - vm_abort("loader_init failed"); + vm_abort("vm_create: loader_init failed"); if (!linker_init()) - vm_abort("linker_init failed"); + vm_abort("vm_create: linker_init failed"); if (!native_init()) - throw_main_exception_exit(); + vm_abort("vm_create: native_init failed"); if (!exceptions_init()) - throw_main_exception_exit(); + vm_abort("vm_create: exceptions_init failed"); if (!builtin_init()) - throw_main_exception_exit(); + vm_abort("vm_create: builtin_init failed"); #if defined(ENABLE_JNI) /* Initialize the JNI subsystem (must be done _before_ @@ -1577,57 +1577,57 @@ bool vm_create(JavaVMInitArgs *vm_args) (e.g. NewGlobalRef). */ if (!jni_init()) - throw_main_exception_exit(); + vm_abort("vm_create: jni_init failed"); #endif #if defined(ENABLE_THREADS) if (!threads_init()) - throw_main_exception_exit(); + vm_abort("vm_create: threads_init failed"); #endif #if defined(ENABLE_PROFILING) /* initialize profiling */ if (!profile_init()) - throw_main_exception_exit(); + vm_abort("vm_create: profile_init failed"); #endif #if defined(ENABLE_THREADS) /* initialize recompilation */ if (!recompile_init()) - throw_main_exception_exit(); + vm_abort("vm_create: recompile_init failed"); /* start the signal handler thread */ if (!signal_start_thread()) - throw_main_exception_exit(); + vm_abort("vm_create: signal_start_thread failed"); /* finally, start the finalizer thread */ if (!finalizer_start_thread()) - throw_main_exception_exit(); + vm_abort("vm_create: finalizer_start_thread failed"); # if !defined(NDEBUG) /* start the memory profiling thread */ if (opt_verbosememory) if (!memory_start_thread()) - throw_main_exception_exit(); + vm_abort("vm_create: memory_start_thread failed"); # endif /* start the recompilation thread (must be done before the profiling thread) */ if (!recompile_start_thread()) - throw_main_exception_exit(); + vm_abort("vm_create: recompile_start_thread failed"); # if defined(ENABLE_PROFILING) /* start the profile sampling thread */ /* if (opt_prof) */ /* if (!profile_start_thread()) */ -/* throw_main_exception_exit(); */ +/* exceptions_print_stacktrace(); */ # endif #endif @@ -1691,10 +1691,15 @@ void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args) status = 0; - if (opt_jar == true) + if (opt_jar == true) { /* open jar file with java.util.jar.JarFile */ + mainstring = vm_get_mainclass_from_jar(mainstring); + if (mainstring == NULL) + vm_exit(1); + } + /* load the main class */ mainutf = utf_new_char(mainstring); @@ -1707,11 +1712,15 @@ void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args) /* error loading class */ - if ((exceptions_get_exception() != NULL) || (mainclass == NULL)) - throw_main_exception_exit(); + if ((exceptions_get_exception() != NULL) || (mainclass == NULL)) { + exceptions_print_stacktrace(); + vm_exit(1); + } - if (!link_class(mainclass)) - throw_main_exception_exit(); + if (!link_class(mainclass)) { + exceptions_print_stacktrace(); + vm_exit(1); + } /* find the `main' method of the main class */ @@ -1721,8 +1730,9 @@ void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args) class_java_lang_Object, false); - if (*exceptionptr) { - throw_main_exception_exit(); + if (exceptions_get_exception()) { + exceptions_print_stacktrace(); + vm_exit(1); } /* there is no main method or it isn't static */ @@ -1733,7 +1743,8 @@ void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args) utf_new_char("main"), utf_new_char("([Ljava/lang/String;)V")); - throw_main_exception_exit(); + exceptions_print_stacktrace(); + vm_exit(1); } /* build argument array */ @@ -1775,14 +1786,14 @@ void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args) /* exception occurred? */ - if (*exceptionptr) { - throw_main_exception(); + if (exceptions_get_exception()) { + exceptions_print_stacktrace(); status = 1; } /* unload the JavaVM */ - vm_destroy(vm); + (void) vm_destroy(vm); /* and exit */ @@ -1832,8 +1843,10 @@ void vm_exit(s4 status) } #endif - if (!link_class(class_java_lang_System)) - throw_main_exception_exit(); + if (!link_class(class_java_lang_System)) { + exceptions_print_stacktrace(); + exit(1); + } /* call java.lang.System.exit(I)V */ @@ -1843,8 +1856,10 @@ void vm_exit(s4 status) class_java_lang_Object, true); - if (m == NULL) - throw_main_exception_exit(); + if (m == NULL) { + exceptions_print_stacktrace(); + exit(1); + } /* call the exit function with passed exit status */ @@ -1993,16 +2008,19 @@ static char *vm_get_mainclass_from_jar(char *mainstring) c = load_class_from_sysloader(utf_new_char("java/util/jar/JarFile")); - if (c == NULL) - throw_main_exception_exit(); - + if (c == NULL) { + exceptions_print_stacktrace(); + return NULL; + } + /* create JarFile object */ o = builtin_new(c); - if (o == NULL) - throw_main_exception_exit(); - + if (o == NULL) { + exceptions_print_stacktrace(); + return NULL; + } m = class_resolveclassmethod(c, utf_init, @@ -2010,15 +2028,19 @@ static char *vm_get_mainclass_from_jar(char *mainstring) class_java_lang_Object, true); - if (m == NULL) - throw_main_exception_exit(); + if (m == NULL) { + exceptions_print_stacktrace(); + return NULL; + } s = javastring_new_from_ascii(mainstring); (void) vm_call_method(m, o, s); - if (*exceptionptr) - throw_main_exception_exit(); + if (exceptions_get_exception()) { + exceptions_print_stacktrace(); + return NULL; + } /* get manifest object */ @@ -2028,14 +2050,16 @@ static char *vm_get_mainclass_from_jar(char *mainstring) class_java_lang_Object, true); - if (m == NULL) - throw_main_exception_exit(); + if (m == NULL) { + exceptions_print_stacktrace(); + return NULL; + } o = vm_call_method(m, o); if (o == NULL) { fprintf(stderr, "Could not get manifest from %s (invalid or corrupt jarfile?)\n", mainstring); - vm_exit(1); + return NULL; } @@ -2047,14 +2071,16 @@ static char *vm_get_mainclass_from_jar(char *mainstring) class_java_lang_Object, true); - if (m == NULL) - throw_main_exception_exit(); + if (m == NULL) { + exceptions_print_stacktrace(); + return NULL; + } o = vm_call_method(m, o); if (o == NULL) { fprintf(stderr, "Could not get main attributes from %s (invalid or corrupt jarfile?)\n", mainstring); - vm_exit(1); + return NULL; } @@ -2066,15 +2092,19 @@ static char *vm_get_mainclass_from_jar(char *mainstring) class_java_lang_Object, true); - if (m == NULL) - throw_main_exception_exit(); + if (m == NULL) { + exceptions_print_stacktrace(); + return NULL; + } s = javastring_new_from_ascii("Main-Class"); o = vm_call_method(m, o, s); - if (o == NULL) - throw_main_exception_exit(); + if (o == NULL) { + exceptions_print_stacktrace(); + return NULL; + } return javastring_tochar(o); } @@ -2171,11 +2201,13 @@ static void vm_compile_method(void) /* create, load and link the main class */ - if (!(mainclass = load_class_bootstrap(utf_new_char(mainstring)))) - throw_main_exception_exit(); + mainclass = load_class_bootstrap(utf_new_char(mainstring)); + + if (mainclass == NULL) + exceptions_print_stacktrace(); if (!link_class(mainclass)) - throw_main_exception_exit(); + exceptions_print_stacktrace(); if (opt_signature != NULL) { m = class_resolveclassmethod(mainclass, diff --git a/src/vmcore/options.c b/src/vmcore/options.c index e422fedcd..1bc4a9b91 100644 --- a/src/vmcore/options.c +++ b/src/vmcore/options.c @@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: options.c 7486 2007-03-08 13:50:07Z twisti $ + $Id: options.c 7450 2007-03-04 19:13:29Z edwin $ */ diff --git a/src/vmcore/options.h b/src/vmcore/options.h index c291daa07..37210caed 100644 --- a/src/vmcore/options.h +++ b/src/vmcore/options.h @@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: options.h 7486 2007-03-08 13:50:07Z twisti $ + $Id: options.h 7450 2007-03-04 19:13:29Z edwin $ */ -- 2.25.1