OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
backtrace.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #include "base/backtrace.h"
6 
7 #include <boost/algorithm/string.hpp>
8 #include <execinfo.h>
9 #include <stdio.h>
10 
11 #include "base/logging.h"
12 
13 ssize_t BackTrace::ToString(void * const* callstack, int frames, char *buf,
14  size_t buf_len) {
15  buf[0] = '\0';
16 
17  char *str = buf;
18  char **strs = backtrace_symbols(callstack, frames);
19  int line_pos;
20  size_t len = 0;
21 
22  for (int i = 0; i < frames; ++i) {
23  int status;
24  std::vector<std::string> SplitVec;
25 
26  if (i == frames - 1) continue;
27  boost::split(SplitVec, strs[i], boost::is_any_of("()"),
28  boost::token_compress_on);
29  boost::split(SplitVec, SplitVec[1], boost::is_any_of("+"),
30  boost::token_compress_on);
31  char *demangledName =
32  abi::__cxa_demangle(SplitVec[0].c_str(), NULL, NULL, &status);
33  line_pos = 1;
34 
35  if (status == 0) {
36  if (!strstr(demangledName, "boost::") &&
37  !strstr(demangledName, "tbb::") &&
38  !strstr(demangledName, "BackTrace::") &&
39  !strstr(demangledName, "BgpDebug::") &&
40  !strstr(demangledName, "testing::")) {
41  len = snprintf(str, buf_len - (str - buf),
42  "\t%s+%s\n", demangledName,
43  SplitVec[line_pos].c_str());
44  if (len > buf_len - (str - buf)) {
45 
46  // Overflow
47  free(demangledName);
48  str += buf_len - (str - buf);
49  assert((size_t) (str - buf) == buf_len);
50  break;
51  }
52  str += len;
53  }
54  free(demangledName);
55  }
56  }
57  free(strs);
58 
59  return (str - buf);
60 }
61 
62 int BackTrace::Get(void * const* &callstack) {
63  callstack = (void * const *) calloc(1024, sizeof(void *));
64  return backtrace((void **) callstack, 1024);
65 }
66 
67 void BackTrace::Log(void * const* callstack, int frames,
68  const std::string &msg) {
69  char buf[10240];
70 
71  ToString(callstack, frames, buf, sizeof(buf));
72  std::string s(buf, strlen(buf));
73  LOG(DEBUG, msg << ":BackTrace\n" << s);
74  free((void *) callstack);
75 }
76 
77 void BackTrace::Log(const std::string &msg) {
78  void * const*callstack;
79 
80  int frames = Get(callstack);
81  Log(callstack, frames, msg);
82 }
static void Log(const std::string &msg)
Definition: backtrace.cc:77
static ssize_t ToString(void *const *callstack, int frames, char *buf, size_t buf_len)
Definition: backtrace.cc:13
static int Get(void *const *&callstack)
Definition: backtrace.cc:62
#define LOG(_Level, _Msg)
Definition: logging.h:33