Mercurial > ecos
annotate packages/language/cxx/ustl/current/src/bktrace.cpp @ 2910:9e1cb7863bef
* src/bktrace.cpp: prevent inclusion of host header <execinfo.h> (eCos builds
for Linux synthetic target).
* src/uexception.cpp:exception::read(): initialise local variable stmSize.
| author | jld |
|---|---|
| date | Mon, 24 Aug 2009 06:46:33 +0000 |
| parents | 88af52c64ce4 |
| children | 4885e0722884 |
| rev | line source |
|---|---|
| 2904 | 1 // This file is part of the uSTL library, an STL implementation. |
| 2 // | |
| 3 // Copyright (c) 2006-2009 by Mike Sharov <msharov@users.sourceforge.net> | |
| 4 // This file is free software, distributed under the MIT License. | |
| 5 | |
| 6 #include "bktrace.h" | |
| 7 #include "sostream.h" | |
| 8 #include "mistream.h" | |
|
2910
9e1cb7863bef
* src/bktrace.cpp: prevent inclusion of host header <execinfo.h> (eCos builds
jld
parents:
2904
diff
changeset
|
9 #if 0 // linux && __GNUC__ |
| 2904 | 10 #include <execinfo.h> |
| 11 #else | |
| 12 static inline int backtrace (void**, int) { return (0); } | |
| 13 static inline char** backtrace_symbols (void* const*, int) { return (NULL); } | |
| 14 #endif | |
| 15 | |
| 16 namespace ustl { | |
| 17 | |
| 18 /// Default constructor. The backtrace is obtained here. | |
| 19 CBacktrace::CBacktrace (void) throw() | |
| 20 : m_Symbols (NULL), | |
| 21 m_nFrames (0), | |
| 22 m_SymbolsSize (0) | |
| 23 { | |
| 24 m_nFrames = backtrace (VectorBlock (m_Addresses)); | |
| 25 GetSymbols(); | |
| 26 } | |
| 27 | |
| 28 /// Copy constructor. | |
| 29 CBacktrace::CBacktrace (const CBacktrace& v) throw() | |
| 30 : m_Symbols (NULL), | |
| 31 m_nFrames (0), | |
| 32 m_SymbolsSize (0) | |
| 33 { | |
| 34 operator= (v); | |
| 35 } | |
| 36 | |
| 37 /// Copy operator. | |
| 38 const CBacktrace& CBacktrace::operator= (const CBacktrace& v) throw() | |
| 39 { | |
| 40 memcpy (m_Addresses, v.m_Addresses, sizeof(m_Addresses)); | |
| 41 m_Symbols = strdup (v.m_Symbols); | |
| 42 m_nFrames = v.m_nFrames; | |
| 43 m_SymbolsSize = v.m_SymbolsSize; | |
| 44 return (*this); | |
| 45 } | |
| 46 | |
| 47 /// Converts a string returned by backtrace_symbols into readable form. | |
| 48 static size_t ExtractAbiName (const char* isym, char* nmbuf) throw() | |
| 49 { | |
| 50 // Prepare the demangled name, if possible | |
| 51 size_t nmSize = 0; | |
| 52 if (isym) { | |
| 53 // Copy out the name; the strings are: "file(function+0x42) [0xAddress]" | |
| 54 const char* mnStart = strchr (isym, '('); | |
| 55 if (++mnStart == (const char*)(1)) | |
| 56 mnStart = isym; | |
| 57 const char* mnEnd = strchr (isym, '+'); | |
| 58 const char* isymEnd = isym + strlen (isym); | |
| 59 if (!mnEnd) | |
| 60 mnEnd = isymEnd; | |
| 61 nmSize = min (size_t (distance (mnStart, mnEnd)), 255U); | |
| 62 memcpy (nmbuf, mnStart, nmSize); | |
| 63 } | |
| 64 nmbuf[nmSize] = 0; | |
| 65 // Demangle | |
| 66 demangle_type_name (nmbuf, 255U, &nmSize); | |
| 67 return (nmSize); | |
| 68 } | |
| 69 | |
| 70 /// Tries to get symbol information for the addresses. | |
| 71 void CBacktrace::GetSymbols (void) throw() | |
| 72 { | |
| 73 char** symbols = backtrace_symbols (m_Addresses, m_nFrames); | |
| 74 if (!symbols) | |
| 75 return; | |
| 76 char nmbuf [256]; | |
| 77 size_t symSize = 1; | |
| 78 for (uoff_t i = 0; i < m_nFrames; ++ i) | |
| 79 symSize += ExtractAbiName (symbols[i], nmbuf) + 1; | |
| 80 if ((m_Symbols = (char*) calloc (symSize, 1))) { | |
| 81 for (uoff_t i = 0; m_SymbolsSize < symSize - 1; ++ i) { | |
| 82 size_t sz = ExtractAbiName (symbols[i], nmbuf); | |
| 83 memcpy (m_Symbols + m_SymbolsSize, nmbuf, sz); | |
| 84 m_SymbolsSize += sz + 1; | |
| 85 m_Symbols [m_SymbolsSize - 1] = '\n'; | |
| 86 } | |
| 87 } | |
| 88 free (symbols); | |
| 89 } | |
| 90 | |
| 91 #if SIZE_OF_LONG == 8 | |
| 92 #define ADDRESS_FMT "%16p " | |
| 93 #else | |
| 94 #define ADDRESS_FMT "%8p " | |
| 95 #endif | |
| 96 | |
| 97 /// Prints the backtrace to \p os. | |
| 98 void CBacktrace::text_write (ostringstream& os) const | |
| 99 { | |
| 100 const char *ss = m_Symbols, *se; | |
| 101 for (uoff_t i = 0; i < m_nFrames; ++ i) { | |
| 102 os.format (ADDRESS_FMT, m_Addresses[i]); | |
| 103 se = strchr (ss, '\n') + 1; | |
| 104 os.write (ss, distance (ss, se)); | |
| 105 ss = se; | |
| 106 } | |
| 107 } | |
| 108 | |
| 109 /// Reads the object from stream \p is. | |
| 110 void CBacktrace::read (istream& is) | |
| 111 { | |
| 112 assert (is.aligned (alignof (m_Addresses[0])) && "Backtrace object contains pointers and must be void* aligned"); | |
| 113 is >> m_nFrames >> m_SymbolsSize; | |
| 114 nfree (m_Symbols); | |
| 115 m_Symbols = (char*) malloc (m_SymbolsSize + 1); | |
| 116 is.read (m_Symbols, m_SymbolsSize); | |
| 117 m_Symbols [m_SymbolsSize] = 0; | |
| 118 is.align(); | |
| 119 is.read (m_Addresses, m_nFrames * sizeof(void*)); | |
| 120 } | |
| 121 | |
| 122 /// Writes the object to stream \p os. | |
| 123 void CBacktrace::write (ostream& os) const | |
| 124 { | |
| 125 assert (os.aligned (alignof (m_Addresses[0])) && "Backtrace object contains pointers and must be void* aligned"); | |
| 126 os << m_nFrames << m_SymbolsSize; | |
| 127 os.write (m_Symbols, m_SymbolsSize); | |
| 128 os.align(); | |
| 129 os.write (m_Addresses, m_nFrames * sizeof(void*)); | |
| 130 } | |
| 131 | |
| 132 /// Returns the size of the written object. | |
| 133 size_t CBacktrace::stream_size (void) const | |
| 134 { | |
| 135 return (Align (stream_size_of (m_nFrames) + | |
| 136 stream_size_of (m_SymbolsSize) + | |
| 137 m_nFrames * sizeof(void*) + | |
| 138 m_SymbolsSize)); | |
| 139 } | |
| 140 | |
| 141 } // namespace ustl |
