summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristopher Ferris2013-10-31 18:25:04 -0500
committerChristopher Ferris2014-01-09 17:09:13 -0600
commit038ac694b36de2b081e62fcfb9b5f4a8c918c533 (patch)
treebde917eef3e385029bee6bd87682705a709ef331 /libutils
parentb0751101b090a8732c62ad261fa44e5d6a69a2cc (diff)
downloadplatform-system-core-038ac694b36de2b081e62fcfb9b5f4a8c918c533.tar.gz
platform-system-core-038ac694b36de2b081e62fcfb9b5f4a8c918c533.tar.xz
platform-system-core-038ac694b36de2b081e62fcfb9b5f4a8c918c533.zip
Move CallStack to libbacktrace.
Fix a small bug in the Printer for strings that didn't properly prepend the prefix. (cherry picked from commit 9b0e074c6d38143e01616404a08b0c7aa992f3c3) Change-Id: I78bfa3f76864c34f33fb439bf20dfc85616f1077
Diffstat (limited to 'libutils')
-rw-r--r--libutils/Android.mk10
-rw-r--r--libutils/CallStack.cpp97
-rw-r--r--libutils/Printer.cpp1
-rw-r--r--libutils/ProcessCallStack.cpp10
4 files changed, 27 insertions, 91 deletions
diff --git a/libutils/Android.mk b/libutils/Android.mk
index 720443e88..1710d3671 100644
--- a/libutils/Android.mk
+++ b/libutils/Android.mk
@@ -116,10 +116,12 @@ LOCAL_STATIC_LIBRARIES := \
116 libcutils 116 libcutils
117 117
118LOCAL_SHARED_LIBRARIES := \ 118LOCAL_SHARED_LIBRARIES := \
119 libcorkscrew \ 119 libbacktrace \
120 liblog \ 120 liblog \
121 libdl 121 libdl
122 122
123include external/stlport/libstlport.mk
124
123LOCAL_MODULE:= libutils 125LOCAL_MODULE:= libutils
124include $(BUILD_STATIC_LIBRARY) 126include $(BUILD_STATIC_LIBRARY)
125 127
@@ -129,10 +131,12 @@ include $(CLEAR_VARS)
129LOCAL_MODULE:= libutils 131LOCAL_MODULE:= libutils
130LOCAL_WHOLE_STATIC_LIBRARIES := libutils 132LOCAL_WHOLE_STATIC_LIBRARIES := libutils
131LOCAL_SHARED_LIBRARIES := \ 133LOCAL_SHARED_LIBRARIES := \
132 liblog \ 134 libbacktrace \
133 libcutils \ 135 libcutils \
134 libdl \ 136 libdl \
135 libcorkscrew 137 liblog \
138
139include external/stlport/libstlport.mk
136 140
137include $(BUILD_SHARED_LIBRARY) 141include $(BUILD_SHARED_LIBRARY)
138 142
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
diff --git a/libutils/Printer.cpp b/libutils/Printer.cpp
index ac729e05c..263e7404b 100644
--- a/libutils/Printer.cpp
+++ b/libutils/Printer.cpp
@@ -145,6 +145,7 @@ void String8Printer::printLine(const char* string) {
145 return; 145 return;
146 } 146 }
147 147
148 mTarget->append(mPrefix);
148 mTarget->append(string); 149 mTarget->append(string);
149 mTarget->append("\n"); 150 mTarget->append("\n");
150} 151}
diff --git a/libutils/ProcessCallStack.cpp b/libutils/ProcessCallStack.cpp
index f9340c5b0..f837bcb63 100644
--- a/libutils/ProcessCallStack.cpp
+++ b/libutils/ProcessCallStack.cpp
@@ -123,7 +123,7 @@ void ProcessCallStack::clear() {
123 mTimeUpdated = tm(); 123 mTimeUpdated = tm();
124} 124}
125 125
126void ProcessCallStack::update(int32_t maxDepth) { 126void ProcessCallStack::update() {
127 DIR *dp; 127 DIR *dp;
128 struct dirent *ep; 128 struct dirent *ep;
129 struct dirent entry; 129 struct dirent entry;
@@ -181,14 +181,13 @@ void ProcessCallStack::update(int32_t maxDepth) {
181 int ignoreDepth = (selfPid == tid) ? IGNORE_DEPTH_CURRENT_THREAD : 0; 181 int ignoreDepth = (selfPid == tid) ? IGNORE_DEPTH_CURRENT_THREAD : 0;
182 182
183 // Update thread's call stacks 183 // Update thread's call stacks
184 CallStack& cs = threadInfo.callStack; 184 threadInfo.callStack.update(ignoreDepth, tid);
185 cs.update(ignoreDepth, maxDepth, tid);
186 185
187 // Read/save thread name 186 // Read/save thread name
188 threadInfo.threadName = getThreadName(tid); 187 threadInfo.threadName = getThreadName(tid);
189 188
190 ALOGV("%s: Got call stack for tid %d (size %zu)", 189 ALOGV("%s: Got call stack for tid %d (size %zu)",
191 __FUNCTION__, tid, cs.size()); 190 __FUNCTION__, tid, threadInfo.callStack.size());
192 } 191 }
193 if (code != 0) { // returns positive error value on error 192 if (code != 0) { // returns positive error value on error
194 ALOGE("%s: Failed to readdir from %s (errno = %d, '%s')", 193 ALOGE("%s: Failed to readdir from %s (errno = %d, '%s')",
@@ -221,13 +220,12 @@ void ProcessCallStack::printInternal(Printer& printer, Printer& csPrinter) const
221 for (size_t i = 0; i < mThreadMap.size(); ++i) { 220 for (size_t i = 0; i < mThreadMap.size(); ++i) {
222 pid_t tid = mThreadMap.keyAt(i); 221 pid_t tid = mThreadMap.keyAt(i);
223 const ThreadInfo& threadInfo = mThreadMap.valueAt(i); 222 const ThreadInfo& threadInfo = mThreadMap.valueAt(i);
224 const CallStack& cs = threadInfo.callStack;
225 const String8& threadName = threadInfo.threadName; 223 const String8& threadName = threadInfo.threadName;
226 224
227 printer.printLine(""); 225 printer.printLine("");
228 printer.printFormatLine("\"%s\" sysTid=%d", threadName.string(), tid); 226 printer.printFormatLine("\"%s\" sysTid=%d", threadName.string(), tid);
229 227
230 cs.print(csPrinter); 228 threadInfo.callStack.print(csPrinter);
231 } 229 }
232 230
233 dumpProcessFooter(printer, getpid()); 231 dumpProcessFooter(printer, getpid());