URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [language/] [cxx/] [ustl/] [current/] [src/] [bktrace.cpp] - Rev 786
Compare with Previous | Blame | View Log
// This file is part of the uSTL library, an STL implementation. // // Copyright (c) 2006-2009 by Mike Sharov <msharov@users.sourceforge.net> // This file is free software, distributed under the MIT License. #include "bktrace.h" #include "sostream.h" #include "mistream.h" #if 0 // linux && __GNUC__ #include <execinfo.h> #else static inline int backtrace (void**, int) { return (0); } static inline char** backtrace_symbols (void* const*, int) { return (NULL); } #endif namespace ustl { /// Default constructor. The backtrace is obtained here. CBacktrace::CBacktrace (void) throw() : m_Symbols (NULL), m_nFrames (0), m_SymbolsSize (0) { m_nFrames = backtrace (VectorBlock (m_Addresses)); GetSymbols(); } /// Copy constructor. CBacktrace::CBacktrace (const CBacktrace& v) throw() : m_Symbols (NULL), m_nFrames (0), m_SymbolsSize (0) { operator= (v); } /// Copy operator. const CBacktrace& CBacktrace::operator= (const CBacktrace& v) throw() { memcpy (m_Addresses, v.m_Addresses, sizeof(m_Addresses)); m_Symbols = strdup (v.m_Symbols); m_nFrames = v.m_nFrames; m_SymbolsSize = v.m_SymbolsSize; return (*this); } /// Converts a string returned by backtrace_symbols into readable form. static size_t ExtractAbiName (const char* isym, char* nmbuf) throw() { // Prepare the demangled name, if possible size_t nmSize = 0; if (isym) { // Copy out the name; the strings are: "file(function+0x42) [0xAddress]" const char* mnStart = strchr (isym, '('); if (++mnStart == (const char*)(1)) mnStart = isym; const char* mnEnd = strchr (isym, '+'); const char* isymEnd = isym + strlen (isym); if (!mnEnd) mnEnd = isymEnd; nmSize = min (size_t (distance (mnStart, mnEnd)), 255U); memcpy (nmbuf, mnStart, nmSize); } nmbuf[nmSize] = 0; // Demangle demangle_type_name (nmbuf, 255U, &nmSize); return (nmSize); } /// Tries to get symbol information for the addresses. void CBacktrace::GetSymbols (void) throw() { char** symbols = backtrace_symbols (m_Addresses, m_nFrames); if (!symbols) return; char nmbuf [256]; size_t symSize = 1; for (uoff_t i = 0; i < m_nFrames; ++ i) symSize += ExtractAbiName (symbols[i], nmbuf) + 1; if ((m_Symbols = (char*) calloc (symSize, 1))) { for (uoff_t i = 0; m_SymbolsSize < symSize - 1; ++ i) { size_t sz = ExtractAbiName (symbols[i], nmbuf); memcpy (m_Symbols + m_SymbolsSize, nmbuf, sz); m_SymbolsSize += sz + 1; m_Symbols [m_SymbolsSize - 1] = '\n'; } } free (symbols); } #if SIZE_OF_LONG == 8 #define ADDRESS_FMT "%16p " #else #define ADDRESS_FMT "%8p " #endif /// Prints the backtrace to \p os. void CBacktrace::text_write (ostringstream& os) const { const char *ss = m_Symbols, *se; for (uoff_t i = 0; i < m_nFrames; ++ i) { os.format (ADDRESS_FMT, m_Addresses[i]); se = strchr (ss, '\n') + 1; os.write (ss, distance (ss, se)); ss = se; } } /// Reads the object from stream \p is. void CBacktrace::read (istream& is) { assert (is.aligned (alignof (m_Addresses[0])) && "Backtrace object contains pointers and must be void* aligned"); is >> m_nFrames >> m_SymbolsSize; nfree (m_Symbols); m_Symbols = (char*) malloc (m_SymbolsSize + 1); is.read (m_Symbols, m_SymbolsSize); m_Symbols [m_SymbolsSize] = 0; is.align(); is.read (m_Addresses, m_nFrames * sizeof(void*)); } /// Writes the object to stream \p os. void CBacktrace::write (ostream& os) const { assert (os.aligned (alignof (m_Addresses[0])) && "Backtrace object contains pointers and must be void* aligned"); os << m_nFrames << m_SymbolsSize; os.write (m_Symbols, m_SymbolsSize); os.align(); os.write (m_Addresses, m_nFrames * sizeof(void*)); } /// Returns the size of the written object. size_t CBacktrace::stream_size (void) const { return (Align (stream_size_of (m_nFrames) + stream_size_of (m_SymbolsSize) + m_nFrames * sizeof(void*) + m_SymbolsSize)); } } // namespace ustl