Mercurial > ecos
view packages/language/cxx/ustl/current/src/bktrace.cpp @ 2904:88af52c64ce4
* ecos.db: Add uSTL library package record.
* language/cxx/ustl/*: Initial check-in of the port of uSTL 1.3 to eCos
contributed by Uwe Kindler.
| author | jld |
|---|---|
| date | Thu, 20 Aug 2009 17:00:30 +0000 |
| parents | |
| children | 9e1cb7863bef |
line wrap: on
line source
// 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 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
