aboutsummaryrefslogtreecommitdiff
path: root/libjava/java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/java')
-rw-r--r--libjava/java/lang/Throwable.java71
-rw-r--r--libjava/java/lang/natThrowable.cc95
2 files changed, 129 insertions, 37 deletions
diff --git a/libjava/java/lang/Throwable.java b/libjava/java/lang/Throwable.java
index 5ae39ae..faba2be 100644
--- a/libjava/java/lang/Throwable.java
+++ b/libjava/java/lang/Throwable.java
@@ -12,6 +12,7 @@ package java.lang;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.Serializable;
+import java.io.OutputStreamWriter;
/**
* @author Tom Tromey <tromey@cygnus.com>
@@ -26,55 +27,51 @@ import java.io.Serializable;
public class Throwable implements Serializable
{
- public Throwable fillInStackTrace ()
- {
- return this;
- }
+ public native Throwable fillInStackTrace ();
public String getLocalizedMessage ()
- {
- return getMessage ();
- }
+ {
+ return getMessage ();
+ }
public String getMessage ()
- {
- return detailMessage;
- }
+ {
+ return detailMessage;
+ }
public void printStackTrace ()
- {
- printStackTrace (System.err);
- }
-
- public void printStackTrace (PrintStream s)
- {
- // No stack trace, but we can still print this object.
- s.println(toString ());
- }
-
- public void printStackTrace (PrintWriter wr)
- {
- // No stack trace, but we can still print this object.
- wr.println(toString ());
- }
-
+ {
+ printStackTrace (System.err);
+ }
+
+ public void printStackTrace (PrintStream ps)
+ {
+ printStackTrace (new PrintWriter(new OutputStreamWriter(ps)));
+ }
+
+ public native void printStackTrace (PrintWriter wr);
+
public Throwable ()
- {
- detailMessage = null;
- }
+ {
+ detailMessage = null;
+ fillInStackTrace ();
+ }
public Throwable (String message)
- {
- detailMessage = message;
- }
+ {
+ detailMessage = message;
+ fillInStackTrace ();
+ }
public String toString ()
- {
- return ((detailMessage == null)
- ? getClass().getName()
- : getClass().getName() + ": " + getMessage ());
- }
+ {
+ return ((detailMessage == null)
+ ? getClass().getName()
+ : getClass().getName() + ": " + getMessage ());
+ }
// Name of this field comes from serialization spec.
private String detailMessage;
+
+ private byte stackTrace[];
}
diff --git a/libjava/java/lang/natThrowable.cc b/libjava/java/lang/natThrowable.cc
new file mode 100644
index 0000000..2227e7d
--- /dev/null
+++ b/libjava/java/lang/natThrowable.cc
@@ -0,0 +1,95 @@
+// natThrowable.cc - Superclass for all exceptions.
+
+/* Copyright (C) 2000 Red Hat Inc
+
+ 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. */
+
+/**
+ * @author Andrew Haley <aph@cygnus.com>
+ * @date Jan 6 2000
+ */
+
+#include <config.h>
+
+#include <string.h>
+
+#pragma implementation "Throwable.h"
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java/lang/Object.h>
+#include <java-threads.h>
+#include <java/lang/Throwable.h>
+#include <java/io/PrintStream.h>
+#include <java/io/PrintWriter.h>
+
+#include <sys/types.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <unistd.h>
+
+#ifdef HAVE_EXECINFO_H
+#include <execinfo.h>
+#endif
+
+#include <name-finder.h>
+
+/* FIXME: size of the stack trace is limited to 128 elements. It's
+ undoubtedly sensible to limit the stack trace, but 128 is rather
+ arbitrary. It may be better to configure this. */
+
+java::lang::Throwable *
+java::lang::Throwable::fillInStackTrace (void)
+{
+#ifdef HAVE_BACKTRACE
+ void *p[128];
+
+ // We subtract 1 from the number of elements because we don't want
+ // to include the call to fillInStackTrace in the trace.
+ int n = backtrace (p, 128) - 1;
+
+ // ??? Might this cause a problem if the byte array isn't aligned?
+ stackTrace = JvNewByteArray (n * sizeof p[0]);
+ memcpy (elements (stackTrace), p+1, (n * sizeof p[0]));
+
+ return this;
+#endif
+}
+
+void
+java::lang::Throwable::printStackTrace (java::io::PrintWriter *wr)
+{
+ wr->println (toString ());
+#ifdef HAVE_BACKTRACE
+ if (!stackTrace)
+ return;
+
+ void **p = (void **)elements (stackTrace);
+ int depth = stackTrace->length / sizeof p[0];
+
+ _Jv_name_finder finder (_Jv_ThisExecutable ());
+
+ for (int i = 0; i < depth; i++)
+ {
+ bool found = finder.lookup (p[i]);
+ wr->print (JvNewStringLatin1 (" at "));
+ wr->print (JvNewStringLatin1 (finder.hex));
+ if (found)
+ {
+ wr->print (JvNewStringLatin1 (": "));
+ wr->print (JvNewStringLatin1 (finder.method_name));
+ wr->print (JvNewStringLatin1 (" ("));
+ wr->print (JvNewStringLatin1 (finder.file_name));
+ wr->print (JvNewStringLatin1 (")"));
+ }
+ wr->println ();
+ }
+#endif /* HAVE_BACKTRACE */
+}
+