STXXL  1.4-dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
stacktrace.h
Go to the documentation of this file.
1 /***************************************************************************
2  * include/stxxl/bits/utils/stacktrace.h
3  *
4  * Part of the STXXL. See http://stxxl.sourceforge.net
5  *
6  * Copyright (C) 2008 Timo Bingmann <[email protected]>
7  *
8  * Distributed under the Boost Software License, Version 1.0.
9  * (See accompanying file LICENSE_1_0.txt or copy at
10  * http://www.boost.org/LICENSE_1_0.txt)
11  **************************************************************************/
12 
13 #ifndef STXXL_UTILS_STACKTRACE_HEADER
14 #define STXXL_UTILS_STACKTRACE_HEADER
15 
16 #include <cstdio>
17 #include <cstdlib>
18 #include <execinfo.h>
19 #include <cxxabi.h>
20 
21 #include <stxxl/bits/namespace.h>
22 
24 
25 /** Print a demangled stack backtrace of the caller function to FILE* out. */
26 static inline void
27 print_stacktrace(FILE* out = stderr, unsigned int max_frames = 64)
28 {
29  fprintf(out, "stack trace:\n");
30 
31  // storage array for stack trace address data
32  void** addrlist = (void**)alloca(max_frames * sizeof(void*));
33 
34  // retrieve current stack addresses
35  int addrlen = backtrace(addrlist, max_frames);
36 
37  if (addrlen == 0) {
38  fprintf(out, " <empty, possibly corrupt>\n");
39  return;
40  }
41 
42  // resolve addresses into strings containing "filename(function+address)",
43  // this array must be free()-ed
44  char** symbollist = backtrace_symbols(addrlist, addrlen);
45 
46  // allocate string which will be filled with the demangled function name
47  size_t funcnamesize = 256;
48  char* funcname = (char*)malloc(funcnamesize);
49 
50  // iterate over the returned symbol lines. skip the first, it is the
51  // address of this function.
52  for (int i = 1; i < addrlen; i++)
53  {
54  char* begin_name = 0, * begin_offset = 0, * end_offset = 0;
55 
56  // find parentheses and +address offset surrounding the mangled name:
57  // ./module(function+0x15c) [0x8048a6d]
58  for (char* p = symbollist[i]; *p; ++p)
59  {
60  if (*p == '(')
61  begin_name = p;
62  else if (*p == '+')
63  begin_offset = p;
64  else if (*p == ')' && begin_offset) {
65  end_offset = p;
66  break;
67  }
68  }
69 
70  if (begin_name && begin_offset && end_offset
71  && begin_name < begin_offset)
72  {
73  *begin_name++ = '\0';
74  *begin_offset++ = '\0';
75  *end_offset = '\0';
76 
77  // mangled name is now in [begin_name, begin_offset) and caller
78  // offset in [begin_offset, end_offset). now apply
79  // __cxa_demangle():
80 
81  int status;
82  char* ret = abi::__cxa_demangle(begin_name,
83  funcname, &funcnamesize, &status);
84  if (status == 0) {
85  funcname = ret; // use possibly realloc()-ed string
86  fprintf(out, " %s : %s+%s\n",
87  symbollist[i], funcname, begin_offset);
88  }
89  else {
90  // demangling failed. Output function name as a C function with
91  // no arguments.
92  fprintf(out, " %s : %s()+%s\n",
93  symbollist[i], begin_name, begin_offset);
94  }
95  }
96  else
97  {
98  // couldn't parse the line? print the whole line.
99  fprintf(out, " %s\n", symbollist[i]);
100  }
101  }
102 
103  free(funcname);
104  free(symbollist);
105 }
106 
108 
109 #endif // !STXXL_UTILS_STACKTRACE_HEADER
void * malloc(size_t size)
static void print_stacktrace(FILE *out=stderr, unsigned int max_frames=64)
Definition: stacktrace.h:27
#define STXXL_BEGIN_NAMESPACE
Definition: namespace.h:16
void free(void *ptr)
#define STXXL_END_NAMESPACE
Definition: namespace.h:17