From 2247690faa2898f6f60099e5ecd82b21d62ba329 Mon Sep 17 00:00:00 2001 From: Michael Andres Date: Wed, 31 Oct 2012 15:00:14 +0100 Subject: [PATCH] Add zypp::dumpBacktrace to dump current stack trace to a stream. --- CMakeLists.txt | 4 +- zypp/CMakeLists.txt | 2 + zypp/base/Backtrace.cc | 100 +++++++++++++++++++++++++++++++++++++++++++++++++ zypp/base/Backtrace.h | 36 ++++++++++++++++++ 4 files changed, 140 insertions(+), 2 deletions(-) create mode 100644 zypp/base/Backtrace.cc create mode 100644 zypp/base/Backtrace.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 587f154..dd2fc2c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,8 +29,8 @@ include(CheckCXXCompilerFlag) CHECK_C_COMPILER_FLAG("-Werror=format-security" CC_FORMAT_SECURITY) CHECK_CXX_COMPILER_FLAG("-Werror=format-security" CXX_FORMAT_SECURITY) -SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden -fno-strict-aliasing -fPIC -g -Wall -Woverloaded-virtual -Wnon-virtual-dtor -Wl,-as-needed -std=c++0x" ) -SET( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-strict-aliasing -fPIC -g -Wall -Wl,-as-needed" ) +SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden -fno-strict-aliasing -fPIC -g -rdynamic -Wall -Woverloaded-virtual -Wnon-virtual-dtor -Wl,-as-needed -std=c++0x" ) +SET( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-strict-aliasing -fPIC -g -rdynamic -Wall -Wl,-as-needed" ) set( CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS} -O3" ) set( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -O3" ) diff --git a/zypp/CMakeLists.txt b/zypp/CMakeLists.txt index cac4aee..fe78e42 100644 --- a/zypp/CMakeLists.txt +++ b/zypp/CMakeLists.txt @@ -191,6 +191,7 @@ INSTALL( FILES ${zypp_HEADERS} DESTINATION "${CMAKE_INSTALL_PREFIX}/include/zyp SET( zypp_base_SRCS base/InterProcessMutex.cc + base/Backtrace.cc base/SerialNumber.cc base/Random.cc base/Measure.cc @@ -215,6 +216,7 @@ SET( zypp_base_SRCS SET( zypp_base_HEADERS base/InterProcessMutex.h + base/Backtrace.h base/Collector.h base/SerialNumber.h base/Easy.h diff --git a/zypp/base/Backtrace.cc b/zypp/base/Backtrace.cc new file mode 100644 index 0000000..6bee0cf --- /dev/null +++ b/zypp/base/Backtrace.cc @@ -0,0 +1,100 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ +/** \file zypp/base/Backtrace.cc + */ +#include +#include + +#include +#include "zypp/base/LogTools.h" +#include "zypp/base/String.h" +#include "zypp/base/Backtrace.h" + +using std::endl; + +/////////////////////////////////////////////////////////////////// +namespace zypp +{ + std::ostream & dumpBacktrace( std::ostream & stream_r ) + { + // get void*'s for all entries on the stack + static const size_t arraySize = 50; + void *array[arraySize]; + size_t size = ::backtrace( array, arraySize ); + + // print out all the frames to stderr + char ** messages = ::backtrace_symbols( array, size ); + if ( messages ) + { + static const size_t first = 1; + for ( size_t i = first; i < size; ++i ) + { + char * mangled_name = 0; + char * offset_begin = 0; + char * offset_end = 0; + + // find parantheses and +address offset surrounding mangled name + for ( char * p = messages[i]; *p; ++p ) + { + if ( *p == '(' ) + { + mangled_name = p; + } + else if ( *p == '+' ) + { + offset_begin = p; + } + else if ( *p == ')' ) + { + offset_end = p; + break; + } + } + + if ( i > first ) + stream_r << endl; + + // if the line could be processed, attempt to demangle the symbol + if ( mangled_name && offset_begin && offset_end && mangled_name < offset_begin ) + { + *mangled_name++ = '\0'; + *offset_begin++ = '\0'; + *offset_end++ = '\0'; + + int status; + char * real_name = ::abi::__cxa_demangle( mangled_name, 0, 0, &status ); + + // if demangling is successful, output the demangled function name + if ( status == 0 ) + { + stream_r << "[bt]: (" << i << ") " << messages[i] << " : " + << real_name << "+" << offset_begin << offset_end; + + } + // otherwise, output the mangled function name + else + { + stream_r << "[bt]: (" << i << ") " << messages[i] << " : " + << mangled_name << "+" << offset_begin << offset_end; + } + ::free( real_name ); + } + else + { + // otherwise, print the whole line + stream_r << "[bt]: (" << i << ") " << messages[i]; + } + } + ::free( messages ); + } + return stream_r; + } + +} // namespace zypp +/////////////////////////////////////////////////////////////////// diff --git a/zypp/base/Backtrace.h b/zypp/base/Backtrace.h new file mode 100644 index 0000000..b94a9ef --- /dev/null +++ b/zypp/base/Backtrace.h @@ -0,0 +1,36 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ +/** \file zypp/base/Backtrace.h + */ +#ifndef ZYPP_BASE_BACKTRACE_H +#define ZYPP_BASE_BACKTRACE_H + +#include +#include + +/////////////////////////////////////////////////////////////////// +namespace zypp +{ + + /** Dump current stack trace to a stream. + * Thanks to http://stackoverflow.com/questions/77005. + * \code + * #include + * std::cerr << zypp::dumpBacktrace << std::endl; + * \endcode + * \code + * #include + * std::string trace( str::Str() << zypp::dumpBacktrace ); + * \endcode + */ + std::ostream & dumpBacktrace( std::ostream & stream_r ); + +} // namespace zypp +/////////////////////////////////////////////////////////////////// +#endif // ZYPP_BASE_BACKTRACE_H -- 2.7.4