From: Christian Thalinger Date: Mon, 18 Aug 2008 20:03:26 +0000 (-0400) Subject: * configure.ac (AC_CHECK_HEADERS): Added execinfo.h. X-Git-Url: http://wien.tomnetworks.com/gitweb/?p=cacao.git;a=commitdiff_plain;h=c7d5c92968f36d38301dfde11dc6a90111b418c8 * configure.ac (AC_CHECK_HEADERS): Added execinfo.h. (AC_CHECK_FUNCS): Added backtrace, and backtrace_symbols. * src/vm/os.cpp (os::print_backtrace): New function. * src/vm/os.hpp (os): Added backtrace, and backtrace_symbols. (os::backtrace): New function. (os::backtrace_symbols): Likewise. * src/vm/vm.cpp (VM::abort): Call os::print_backtrace(). (VM::abort_errnum): Likewise. --- diff --git a/configure.ac b/configure.ac index 9b773032c..685d4d4cd 100644 --- a/configure.ac +++ b/configure.ac @@ -254,6 +254,7 @@ AC_CHECK_HEADERS([stdint.h],, [AC_MSG_ERROR(cannot find stdint.h)]) dnl keep them alpha-sorted! AC_CHECK_HEADERS([assert.h]) AC_CHECK_HEADERS([errno.h]) +AC_CHECK_HEADERS([execinfo.h]) AC_CHECK_HEADERS([fcntl.h]) AC_CHECK_HEADERS([libgen.h]) AC_CHECK_HEADERS([netdb.h]) @@ -304,6 +305,8 @@ AC_CHECK_FUNCS([accept]) AC_CHECK_FUNCS([access]) AC_CHECK_FUNCS([atoi]) AC_CHECK_FUNCS([atol]) +AC_CHECK_FUNCS([backtrace]) +AC_CHECK_FUNCS([backtrace_symbols]) AC_CHECK_FUNCS([calloc]) AC_CHECK_FUNCS([close]) AC_CHECK_FUNCS([confstr]) diff --git a/src/vm/os.cpp b/src/vm/os.cpp index 6eaf41f86..b5e8592ae 100644 --- a/src/vm/os.cpp +++ b/src/vm/os.cpp @@ -2,6 +2,7 @@ Copyright (C) 2007, 2008 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO + Copyright (C) 2008 Theobroma Systems Ltd. This file is part of CACAO. @@ -100,6 +101,30 @@ void* os::mmap_anonymous(void *addr, size_t len, int prot, int flags) } +/** + * Print a C backtrace. + */ +void os::print_backtrace() +{ +#define BACKTRACE_SIZE 100 + void** array = new void*[SIZEOF_VOID_P * BACKTRACE_SIZE]; + + // Get the backtrace. + int size = backtrace(array, BACKTRACE_SIZE); + + // Resolve the symbols. + char** strings = backtrace_symbols(array, size); + + log_println("Backtrace (%d stack frames):", size); + + for (int i = 0; i < size; i++) + log_println("%s", strings[i]); + + // We have to free the strings. + free(strings); +} + + /** * Returns the number of online processors in the system. * diff --git a/src/vm/os.hpp b/src/vm/os.hpp index 7ee25a8f1..3abb67211 100644 --- a/src/vm/os.hpp +++ b/src/vm/os.hpp @@ -2,6 +2,7 @@ Copyright (C) 2007, 2008 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO + Copyright (C) 2008 Theobroma Systems Ltd. This file is part of CACAO. @@ -43,6 +44,10 @@ # include #endif +#if defined(HAVE_EXECINFO_H) +# include +#endif + #if defined(HAVE_FCNTL_H) # include #endif @@ -104,6 +109,8 @@ public: static inline int accept(int sockfd, struct sockaddr* addr, socklen_t* addrlen); static inline int access(const char *pathname, int mode); static inline int atoi(const char* nptr); + static inline int backtrace(void** array, int size); + static inline char** backtrace_symbols(void* const* array, int size) throw (); static inline void* calloc(size_t nmemb, size_t size); static inline int close(int fd); static inline int connect(int sockfd, const struct sockaddr* serv_addr, socklen_t addrlen); @@ -141,8 +148,10 @@ public: static inline size_t strlen(const char* s); static inline char* strerror(int errnum); + // Convenience functions. static void* mmap_anonymous(void *addr, size_t len, int prot, int flags); - static int processors_online(void); + static void print_backtrace(); + static int processors_online(); }; @@ -182,6 +191,26 @@ inline int os::atoi(const char* nptr) #endif } +inline int os::backtrace(void** array, int size) +{ +#if defined(HAVE_BACKTRACE) + return ::backtrace(array, size); +#else + log_println("os::backtrace: Not available."); + return 0; +#endif +} + +inline char** os::backtrace_symbols(void* const* array, int size) throw () +{ +#if defined(HAVE_BACKTRACE_SYMBOLS) + return ::backtrace_symbols(array, size); +#else + log_println("os::backtrace_symbols: Not available."); + return NULL; +#endif +} + inline void* os::calloc(size_t nmemb, size_t size) { #if defined(HAVE_CALLOC) diff --git a/src/vm/vm.cpp b/src/vm/vm.cpp index a3d6f1554..29c721b01 100644 --- a/src/vm/vm.cpp +++ b/src/vm/vm.cpp @@ -2043,6 +2043,9 @@ void VM::abort(const char* text, ...) log_finish(); + // Print a backtrace. + os::print_backtrace(); + // Now abort the VM. os::abort(); } @@ -2071,6 +2074,9 @@ void VM::abort_errnum(int errnum, const char* text, ...) log_finish(); + // Print a backtrace. + os::print_backtrace(); + // Now abort the VM. os::abort(); }