// 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 * @date Jan 6 2000 */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_EXECINFO_H #include #endif #include #ifdef __ia64__ extern "C" int __ia64_backtrace (void **array, int size); #endif /* 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) || defined (__ia64__) 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. #if defined (__ia64__) int n = __ia64_backtrace (p, 128) - 1; #else int n = backtrace (p, 128) - 1; #endif if (n > 0) { // ??? 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])); } #endif return this; } void java::lang::Throwable::printRawStackTrace (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)); if (finder.file_name[0]) { wr->print (JvNewStringLatin1 (" (")); wr->print (JvNewStringLatin1 (finder.file_name)); wr->print (JvNewStringLatin1 (")")); } } wr->println (); } #endif /* HAVE_BACKTRACE */ wr->flush (); }