summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristopher Ferris2013-10-31 18:25:04 -0500
committerChristopher Ferris2013-11-06 14:37:14 -0600
commit9b0e074c6d38143e01616404a08b0c7aa992f3c3 (patch)
treec8cc73a2d73f7a600d70eee4fee2028895a61066 /libutils/CallStack.cpp
parent62a70df0643e7d5d40613904bf6c9747494366ef (diff)
downloadplatform-system-core-9b0e074c6d38143e01616404a08b0c7aa992f3c3.tar.gz
platform-system-core-9b0e074c6d38143e01616404a08b0c7aa992f3c3.tar.xz
platform-system-core-9b0e074c6d38143e01616404a08b0c7aa992f3c3.zip
Move CallStack to libbacktrace.
Fix a small bug in the Printer for strings that didn't properly prepend the prefix. Change-Id: I33c63841ef6e07728ab3195886539d82b38ee19a
Diffstat (limited to 'libutils/CallStack.cpp')
-rw-r--r--libutils/CallStack.cpp97
1 files changed, 15 insertions, 82 deletions
diff --git a/libutils/CallStack.cpp b/libutils/CallStack.cpp
index 4ceaa7c91..0bfb520e9 100644
--- a/libutils/CallStack.cpp
+++ b/libutils/CallStack.cpp
@@ -20,93 +20,33 @@
20#include <utils/Printer.h> 20#include <utils/Printer.h>
21#include <utils/Errors.h> 21#include <utils/Errors.h>
22#include <utils/Log.h> 22#include <utils/Log.h>
23#include <corkscrew/backtrace.h> 23#include <UniquePtr.h>
24
25#include <backtrace/Backtrace.h>
24 26
25namespace android { 27namespace android {
26 28
27CallStack::CallStack() : 29CallStack::CallStack() {
28 mCount(0) {
29} 30}
30 31
31CallStack::CallStack(const char* logtag, int32_t ignoreDepth, int32_t maxDepth) { 32CallStack::CallStack(const char* logtag, int32_t ignoreDepth) {
32 this->update(ignoreDepth+1, maxDepth, CURRENT_THREAD); 33 this->update(ignoreDepth+1);
33 this->log(logtag); 34 this->log(logtag);
34} 35}
35 36
36CallStack::CallStack(const CallStack& rhs) :
37 mCount(rhs.mCount) {
38 if (mCount) {
39 memcpy(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t));
40 }
41}
42
43CallStack::~CallStack() { 37CallStack::~CallStack() {
44} 38}
45 39
46CallStack& CallStack::operator = (const CallStack& rhs) { 40void CallStack::update(int32_t ignoreDepth, pid_t tid) {
47 mCount = rhs.mCount; 41 mFrameLines.clear();
48 if (mCount) {
49 memcpy(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t));
50 }
51 return *this;
52}
53
54bool CallStack::operator == (const CallStack& rhs) const {
55 if (mCount != rhs.mCount)
56 return false;
57 return !mCount || memcmp(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)) == 0;
58}
59
60bool CallStack::operator != (const CallStack& rhs) const {
61 return !operator == (rhs);
62}
63
64bool CallStack::operator < (const CallStack& rhs) const {
65 if (mCount != rhs.mCount)
66 return mCount < rhs.mCount;
67 return memcmp(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)) < 0;
68}
69 42
70bool CallStack::operator >= (const CallStack& rhs) const { 43 UniquePtr<Backtrace> backtrace(Backtrace::Create(BACKTRACE_CURRENT_PROCESS, tid));
71 return !operator < (rhs); 44 if (!backtrace->Unwind(ignoreDepth)) {
72} 45 ALOGW("%s: Failed to unwind callstack.", __FUNCTION__);
73
74bool CallStack::operator > (const CallStack& rhs) const {
75 if (mCount != rhs.mCount)
76 return mCount > rhs.mCount;
77 return memcmp(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)) > 0;
78}
79
80bool CallStack::operator <= (const CallStack& rhs) const {
81 return !operator > (rhs);
82}
83
84const void* CallStack::operator [] (int index) const {
85 if (index >= int(mCount))
86 return 0;
87 return reinterpret_cast<const void*>(mStack[index].absolute_pc);
88}
89
90void CallStack::clear() {
91 mCount = 0;
92}
93
94void CallStack::update(int32_t ignoreDepth, int32_t maxDepth, pid_t tid) {
95 if (maxDepth > MAX_DEPTH) {
96 maxDepth = MAX_DEPTH;
97 } 46 }
98 ssize_t count; 47 for (size_t i = 0; i < backtrace->NumFrames(); i++) {
99 48 mFrameLines.push_back(String8(backtrace->FormatFrameData(i).c_str()));
100 if (tid >= 0) {
101 count = unwind_backtrace_thread(tid, mStack, ignoreDepth + 1, maxDepth);
102 } else if (tid == CURRENT_THREAD) {
103 count = unwind_backtrace(mStack, ignoreDepth + 1, maxDepth);
104 } else {
105 ALOGE("%s: Invalid tid specified (%d)", __FUNCTION__, tid);
106 count = 0;
107 } 49 }
108
109 mCount = count > 0 ? count : 0;
110} 50}
111 51
112void CallStack::log(const char* logtag, android_LogPriority priority, const char* prefix) const { 52void CallStack::log(const char* logtag, android_LogPriority priority, const char* prefix) const {
@@ -129,16 +69,9 @@ String8 CallStack::toString(const char* prefix) const {
129} 69}
130 70
131void CallStack::print(Printer& printer) const { 71void CallStack::print(Printer& printer) const {
132 backtrace_symbol_t symbols[mCount]; 72 for (size_t i = 0; i < mFrameLines.size(); i++) {
133 73 printer.printLine(mFrameLines[i]);
134 get_backtrace_symbols(mStack, mCount, symbols);
135 for (size_t i = 0; i < mCount; i++) {
136 char line[MAX_BACKTRACE_LINE_LENGTH];
137 format_backtrace_line(i, &mStack[i], &symbols[i],
138 line, MAX_BACKTRACE_LINE_LENGTH);
139 printer.printLine(line);
140 } 74 }
141 free_backtrace_symbols(symbols, mCount);
142} 75}
143 76
144}; // namespace android 77}; // namespace android