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