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