diff options
author | Christopher Ferris <cferris@google.com> | 2014-01-09 23:48:26 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2014-01-09 23:48:26 +0000 |
commit | c49bd655e5233f367c535ed4324bbadc4aea5453 (patch) | |
tree | 82b9c16d470b1d8c4ab283994a9e213eec9abb45 | |
parent | 3794c96f3e7bb27e56336035bcd7ac643c6869fc (diff) | |
parent | 5d2ec87bf54dc8a02e6bcbe5848fd378056b8f78 (diff) | |
download | system_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.h | 39 | ||||
-rw-r--r-- | include/utils/ProcessCallStack.h | 2 | ||||
-rw-r--r-- | libutils/Android.mk | 10 | ||||
-rw-r--r-- | libutils/CallStack.cpp | 97 | ||||
-rw-r--r-- | libutils/Printer.cpp | 1 | ||||
-rw-r--r-- | libutils/ProcessCallStack.cpp | 10 |
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()); |