| // 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> | |
| #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 <java/io/IOException.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) | |
| { | |
| if (! trace_enabled) | |
| return this; | |
| #if defined (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; | |
| if (n > 0) | |
| { | |
| // We copy the array below to deal with alignment issues. | |
| stackTrace = JvNewByteArray (n * sizeof p[0]); | |
| memcpy (elements (stackTrace), p+1, (n * sizeof p[0])); | |
| } | |
| #endif | |
| return this; | |
| } | |
| void | |
| java::lang::Throwable::printRawStackTrace (java::io::PrintWriter *wr) | |
| { | |
| wr->println (toString ()); | |
| #ifdef HAVE_BACKTRACE | |
| if (!stackTrace) | |
| return; | |
| int depth = stackTrace->length / sizeof (void *); | |
| void *p[depth]; | |
| memcpy (p, elements (stackTrace), sizeof p); | |
| _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)); | |
| if (finder.file_name[0]) | |
| { | |
| wr->print (JvNewStringLatin1 (" (")); | |
| wr->print (JvNewStringLatin1 (finder.file_name)); | |
| wr->print (JvNewStringLatin1 (")")); | |
| } | |
| } | |
| wr->println (); | |
| } | |
| #endif /* HAVE_BACKTRACE */ | |
| wr->flush (); | |
| } |