ardour
stacktrace.cc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2000-2007 Paul Davis
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or
7  (at your option) any later version.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 
18 */
19 
20 #include "libpbd-config.h"
21 
22 #include "pbd/stacktrace.h"
23 #include <cstdio>
24 #include <iostream>
25 #include <string>
26 
27 void
29 {
30 }
31 
32 /* Obtain a backtrace and print it to stdout. */
33 
34 #ifdef HAVE_EXECINFO
35 
36 #include <execinfo.h>
37 #include <cxxabi.h>
38 
39 static std::string
40 symbol_demangle (const std::string& l)
41 {
42  int status;
43 
44  try {
45 
46  char* realname = abi::__cxa_demangle (l.c_str(), 0, 0, &status);
47  std::string d (realname);
48  free (realname);
49  return d;
50  } catch (std::exception) {
51 
52  }
53 
54  return l;
55 }
56 
57 std::string
58 PBD::demangle (std::string const & l)
59 {
60  std::string::size_type const b = l.find_first_of ("(");
61 
62  if (b == std::string::npos) {
63  return symbol_demangle (l);
64  }
65 
66  std::string::size_type const p = l.find_last_of ("+");
67  if (p == std::string::npos) {
68  return symbol_demangle (l);
69  }
70 
71  if ((p - b) <= 1) {
72  return symbol_demangle (l);
73  }
74 
75  std::string const fn = l.substr (b + 1, p - b - 1);
76 
77  return symbol_demangle (fn);
78 }
79 
80 void
81 PBD::stacktrace (std::ostream& out, int levels)
82 {
83  void *array[200];
84  size_t size;
85  char **strings;
86  size_t i;
87 
88  size = backtrace (array, 200);
89 
90  if (size) {
91  strings = backtrace_symbols (array, size);
92 
93  if (strings) {
94 
95  for (i = 0; i < size && (levels == 0 || i < size_t(levels)); i++) {
96  out << " " << demangle (strings[i]) << std::endl;
97  }
98 
99  free (strings);
100  }
101  } else {
102  out << "no stacktrace available!" << std::endl;
103  }
104 }
105 
106 #else
107 
108 std::string
109 PBD::demangle (std::string const & l) /* JE - !!!! 'PBD' namespace might possibly get removed (except it's still used in 'libs/canvas/item.cc') */
110 {
111  return std::string();
112 }
113 
114 void
115 PBD::stacktrace (std::ostream& out, int /*levels*/)
116 {
117  out << "stack tracing is not enabled on this platform" << std::endl;
118 }
119 
120 void
122 {
123  PBD::stacktrace (std::cout);
124 }
125 
126 #endif /* HAVE_EXECINFO */
void c_stacktrace()
Definition: stacktrace.cc:121
LIBPBD_API void stacktrace(std::ostream &out, int levels=0)
Definition: stacktrace.cc:115
LIBPBD_API void trace_twb()
Definition: stacktrace.cc:28
LIBPBD_API std::string demangle(const std::string &)
Definition: stacktrace.cc:109