13 # include <SymbolResolve.h>
23 LowLevelException::LowLevelException() {
28 LowLevelException::~LowLevelException() {
32 LowLevelException::LowLevelException(const LowLevelException
& ex
) {
33 #if ! defined(DISABLESTACKTRACE)
36 for(short i
= 0; i
< trace
; ++i
) {
37 callersAddr
[i
] = ex
.callersAddr
[i
];
42 #if defined(_MSC_VER) && defined(_M_IX86) && ! defined(DISABLESTACKTRACE)
43 static void *getCaller(int index
) {
51 Exception_getCaller_next
:
55 jnz Exception_getCaller_next
64 Creates the stacktrace buffer.
66 void LowLevelException::fillInStackTrace() {
67 #if ! defined(DISABLESTACKTRACE)
68 #if defined(_MSC_VER) && defined(_M_IX86)
72 addr
= getCaller(trace
);
73 callersAddr
[trace
++] = addr
;
74 } while( (addr
!= 0) && (trace
< MAXTRACESIZE
) );
76 trace
= backtrace(callersAddr
, MAXTRACESIZE
);
83 void LowLevelException::printStackTrace() const {
84 printStackTrace( std::cout
);
88 Prints this Exception and its backtrace to the
89 standard error stream. This method prints a stack trace
90 for this exception on the error output stream
91 The first line of output contains the result of the getMessage()
92 method for this object. Remaining lines represent
93 a list of the function calls that are currently active
95 void LowLevelException::printStackTrace(std::ostream
& str
) const {
96 #if ! defined(DISABLESTACKTRACE)
97 #if defined(_MSC_VER) && defined(_M_IX86)
98 for(unsigned short i
= 2; i
< trace
; ++i
) {
99 str
<< '(' << (trace
- i
) << ") "
100 << " [" << std::hex
<< callersAddr
[i
] << std::dec
<< "]: ";
103 DWORD64 addr
= DWORD64(callersAddr
[i
]);
104 PSYMBOL_INFO sym
= SymbolResolve::getSymbolFromAddress( addr
);
105 str
<< ((sym
!= 0) ? sym
->Name
: "???") << std::endl
;
107 IMAGEHLP_LINE64
*im
= SymbolResolve::getSourceFromAddress( addr
);
109 str
<< "\t" << im
->FileName
<< ":" << im
->LineNumber
<< std::endl
;
111 str
<< "???" << std::endl
;
116 for(unsigned short i
= 2; i
< trace
; ++i
) {
117 str
<< '(' << (trace
- i
) << ") ";
118 if( (dladdr(callersAddr
[i
], &info
) != 0) && (info
.dli_sname
!= 0) ) {
119 const char *name
=__cxxabiv1::__cxa_demangle(info
.dli_sname
, 0, 0, 0);
122 free( (void *)name
);
124 str
<< info
.dli_sname
;
128 str
<< " [" << std::hex
<< callersAddr
[i
] << std::dec
<< ']' << std::endl
;
131 /* backtrace_symbols might be more portable but does not do name