classpath
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: exceptions patch (fixed!)


From: Petter Reinholdtsen
Subject: Re: exceptions patch (fixed!)
Date: Tue, 05 Dec 2000 19:16:14 +0100

[Brian Jones]
> I'm mostly concerned about how I've had to assume the stream class
> is either PrintStream or PrintWriter rather than just being able to
> ask for a println method on whatever object I'm passed.  Then there
> is the question of memory usage and whether or not I've created any
> sort of leak.  Finally should I do anything in particular to try to
> prevent throwing an exception while printing an exception's
> backtrace?

I had a look, and could not see anything obvious wrong with your
patch.  I removed some redundant code, and made sure the lines stay
shorter then 80 characters.  Could you please verify this patch?

As for your questions, I do not remember enough JNI and Japhar code to
give any authorative answers.  The code seems OK, and if my new
suggestions still work, I'll commit it.  (Or, parhaps you want to do
it yourself? :-)

Index: include/runtime.h
===================================================================
RCS file: /cvsroot/hungry/java/japhar/include/runtime.h,v
retrieving revision 1.11
diff -u -r1.11 runtime.h
--- runtime.h   2000/08/05 01:54:46     1.11
+++ runtime.h   2000/12/05 18:05:56
@@ -428,6 +428,11 @@
 HVM_ExceptionPrintBacktrace(HungryEnv *henv, japhar_object* throwable_ref);
 
 PR_EXTERN( void )
+HVM_ExceptionPrintBacktraceToStream(HungryEnv *henv,
+                                    japhar_object* throwable_ref,
+                                    japhar_object* stream);
+
+PR_EXTERN( void )
 HVM_ExceptionFillInBacktraceFromStack(HungryEnv *henv,
                                       japhar_object* throwable_ref);
 
Index: lib/libnative/java.lang/throwable.c
===================================================================
RCS file: /cvsroot/hungry/java/japhar/lib/libnative/java.lang/throwable.c,v
retrieving revision 1.19
diff -u -r1.19 throwable.c
--- throwable.c 1999/10/25 07:10:19     1.19
+++ throwable.c 2000/12/05 18:05:57
@@ -35,7 +35,7 @@
                                          jobject printwriter_stream)
 {
   HungryEnv *henv = HVM_ThreadGetEnv();
-  HVM_ExceptionPrintBacktrace(henv, throwable);
+  HVM_ExceptionPrintBacktraceToStream(henv, throwable, printwriter_stream);
 }
 
 JNIEXPORT jobject JNICALL
