summaryrefslogtreecommitdiffstats
path: root/libutils/CallStack.cpp
diff options
context:
space:
mode:
authorIgor Murashkin <iam@google.com>2013-10-24 17:09:15 -0700
committerIgor Murashkin <iam@google.com>2013-10-25 19:24:56 -0700
commitec79ef2e7b6b1d81266637ca0e002b5c0c5a789b (patch)
tree309ff8a328db5ccd522995abe3614959cfded1c6 /libutils/CallStack.cpp
parenta9e453f1b552699f69dca19599c7624a581089bd (diff)
downloadsystem_core-ec79ef2e7b6b1d81266637ca0e002b5c0c5a789b.zip
system_core-ec79ef2e7b6b1d81266637ca0e002b5c0c5a789b.tar.gz
system_core-ec79ef2e7b6b1d81266637ca0e002b5c0c5a789b.tar.bz2
utils: Add ProcessCallStack to collect stack traces for all threads in a process
- Also add a Printer class (print lines to logcat, fd, or strings) Bug: 11324229 Change-Id: I78435ed49aa196a0efb45bf9b2d58b62c41737d3
Diffstat (limited to 'libutils/CallStack.cpp')
-rw-r--r--libutils/CallStack.cpp60
1 files changed, 33 insertions, 27 deletions
diff --git a/libutils/CallStack.cpp b/libutils/CallStack.cpp
index e60f5d8..4ceaa7c 100644
--- a/libutils/CallStack.cpp
+++ b/libutils/CallStack.cpp
@@ -16,14 +16,12 @@
#define LOG_TAG "CallStack"
-#include <string.h>
-
-#include <utils/Log.h>
-#include <utils/Errors.h>
#include <utils/CallStack.h>
+#include <utils/Printer.h>
+#include <utils/Errors.h>
+#include <utils/Log.h>
#include <corkscrew/backtrace.h>
-/*****************************************************************************/
namespace android {
CallStack::CallStack() :
@@ -31,8 +29,8 @@ CallStack::CallStack() :
}
CallStack::CallStack(const char* logtag, int32_t ignoreDepth, int32_t maxDepth) {
- this->update(ignoreDepth+1, maxDepth);
- this->dump(logtag);
+ this->update(ignoreDepth+1, maxDepth, CURRENT_THREAD);
+ this->log(logtag);
}
CallStack::CallStack(const CallStack& rhs) :
@@ -93,31 +91,44 @@ void CallStack::clear() {
mCount = 0;
}
-void CallStack::update(int32_t ignoreDepth, int32_t maxDepth) {
+void CallStack::update(int32_t ignoreDepth, int32_t maxDepth, pid_t tid) {
if (maxDepth > MAX_DEPTH) {
maxDepth = MAX_DEPTH;
}
- ssize_t count = unwind_backtrace(mStack, ignoreDepth + 1, maxDepth);
+ ssize_t count;
+
+ if (tid >= 0) {
+ count = unwind_backtrace_thread(tid, mStack, ignoreDepth + 1, maxDepth);
+ } else if (tid == CURRENT_THREAD) {
+ count = unwind_backtrace(mStack, ignoreDepth + 1, maxDepth);
+ } else {
+ ALOGE("%s: Invalid tid specified (%d)", __FUNCTION__, tid);
+ count = 0;
+ }
+
mCount = count > 0 ? count : 0;
}
-void CallStack::dump(const char* logtag, const char* prefix) const {
- backtrace_symbol_t symbols[mCount];
+void CallStack::log(const char* logtag, android_LogPriority priority, const char* prefix) const {
+ LogPrinter printer(logtag, priority, prefix, /*ignoreBlankLines*/false);
+ print(printer);
+}
- get_backtrace_symbols(mStack, mCount, symbols);
- for (size_t i = 0; i < mCount; i++) {
- char line[MAX_BACKTRACE_LINE_LENGTH];
- format_backtrace_line(i, &mStack[i], &symbols[i],
- line, MAX_BACKTRACE_LINE_LENGTH);
- ALOG(LOG_DEBUG, logtag, "%s%s",
- prefix ? prefix : "",
- line);
- }
- free_backtrace_symbols(symbols, mCount);
+void CallStack::dump(int fd, int indent, const char* prefix) const {
+ FdPrinter printer(fd, indent, prefix);
+ print(printer);
}
String8 CallStack::toString(const char* prefix) const {
String8 str;
+
+ String8Printer printer(&str, prefix);
+ print(printer);
+
+ return str;
+}
+
+void CallStack::print(Printer& printer) const {
backtrace_symbol_t symbols[mCount];
get_backtrace_symbols(mStack, mCount, symbols);
@@ -125,14 +136,9 @@ String8 CallStack::toString(const char* prefix) const {
char line[MAX_BACKTRACE_LINE_LENGTH];
format_backtrace_line(i, &mStack[i], &symbols[i],
line, MAX_BACKTRACE_LINE_LENGTH);
- if (prefix) {
- str.append(prefix);
- }
- str.append(line);
- str.append("\n");
+ printer.printLine(line);
}
free_backtrace_symbols(symbols, mCount);
- return str;
}
}; // namespace android