source: icXML/icXML-devel/src/icxmlc/backtrace.h @ 2720

Last change on this file since 2720 was 2720, checked in by cameron, 6 years ago

Initial check-in of icXML 0.8 source files

File size: 2.8 KB
Line 
1/*
2 *  Copyright © 2012 International Characters.
3 *  This software is licensed to the public under the Open Software License 3.0.
4 *  icXML is a trademark of International Characters.
5 */
6
7/*
8 * @author Nigel Medforth, nigelm -at- interational-characters.com
9 * @version $Id: backtrace.h 207 2012-12-02 20:38:22Z robc $
10 *
11 */
12
13#ifndef BACKTRACE_H
14#define BACKTRACE_H
15
16#include <iostream>
17
18#ifdef __GNUC__
19#include <execinfo.h>
20#include <signal.h>
21#include <cxxabi.h>
22#include <cstdlib>
23#endif
24
25#include <simd-lib/builtins.hpp>
26
27using namespace std;
28
29inline static void generateCallstack()
30{
31        #ifdef __GNUC__
32                void *                  array[256];
33                char **                 messages;
34                size_t          size;
35                size_t                  bufDemangledNameSz = 1024;
36                char *                  bufDemangledName = static_cast<char*>(malloc(bufDemangledNameSz));
37
38                // get void*'s for all entries on the stack
39                size = backtrace(array, 256);
40
41                messages = backtrace_symbols(array, size);
42
43
44                std::clog << "======= Backtrace: =========" << std::endl;
45
46                /* skip first stack frame (points here) */
47                for (unsigned int i = 0; i < size && messages != NULL; ++i)
48                {
49                        char *name = messages[i];
50                        char *demangledName = 0, *offset_begin = 0, *offset_end = 0;
51                        unsigned long int offset = 0;
52
53                        // find the parentheses and +address offset surrounding the mangled name
54                        for (char *j = name; *j; ++j)
55                        {
56                                if (*j == '(')
57                                {
58                                        char * begin = ++j;
59                                        for (; *j; ++j)
60                                        {
61                                                if (*j == '+')
62                                                {
63                                                        // attempt to demangle the name
64                                                        *j = 0;
65                                                        int status = -1;
66                                                        begin = abi::__cxa_demangle(begin, bufDemangledName, &bufDemangledNameSz, &status);
67                                                        if (likely(status == 0))
68                                                        {
69                                                                demangledName = begin;
70                                                                // TODO: trim out the namespace?
71
72                                                                offset_begin = ++j;
73                                                                for (; *j; j++)
74                                                                {
75                                                                        if (*j == ')')
76                                                                        {
77                                                                                // get the address offset of the function
78                                                                                *j = 0;
79                                                                                offset_end = ++j;
80                                                                                offset = strtoul(offset_begin, NULL, 16);
81                                                                                // TODO: translate the offset into a line number?
82                                                                                break;
83                                                                        }
84                                                                }
85                                                        }
86                                                        break;
87                                                }
88                                        }
89                                        break;
90                                }
91                        }
92
93                        if (demangledName)
94                        {
95                                std::clog << demangledName << '+' << offset << offset_end << std::endl;
96                        }
97                        else
98                        {
99                                std::clog << name << std::endl;
100                        }
101                }
102                free(messages);
103                free(bufDemangledName);
104        #else
105                abort();
106        #endif
107}
108
109#ifdef __GNUC__
110static void callstackHandler(int error_code)
111{
112        if (error_code == SIGSEGV)
113        {
114                std::clog << "ERROR: SEGMENTATION FAULT!" << std::endl;
115        }
116        generateCallstack();
117        exit(-1);
118}
119#endif
120
121IDISA_ALWAYS_INLINE
122static bool deprecatedFeatureUsed()
123{
124        std::clog << "ERROR: DEPRECATED FEATURE USED!" << std::endl;
125        generateCallstack();
126        return false;
127}
128
129IDISA_ALWAYS_INLINE
130static void registerSegFaultHandler()
131{
132        #ifdef __GNUC__
133        signal(SIGSEGV, callstackHandler);
134        #endif
135}
136
137#endif // BACKTRACE_H
Note: See TracBrowser for help on using the repository browser.