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