1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
//
// libavg - Media Playback Engine.
// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// Current versions can be found at www.libavg.de
//
#include "Backtrace.h"
#include "StringHelper.h"
#ifndef _WIN32
#include <execinfo.h>
#include <cxxabi.h>
#endif
#include <stdlib.h>
#include <iostream>
#include <stdio.h>
using namespace std;
namespace avg {
void dumpBacktrace()
{
#ifndef _WIN32
vector<string> sFuncs;
getBacktrace(sFuncs);
vector<string>::iterator it = sFuncs.begin();
++it;
for (; it != sFuncs.end(); ++it) {
cerr << " " << *it << endl;
}
#endif
}
string funcNameFromLine(const string& sLine)
{
try {
#ifdef __APPLE__
string::size_type addressPos = sLine.find("0x");
string::size_type namePos = sLine.find(" ", addressPos);
namePos++;
string::size_type nameEndPos = sLine.find(" ", namePos);
#else
string::size_type namePos = sLine.find("(");
namePos++;
string::size_type nameEndPos = sLine.find_first_of(")+", namePos);
#endif
return sLine.substr(namePos, nameEndPos-namePos);
} catch (exception&) {
return sLine;
}
}
void consolidateRepeatedLines(vector<string>& sFuncs, unsigned& i, unsigned numSameLines)
{
unsigned firstSameLine = i - numSameLines;
sFuncs[firstSameLine+1] = " [...]";
sFuncs.erase(sFuncs.begin()+firstSameLine+2, sFuncs.begin()+i-1);
i = firstSameLine + 3;
}
void getBacktrace(vector<string>& sFuncs)
{
#ifndef _WIN32
void* callstack[128];
int numFrames = backtrace(callstack, 128);
char** ppszLines = backtrace_symbols(callstack, numFrames);
for (int i = 1; i < numFrames; ++i) {
string sLine = ppszLines[i];
string sFuncName = funcNameFromLine(sLine);
int result;
char * pszDemangledFuncName = abi::__cxa_demangle(sFuncName.c_str(), 0, 0,
&result);
if (!result) {
sFuncName = pszDemangledFuncName;
free(pszDemangledFuncName);
}
char szLineNum[10];
sprintf(szLineNum, "%3d", i);
sFuncs.push_back(string(szLineNum)+" "+sFuncName);
}
free(ppszLines);
unsigned numSameLines = 1;
unsigned i = 1;
for (i = 1; i < sFuncs.size(); ++i) {
if (sFuncs[i].substr(4, string::npos) == sFuncs[i-1].substr(4, string::npos)) {
numSameLines++;
} else {
if (numSameLines > 3) {
consolidateRepeatedLines(sFuncs, i, numSameLines);
}
numSameLines = 1;
}
}
if (numSameLines > 2) {
consolidateRepeatedLines(sFuncs, i, numSameLines);
}
#endif
}
}
|