OpenCores
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] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
// 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"
9
#if 0 // linux && __GNUC__
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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.