Backtrace.cc
Go to the documentation of this file.
1 //
2 // Copyright (c) 2020 Fraunhofer Institute for Applied Information Technology (FIT)
3 // Network Research Group (NET)
4 // Schloss Birlinghoven, 53754 Sankt Augustin, GERMANY
5 // Contact: support@wiback.org
6 //
7 // This file is part of the SENF code tree.
8 // It is licensed under the 3-clause BSD License (aka New BSD License).
9 // See LICENSE.txt in the top level directory for details or visit
10 // https://opensource.org/licenses/BSD-3-Clause
11 //
12 
13 
17 #include "Backtrace.hh"
18 //#include "Backtrace.ih"
19 
20 // Custom includes
21 #include <senf/config.hh>
22 #ifdef SENF_BACKTRACE
23  #include <execinfo.h>
24  #include <errno.h>
25 #endif
26 #include <cxxabi.h>
27 #include <boost/regex.hpp>
28 #include "Buffer.hh"
29 
30 //#include "Backtrace.mpp"
31 #define prefix_
32 //-/////////////////////////////////////////////////////////////////////////////////////////////////
33 
34 prefix_ void senf::formatBacktrace(std::ostream & os, void ** backtrace, int numEntries)
35 {
36 #ifdef SENF_BACKTRACE
37  char ** symbols (::backtrace_symbols(backtrace, numEntries));
38  if (symbols == NULL) {
39  os << "error on translating backtrace addresses with ::backtrace_symbols: " << std::strerror(errno);
40  return;
41  }
42 
43  static boost::regex const backtraceRx
44  ("(.*)\\((.*)\\+(0x[0-9a-f]+)\\) \\[(0x[0-9a-f]+)\\]");
45  enum { File = 1,
46  Symbol = 2,
47  Offset = 3,
48  Address = 4 };
49 
50  for (int i=0; i<numEntries; ++i) {
51  std::string sym (symbols[i]);
52  boost::smatch match;
53  if (regex_match(sym, match, backtraceRx)) {
54  std::string symbol (match[Symbol]);
55  int status (0);
56  char * demangled ( abi::__cxa_demangle(symbol.c_str(), 0, 0, &status) );
57  if (demangled) {
58  symbol = std::string(demangled);
59  free(demangled);
60  }
61  os << " " << symbol << " + " << match[Offset]
62  << "\n in " << match[File] << " [" << match[Address] << "]\n";
63  }
64  else if (sym == "[0xffffe410]")
65  os << " __kernel_vsyscall [0xffffe410]\n";
66  else if (sym == "[0xffffe420]")
67  os << " __kernel_sigreturn [0xffffe410]\n";
68  else if (sym == "[0xffffe440]")
69  os << " __kernel_rt_sigreturn [0xffffe440]\n";
70  else
71  os << " " << sym << "\n";
72  }
73  free(symbols);
74 #else
75  os << "no backtrace available please compile SENF without final=1\n";
76 #endif
77 
78 }
79 
80 prefix_ void senf::backtrace(std::ostream & os, int numEntries)
81 {
82 #ifdef SENF_BACKTRACE
83  SENF_SCOPED_BUFFER( void*, entries, numEntries);
84  int n ( ::backtrace(entries, numEntries) );
85  senf::formatBacktrace(os, entries, n);
86 #endif
87 }
88 
89 //-/////////////////////////////////////////////////////////////////////////////////////////////////
90 #undef prefix_
91 //#include "Backtrace.mpp"
92 
93 
94 // Local Variables:
95 // mode: c++
96 // fill-column: 100
97 // comment-column: 40
98 // c-file-style: "senf"
99 // indent-tabs-mode: nil
100 // ispell-local-dictionary: "american"
101 // compile-command: "scons -u test"
102 // End:
Buffer public header.
Backtrace public header.
void backtrace(std::ostream &os, int numEntries)
Write a backtrace to os.
Definition: Backtrace.cc:80
#define prefix_
Definition: Backtrace.cc:31
void formatBacktrace(std::ostream &os, void **backtrace, int numEntries)
Format a given backtrace.
Definition: Backtrace.cc:34