libzypp 17.31.0
Backtrace.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8\---------------------------------------------------------------------*/
11#include <execinfo.h>
12#include <cxxabi.h>
13
14#include <iostream>
15#include <zypp/base/LogTools.h>
16#include <zypp/base/String.h>
17#include <zypp/base/Backtrace.h>
18
19using std::endl;
20
22namespace zypp
23{
24 std::ostream & dumpBacktrace( std::ostream & stream_r )
25 {
26 // get void*'s for all entries on the stack
27 static const size_t arraySize = 50;
28 void *array[arraySize];
29 size_t size = ::backtrace( array, arraySize );
30
31 // Print out all frames to stderr. Separate sigsegvHandler stack
32 // [dumpBacktrace][sigsegvHandler][libc throwing] from actual
33 // code stack.
34 char ** messages = ::backtrace_symbols( array, size );
35 if ( messages )
36 {
37 static const size_t handlerStack = 3; // [dumpBacktrace][sigsegvHandler][libc throwing]
38 static const size_t first = 0;
39 for ( size_t i = first; i < size; ++i )
40 {
41 char * mangled_name = 0;
42 char * offset_begin = 0;
43 char * offset_end = 0;
44
45 // find parentheses and +address offset surrounding mangled name
46 for ( char * p = messages[i]; *p; ++p )
47 {
48 if ( *p == '(' )
49 {
50 mangled_name = p;
51 }
52 else if ( *p == '+' )
53 {
54 offset_begin = p;
55 }
56 else if ( *p == ')' )
57 {
58 offset_end = p;
59 break;
60 }
61 }
62
63 int btLevel = i-handlerStack; // negative level in sigsegvHandler
64 if ( i > first )
65 {
66 stream_r << endl;
67 if ( btLevel == 0 )
68 stream_r << "vvvvvvvvvv----------------------------------------" << endl;
69 }
70 stream_r << "[" << (btLevel<0 ?"hd":"bt") << "]: (" << btLevel << ") ";
71
72 // if the line could be processed, attempt to demangle the symbol
73 if ( mangled_name && offset_begin && offset_end && mangled_name < offset_begin )
74 {
75 *mangled_name++ = '\0';
76 *offset_begin++ = '\0';
77 *offset_end++ = '\0';
78
79 int status;
80 char * real_name = ::abi::__cxa_demangle( mangled_name, 0, 0, &status );
81
82 // if demangling is successful, output the demangled function name
83 if ( status == 0 )
84 {
85 stream_r << messages[i] << " : " << real_name << "+" << offset_begin << offset_end;
86 }
87 // otherwise, output the mangled function name
88 else
89 {
90 stream_r << messages[i] << " : " << mangled_name << "+" << offset_begin << offset_end;
91 }
92 ::free( real_name );
93 }
94 else
95 {
96 // otherwise, print the whole line
97 stream_r << messages[i];
98 }
99 }
100 ::free( messages );
101 }
102 return stream_r;
103 }
104
105} // namespace zypp
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:2
std::ostream & dumpBacktrace(std::ostream &stream_r)
Dump current stack trace to a stream.
Definition: Backtrace.cc:24
#define arraySize(A)
Definition: Easy.h:42