2 * avr-sim: An atmel AVR simulator
3 * Copyright (C) 2008 Tom Haber
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include "Exception.h"
23 # include <execinfo.h>
31 # include <SymbolResolve.h>
41 LowLevelException::LowLevelException() {
46 LowLevelException::~LowLevelException() {
50 LowLevelException::LowLevelException(const LowLevelException
& ex
) {
51 #if ! defined(DISABLESTACKTRACE)
54 for(short i
= 0; i
< trace
; ++i
) {
55 callersAddr
[i
] = ex
.callersAddr
[i
];
60 #if defined(_MSC_VER) && defined(_M_IX86) && ! defined(DISABLESTACKTRACE)
61 static void *getCaller(int index
) {
69 Exception_getCaller_next
:
73 jnz Exception_getCaller_next
82 Creates the stacktrace buffer.
84 void LowLevelException::fillInStackTrace() {
85 #if ! defined(DISABLESTACKTRACE)
86 #if defined(_MSC_VER) && defined(_M_IX86)
90 addr
= getCaller(trace
);
91 callersAddr
[trace
++] = addr
;
92 } while( (addr
!= 0) && (trace
< MAXTRACESIZE
) );
93 #elif defined(__GNUC__)
94 trace
= backtrace(callersAddr
, MAXTRACESIZE
);
101 void LowLevelException::printStackTrace() const {
102 printStackTrace( std::cout
);
106 Prints this Exception and its backtrace to the
107 standard error stream. This method prints a stack trace
108 for this exception on the error output stream
109 The first line of output contains the result of the getMessage()
110 method for this object. Remaining lines represent
111 a list of the function calls that are currently active
113 void LowLevelException::printStackTrace(std::ostream
& str
) const {
114 #if ! defined(DISABLESTACKTRACE)
115 #if defined(_MSC_VER) && defined(_M_IX86)
116 for(unsigned short i
= 2; i
< trace
; ++i
) {
117 str
<< '(' << (trace
- i
) << ") "
118 << " [" << std::hex
<< callersAddr
[i
] << std::dec
<< "]: ";
121 DWORD64 addr
= DWORD64(callersAddr
[i
]);
122 PSYMBOL_INFO sym
= SymbolResolve::getSymbolFromAddress( addr
);
123 str
<< ((sym
!= 0) ? sym
->Name
: "???") << std::endl
;
125 IMAGEHLP_LINE64
*im
= SymbolResolve::getSourceFromAddress( addr
);
127 str
<< "\t" << im
->FileName
<< ":" << im
->LineNumber
<< std::endl
;
129 str
<< "???" << std::endl
;
132 #elif defined(__GNUC__)
134 for(unsigned short i
= 2; i
< trace
; ++i
) {
135 str
<< '(' << (trace
- i
) << ") ";
136 if( (dladdr(callersAddr
[i
], &info
) != 0) && (info
.dli_sname
!= 0) ) {
137 const char *name
=__cxxabiv1::__cxa_demangle(info
.dli_sname
, 0, 0, 0);
140 free( (void *)name
);
142 str
<< info
.dli_sname
;
146 str
<< " [" << std::hex
<< callersAddr
[i
] << std::dec
<< ']' << std::endl
;
149 /* backtrace_symbols might be more portable but does not do name