summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristopher Ferris <cferris@google.com>2014-01-09 23:48:26 +0000
committerAndroid Git Automerger <android-git-automerger@android.com>2014-01-09 23:48:26 +0000
commitc49bd655e5233f367c535ed4324bbadc4aea5453 (patch)
tree82b9c16d470b1d8c4ab283994a9e213eec9abb45
parent3794c96f3e7bb27e56336035bcd7ac643c6869fc (diff)
parent5d2ec87bf54dc8a02e6bcbe5848fd378056b8f78 (diff)
downloadsystem_core-c49bd655e5233f367c535ed4324bbadc4aea5453.zip
system_core-c49bd655e5233f367c535ed4324bbadc4aea5453.tar.gz
system_core-c49bd655e5233f367c535ed4324bbadc4aea5453.tar.bz2
am 5d2ec87b: am b18f93ea: Merge "Move CallStack to libbacktrace."
* commit '5d2ec87bf54dc8a02e6bcbe5848fd378056b8f78': Move CallStack to libbacktrace.
-rw-r--r--include/utils/CallStack.h39
-rw-r--r--include/utils/ProcessCallStack.h2
-rw-r--r--libutils/Android.mk10
-rw-r--r--libutils/CallStack.cpp97
-rw-r--r--libutils/Printer.cpp1
-rw-r--r--libutils/ProcessCallStack.cpp10
6 files changed, 36 insertions, 123 deletions
diff --git a/include/utils/CallStack.h b/include/utils/CallStack.h
index 2056751..5836037 100644
--- a/include/utils/CallStack.h
+++ b/include/utils/CallStack.h
@@ -18,8 +18,9 @@
#define ANDROID_CALLSTACK_H
#include <android/log.h>
+#include <backtrace/backtrace.h>
#include <utils/String8.h>
-#include <corkscrew/backtrace.h>
+#include <utils/Vector.h>
#include <stdint.h>
#include <sys/types.h>
@@ -31,42 +32,19 @@ class Printer;
// Collect/print the call stack (function, file, line) traces for a single thread.
class CallStack {
public:
- enum {
- // Prune the lowest-most stack frames until we have at most MAX_DEPTH.
- MAX_DEPTH = 31,
- // Placeholder for specifying the current thread when updating the stack.
- CURRENT_THREAD = -1,
- };
-
// Create an empty call stack. No-op.
CallStack();
// Create a callstack with the current thread's stack trace.
// Immediately dump it to logcat using the given logtag.
- CallStack(const char* logtag, int32_t ignoreDepth=1,
- int32_t maxDepth=MAX_DEPTH);
- // Copy the existing callstack (no other side effects).
- CallStack(const CallStack& rhs);
+ CallStack(const char* logtag, int32_t ignoreDepth=1);
~CallStack();
- // Copy the existing callstack (no other side effects).
- CallStack& operator = (const CallStack& rhs);
-
- // Compare call stacks by their backtrace frame memory.
- bool operator == (const CallStack& rhs) const;
- bool operator != (const CallStack& rhs) const;
- bool operator < (const CallStack& rhs) const;
- bool operator >= (const CallStack& rhs) const;
- bool operator > (const CallStack& rhs) const;
- bool operator <= (const CallStack& rhs) const;
-
- // Get the PC address for the stack frame specified by index.
- const void* operator [] (int index) const;
-
// Reset the stack frames (same as creating an empty call stack).
- void clear();
+ void clear() { mFrameLines.clear(); }
// Immediately collect the stack traces for the specified thread.
- void update(int32_t ignoreDepth=1, int32_t maxDepth=MAX_DEPTH, pid_t tid=CURRENT_THREAD);
+ // The default is to dump the stack of the current call.
+ void update(int32_t ignoreDepth=1, pid_t tid=BACKTRACE_NO_TID);
// Dump a stack trace to the log using the supplied logtag.
void log(const char* logtag,
@@ -83,11 +61,10 @@ public:
void print(Printer& printer) const;
// Get the count of stack frames that are in this call stack.
- size_t size() const { return mCount; }
+ size_t size() const { return mFrameLines.size(); }
private:
- size_t mCount;
- backtrace_frame_t mStack[MAX_DEPTH];
+ Vector<String8> mFrameLines;
};
}; // namespace android
diff --git a/include/utils/ProcessCallStack.h b/include/utils/ProcessCallStack.h
index 4a86869..32458b8 100644
--- a/include/utils/ProcessCallStack.h
+++ b/include/utils/ProcessCallStack.h
@@ -39,7 +39,7 @@ public:
~ProcessCallStack();
// Immediately collect the stack traces for all threads.
- void update(int32_t maxDepth = CallStack::MAX_DEPTH);
+ void update();
// Print all stack traces to the log using the supplied logtag.
void log(const char* logtag, android_LogPriority priority = ANDROID_LOG_DEBUG,
diff --git a/libutils/Android.mk b/libutils/Android.mk
index 720443e..1710d36 100644
--- a/libutils/Android.mk
+++ b/libutils/Android.mk
@@ -116,10 +116,12 @@ LOCAL_STATIC_LIBRARIES := \
libcutils
LOCAL_SHARED_LIBRARIES := \
- libcorkscrew \
+ libbacktrace \
liblog \
libdl
+include external/stlport/libstlport.mk
+
LOCAL_MODULE:= libutils
include $(BUILD_STATIC_LIBRARY)
@@ -129,10 +131,12 @@ include $(CLEAR_VARS)
LOCAL_MODULE:= libutils
LOCAL_WHOLE_STATIC_LIBRARIES := libutils
LOCAL_SHARED_LIBRARIES := \
- liblog \
+ libbacktrace \
libcutils \
libdl \
- libcorkscrew
+ liblog \
+
+include external/stlport/libstlport.mk
include $(BUILD_SHARED_LIBRARY)
diff --git a/libutils/CallStack.cpp b/libutils/CallStack.cpp
index 4ceaa7c..0bfb520 100644
--- a/libutils/CallStack.cpp
+++ b/libutils/CallStack.cpp
@@ -20,93 +20,33 @@
#include <utils/Printer.h>
#include <utils/Errors.h>
#include <utils/Log.h>
-#include <corkscrew/backtrace.h>
+#include <UniquePtr.h>
+
+#include <backtrace/Backtrace.h>
namespace android {
-CallStack::CallStack() :
- mCount(0) {
+CallStack::CallStack() {
}
-CallStack::CallStack(const char* logtag, int32_t ignoreDepth, int32_t maxDepth) {
- this->update(ignoreDepth+1, maxDepth, CURRENT_THREAD);
+CallStack::CallStack(const char* logtag, int32_t ignoreDepth) {
+ this->update(ignoreDepth+1);
this->log(logtag);
}
-CallStack::CallStack(const CallStack& rhs) :
- mCount(rhs.mCount) {
- if (mCount) {
- memcpy(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t));
- }
-}
-
CallStack::~CallStack() {
}
-CallStack& CallStack::operator = (const CallStack& rhs) {
- mCount = rhs.mCount;
- if (mCount) {
- memcpy(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t));
- }
- return *this;
-}
-
-bool CallStack::operator == (const CallStack& rhs) const {
- if (mCount != rhs.mCount)
- return false;
- return !mCount || memcmp(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)) == 0;
-}
-
-bool CallStack::operator != (const CallStack& rhs) const {
- return !operator == (rhs);
-}
-
-bool CallStack::operator < (const CallStack& rhs) const {
- if (mCount != rhs.mCount)
- return mCount < rhs.mCount;
- return memcmp(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)) < 0;
-}
+void CallStack::update(int32_t ignoreDepth, pid_t tid) {
+ mFrameLines.clear();
-bool CallStack::operator >= (const CallStack& rhs) const {
- return !operator < (rhs);
-}
-
-bool CallStack::operator > (const CallStack& rhs) const {
- if (mCount != rhs.mCount)
- return mCount > rhs.mCount;
- return memcmp(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)) > 0;
-}
-
-bool CallStack::operator <= (const CallStack& rhs) const {
- return !operator > (rhs);
-}
-
-const void* CallStack::operator [] (int index) const {
- if (index >= int(mCount))
- return 0;
- return reinterpret_cast<const void*>(mStack[index].absolute_pc);
-}
-
-void CallStack::clear() {
- mCount = 0;
-}
-
-void CallStack::update(int32_t ignoreDepth, int32_t maxDepth, pid_t tid) {
- if (maxDepth > MAX_DEPTH) {
- maxDepth = MAX_DEPTH;
+ UniquePtr<Backtrace> backtrace(Backtrace::Create(BACKTRACE_CURRENT_PROCESS, tid));
+ if (!backtrace->Unwind(ignoreDepth)) {
+ ALOGW("%s: Failed to unwind callstack.", __FUNCTION__);
}
- 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;
+ for (size_t i = 0; i < backtrace->NumFrames(); i++) {
+ mFrameLines.push_back(String8(backtrace->FormatFrameData(i).c_str()));
}
-
- mCount = count > 0 ? count : 0;
}
void CallStack::log(const char* logtag, android_LogPriority priority, const char* prefix) const {
@@ -129,16 +69,9 @@ String8 CallStack::toString(const char* prefix) const {
}
void CallStack::print(Printer& printer) const {
- backtrace_symbol_t symbols[mCount];
-
- 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);
- printer.printLine(line);
+ for (size_t i = 0; i < mFrameLines.size(); i++) {
+ printer.printLine(mFrameLines[i]);
}
- free_backtrace_symbols(symbols, mCount);
}
}; // namespace android
diff --git a/libutils/Printer.cpp b/libutils/Printer.cpp
index ac729e0..263e740 100644
--- a/libutils/Printer.cpp
+++ b/libutils/Printer.cpp
@@ -145,6 +145,7 @@ void String8Printer::printLine(const char* string) {
return;
}
+ mTarget->append(mPrefix);
mTarget->append(string);
mTarget->append("\n");
}
diff --git a/libutils/ProcessCallStack.cpp b/libutils/ProcessCallStack.cpp
index f9340c5..f837bcb 100644
--- a/libutils/ProcessCallStack.cpp
+++ b/libutils/ProcessCallStack.cpp
@@ -123,7 +123,7 @@ void ProcessCallStack::clear() {
mTimeUpdated = tm();
}
-void ProcessCallStack::update(int32_t maxDepth) {
+void ProcessCallStack::update() {
DIR *dp;
struct dirent *ep;
struct dirent entry;
@@ -181,14 +181,13 @@ void ProcessCallStack::update(int32_t maxDepth) {
int ignoreDepth = (selfPid == tid) ? IGNORE_DEPTH_CURRENT_THREAD : 0;
// Update thread's call stacks
- CallStack& cs = threadInfo.callStack;
- cs.update(ignoreDepth, maxDepth, tid);
+ threadInfo.callStack.update(ignoreDepth, tid);
// Read/save thread name
threadInfo.threadName = getThreadName(tid);
ALOGV("%s: Got call stack for tid %d (size %zu)",
- __FUNCTION__, tid, cs.size());
+ __FUNCTION__, tid, threadInfo.callStack.size());
}
if (code != 0) { // returns positive error value on error
ALOGE("%s: Failed to readdir from %s (errno = %d, '%s')",
@@ -221,13 +220,12 @@ void ProcessCallStack::printInternal(Printer& printer, Printer& csPrinter) const
for (size_t i = 0; i < mThreadMap.size(); ++i) {
pid_t tid = mThreadMap.keyAt(i);
const ThreadInfo& threadInfo = mThreadMap.valueAt(i);
- const CallStack& cs = threadInfo.callStack;
const String8& threadName = threadInfo.threadName;
printer.printLine("");
printer.printFormatLine("\"%s\" sysTid=%d", threadName.string(), tid);
- cs.print(csPrinter);
+ threadInfo.callStack.print(csPrinter);
}
dumpProcessFooter(printer, getpid());