Drizzled Public API Documentation

backtrace.cc
1 /* - mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3  *
4  * Copyright (C) 2010 Brian Aker
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include <config.h>
22 #include <drizzled/util/backtrace.h>
23 
24 #include <cstring>
25 #include <cstdlib>
26 #include <iostream>
27 #include <cstdio>
28 
29 #ifdef __GNUC__
30 # ifdef HAVE_BACKTRACE
31 # include <execinfo.h>
32 # include <cxxabi.h>
33 # endif // HAVE_BACKTRACE
34 #endif // __GNUC__
35 
36 namespace drizzled
37 {
38 namespace util
39 {
40 
41 void custom_backtrace(const char *file, int line, const char *func, size_t depth)
42 {
43  (void)file; (void)line; (void)func; (void)depth;
44 #ifdef HAVE_BACKTRACE
45  void *array[50];
46 
47  size_t size= backtrace(array, 50);
48  char **strings= backtrace_symbols(array, size);
49 
50  if (strings == NULL)
51  {
52  return;
53  }
54 
55  std::cerr << std::endl << "call_backtrace(" << size << ") began at " << file << ":" << line << " for " << func << "()" << std::endl;
56 
57  if (depth == 0)
58  {
59  depth= size;
60  }
61  else
62  {
63  depth= std::min(depth, size);
64  }
65 
66  char *named_function= (char *)::realloc(NULL, 1024);
67 
68  if (named_function == NULL)
69  {
70  ::free(strings);
71  return;
72  }
73 
74  for (size_t x= 1; x < depth; x++)
75  {
76  if (true) // DEMANGLE
77  {
78  size_t sz= 200;
79  char *named_function_ptr= (char *)::realloc(named_function, sz);
80  if (named_function_ptr == NULL)
81  {
82  continue;
83  }
84  named_function= named_function_ptr;
85 
86  char *begin_name= 0;
87  char *begin_offset= 0;
88  char *end_offset= 0;
89 
90  for (char *j= strings[x]; *j; ++j)
91  {
92  if (*j == '(')
93  {
94  begin_name= j;
95  }
96  else if (*j == '+')
97  {
98  begin_offset= j;
99  }
100  else if (*j == ')' and begin_offset)
101  {
102  end_offset= j;
103  break;
104  }
105  }
106 
107  if (begin_name and begin_offset and end_offset and begin_name < begin_offset)
108  {
109  *begin_name++= '\0';
110  *begin_offset++= '\0';
111  *end_offset= '\0';
112 
113  int status;
114  char *ret= abi::__cxa_demangle(begin_name, named_function, &sz, &status);
115  if (ret) // realloc()'ed string
116  {
117  named_function= ret;
118  std::cerr << " " << strings[x] << " : " << begin_name << "() + " << begin_offset << std::endl;
119  }
120  else
121  {
122  std::cerr << " " << strings[x] << " : " << begin_name << "() + " << begin_offset << std::endl;
123  }
124  }
125  else
126  {
127  std::cerr << " " << strings[x] << std::endl;
128  }
129  }
130  else
131  {
132  std::cerr << " unmangled:" << strings[x] << std::endl;
133  }
134  }
135 
136  ::free(named_function);
137  ::free(strings);
138 #endif // HAVE_BACKTRACE
139 }
140 
141 } /* namespace util */
142 } /* namespace drizzled */