Index: lib/libruntime/exceptions.c
===================================================================
RCS file: /cvsroot/hungry/java/japhar/lib/libruntime/exceptions.c,v
retrieving revision 1.58
diff -u -r1.58 exceptions.c
--- exceptions.c        2000/12/05 17:56:53     1.58
+++ exceptions.c        2000/12/05 18:05:58
@@ -63,8 +63,17 @@
 PR_IMPLEMENT(void)
 HVM_ExceptionPrintBacktrace(HungryEnv *henv, japhar_object* throwable_ref)
 {
-  ClazzFile *throwable_class;
-  MethodStruct *getMessage;
+  HVM_ExceptionPrintBacktraceToStream(henv, throwable_ref,
+                                      (japhar_object*)NULL);
+}
+
+PR_IMPLEMENT(void)
+HVM_ExceptionPrintBacktraceToStream(HungryEnv *henv,
+                                    japhar_object* throwable_ref,
+                                    japhar_object* stream_ref)
+{
+  ClazzFile *throwable_class, *stream_class;
+  MethodStruct *getMessage, *println = NULL;
   japhar_object* msg = NULL;
   ClazzFile *exception_cf = throwable_ref->clazz;
   char *exceptionname = getClassName(env, exception_cf);
@@ -72,35 +81,34 @@
   ExceptionInfo *exc_info = HVM_ObjectGetNativeState(throwable_ref);
   BackTraceLevel *level;
   InterpValue msg_value;
+  char *msg_to_print;
+  japhar_object *msg_obj;
 
-  throwable_class = HVM_ClassFind(henv, java_lang_Throwable);
-
-  getMessage = HVM_MethodFind(henv, throwable_class,
-                              "getMessage",
-                              "()Ljava/lang/String;");
-
-  /*
-   * Cache exception and make sure the runtime don't think the call to
-   * getMessage failed
-   */
-  exception_cache = henv->_exception;
-  henv->_exception = NULL;
-
-  msg_value = HVM_MethodCallA(henv, getMessage, throwable_ref, NULL);
-  msg = msg_value.l;
-
-  /* Don't know what to do if the call fails.  Die a horrible death? */
-  PR_ASSERT(NULL == henv->_exception);
-  henv->_exception = exception_cache;
-
-  if (msg)
+  if (stream_ref != NULL)
     {
-      const char *msg_bytes = HVM_StringToCString(henv, msg);
+      ClazzFile *stream_clazz = HVM_ClassFind(henv, "java/io/PrintWriter");
+      PRBool pwriter = HVM_ObjectIsInstanceOf(henv, stream_ref, stream_clazz);
+      if (pwriter)
+        stream_class = HVM_ClassFind(henv, "java/io/PrintWriter");
+      else
+        stream_class = HVM_ClassFind(henv, "java/io/PrintStream");
 
-      fprintf (stderr, "%s (%s)\n", exceptionname, msg_bytes);
+      if (stream_class == NULL)
+        {
+          if (pwriter)
+            abort_with_message("ExceptionPrintBacktraceToStream could not "
+                               "find java/io/PrintWriter");
+          else
+            abort_with_message("ExceptionPrintBacktraceToStream could not "
+                               "find java/io/PrintStream");
+        }
+
+      println = HVM_MethodFind(henv, stream_class, "println",
+                               "(Ljava/lang/String;)V");
+      if (println == NULL)
+        abort_with_message("ExceptionPrintBacktraceToStream could not "
+                           "find method println");
     }
-  else
-    fprintf (stderr, "%s\n", exceptionname);
 
   level = exc_info->head;
   while (level)
@@ -108,27 +116,48 @@
       int line_number = method_pc_to_line_number(henv, level->method,
                                                  level->pc);
 
+      PR_ASSERT(NULL != level->method);
       if (level->method->access_flags & ACC_NATIVE)
-        fprintf (stderr, "        in %s.%s(%s%snative method)\n",
-                 level->classname,
-                 level->method->name,
-                 level->filename ? level->filename : "",
-                 level->filename ? ", " : "");
+        {
+          msg_to_print = PR_smprintf("        in %s.%s(%s%snative method)",
+                                     level->classname,
+                                     level->method->name,
+                                     level->filename ? level->filename : "",
+                                     level->filename ? ", " : "");
+        }
       else if (line_number == -1)
-        fprintf (stderr, "        in %s.%s(%s%spc = %d)\n",
-                 level->classname,
-                 level->method->name,
-                 level->filename ? level->filename : "",
-                 level->filename ? ", " : "",
-                 level->pc);
+        {
+          msg_to_print = PR_smprintf("        in %s.%s(%s%spc = %d)",
+                                     level->classname,
+                                     level->method->name,
+                                     level->filename ? level->filename : "",
+                                     level->filename ? ", " : "",
+                                     level->pc);
+        }
       else
-        fprintf (stderr, "        at %s.%s(%s%s%d, pc = %d)\n",
-                 level->classname,
-                 level->method->name,
-                 level->filename ? level->filename : "",
-                 level->filename ? ":" : "line ",
-                 line_number,
-                 level->pc);
+        {
+          msg_to_print = PR_smprintf("        at %s.%s(%s%s%d, pc = %d)",
+                                     level->classname,
+                                     level->method->name,
+                                     level->filename ? level->filename : "",
+                                     level->filename ? ":" : "line ",
+                                     line_number,
+                                     level->pc);
+        }
+
+      msg_obj = HVM_StringFromCString(henv, msg_to_print);
+      if (msg_obj == NULL)
+        abort_with_message("ExceptionPrintBacktraceToStream unable to "
+                           "allocate message");
+
+      if (println != NULL)
+        {
+          HVM_MethodCall(henv, println, stream_ref, msg_obj);
+        }
+      else
+        fprintf (stderr, "%s\n", msg_to_print);
+
+      PR_smprintf_free(msg_to_print);
 
       level = level->next;
     }
-- 
##>  Petter Reinholdtsen <##    | address@hidden
 O-  <SCRIPT Language="Javascript">window.close()</SCRIPT>
http://www.hungry.com/~pere/    | Go Mozilla, go! Go!



reply via email to

[Prev in Thread] Current Thread [Next in Thread]