diff --git a/libutils/Android.mk b/libutils/Android.mk
index 7e6b1be..720443e 100644
--- a/libutils/Android.mk
+++ b/libutils/Android.mk
@@ -26,6 +26,8 @@
 	LinearAllocator.cpp \
 	LinearTransform.cpp \
 	Log.cpp \
+	Printer.cpp \
+	ProcessCallStack.cpp \
 	PropertyMap.cpp \
 	RefBase.cpp \
 	SharedBuffer.cpp \
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(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 @@
     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 @@
         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
diff --git a/libutils/Printer.cpp b/libutils/Printer.cpp
new file mode 100644
index 0000000..b062ef0
--- /dev/null
+++ b/libutils/Printer.cpp
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "Printer"
+// #define LOG_NDEBUG 0
+
+#include <utils/Printer.h>
+#include <utils/String8.h>
+#include <utils/Log.h>
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifndef __BIONIC__
+#define fdprintf dprintf
+#endif
+
+namespace android {
+
+/*
+ * Implementation of Printer
+ */
+Printer::Printer() {
+    // Intentionally left empty
+}
+
+Printer::~Printer() {
+    // Intentionally left empty
+}
+
+void Printer::printFormatLine(const char* format, ...) {
+    va_list arglist;
+    va_start(arglist, format);
+
+    char* formattedString;
+    if (vasprintf(&formattedString, format, arglist) < 0) { // returns -1 on error
+        ALOGE("%s: Failed to format string", __FUNCTION__);
+        return;
+    }
+    va_end(arglist);
+
+    printLine(formattedString);
+    free(formattedString);
+}
+
+/*
+ * Implementation of LogPrinter
+ */
+LogPrinter::LogPrinter(const char* logtag,
+                       android_LogPriority priority,
+                       const char* prefix,
+                       bool ignoreBlankLines) :
+        mLogTag(logtag),
+        mPriority(priority),
+        mPrefix(prefix ?: ""),
+        mIgnoreBlankLines(ignoreBlankLines) {
+}
+
+void LogPrinter::printLine(const char* string) {
+    if (string == NULL) {
+        ALOGW("%s: NULL string passed in", __FUNCTION__);
+        return;
+    }
+
+    if (mIgnoreBlankLines || (*string)) {
+        // Simple case: Line is not blank, or we don't care about printing blank lines
+        printRaw(string);
+    } else {
+        // Force logcat to print empty lines by adding prefixing with a space
+        printRaw(" ");
+    }
+}
+
+void LogPrinter::printRaw(const char* string) {
+    __android_log_print(mPriority, mLogTag, "%s%s", mPrefix, string);
+}
+
+
+/*
+ * Implementation of FdPrinter
+ */
+FdPrinter::FdPrinter(int fd, unsigned int indent, const char* prefix) :
+        mFd(fd), mIndent(indent), mPrefix(prefix ?: "") {
+
+    if (fd < 0) {
+        ALOGW("%s: File descriptor out of range (%d)", __FUNCTION__, fd);
+    }
+
+    // <indent><prefix><line> -- e.g. '%-4s%s\n' for indent=4
+    snprintf(mFormatString, sizeof(mFormatString), "%%-%us%%s\n", mIndent);
+}
+
+void FdPrinter::printLine(const char* string) {
+    if (string == NULL) {
+        ALOGW("%s: NULL string passed in", __FUNCTION__);
+        return;
+    } else if (mFd < 0) {
+        ALOGW("%s: File descriptor out of range (%d)", __FUNCTION__, mFd);
+        return;
+    }
+
+    fdprintf(mFd, mFormatString, mPrefix, string);
+}
+
+/*
+ * Implementation of String8Printer
+ */
+String8Printer::String8Printer(String8* target, const char* prefix) :
+        mTarget(target),
+        mPrefix(prefix ?: "") {
+
+    if (target == NULL) {
+        ALOGW("%s: Target string was NULL", __FUNCTION__);
+    }
+}
+
+void String8Printer::printLine(const char* string) {
+    if (string == NULL) {
+        ALOGW("%s: NULL string passed in", __FUNCTION__);
+        return;
+    } else if (mTarget == NULL) {
+        ALOGW("%s: Target string was NULL", __FUNCTION__);
+        return;
+    }
+
+    mTarget->append(string);
+    mTarget->append("\n");
+}
+
+/*
+ * Implementation of PrefixPrinter
+ */
+PrefixPrinter::PrefixPrinter(Printer& printer, const char* prefix) :
+        mPrinter(printer), mPrefix(prefix ?: "") {
+}
+
+void PrefixPrinter::printLine(const char* string) {
+    mPrinter.printFormatLine("%s%s", mPrefix, string);
+}
+
+}; //namespace android
diff --git a/libutils/ProcessCallStack.cpp b/libutils/ProcessCallStack.cpp
new file mode 100644
index 0000000..ed35237
--- /dev/null
+++ b/libutils/ProcessCallStack.cpp
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "ProcessCallStack"
+// #define LOG_NDEBUG 0
+
+#include <string.h>
+#include <stdio.h>
+#include <dirent.h>
+
+#include <utils/Log.h>
+#include <utils/Errors.h>
+#include <utils/ProcessCallStack.h>
+#include <utils/Printer.h>
+
+namespace android {
+
+enum {
+    // Max sizes for various dynamically generated strings
+    MAX_TIME_STRING = 64,
+    MAX_PROC_PATH = 1024,
+
+    // Dump related prettiness constants
+    IGNORE_DEPTH_CURRENT_THREAD = 2,
+};
+
+static const char* CALL_STACK_PREFIX = "  ";
+static const char* PATH_THREAD_NAME = "/proc/self/task/%d/comm";
+static const char* PATH_SELF_TASK = "/proc/self/task";
+
+static void dumpProcessHeader(Printer& printer, pid_t pid, const char* timeStr) {
+    if (timeStr == NULL) {
+        ALOGW("%s: timeStr was NULL", __FUNCTION__);
+        return;
+    }
+
+    char path[PATH_MAX];
+    char procNameBuf[MAX_PROC_PATH];
+    char* procName = NULL;
+    FILE* fp;
+
+    snprintf(path, sizeof(path), "/proc/%d/cmdline", pid);
+    if ((fp = fopen(path, "r"))) {
+        procName = fgets(procNameBuf, sizeof(procNameBuf), fp);
+        fclose(fp);
+    }
+
+    if (!procName) {
+        procName = const_cast<char*>("<unknown>");
+    }
+
+    printer.printLine();
+    printer.printLine();
+    printer.printFormatLine("----- pid %d at %s -----", pid, timeStr);
+    printer.printFormatLine("Cmd line: %s", procName);
+}
+
+static void dumpProcessFooter(Printer& printer, pid_t pid) {
+    printer.printLine();
+    printer.printFormatLine("----- end %d -----", pid);
+    printer.printLine();
+}
+
+static String8 getThreadName(pid_t tid) {
+    char path[PATH_MAX];
+    char* procName = NULL;
+    char procNameBuf[MAX_PROC_PATH];
+    FILE* fp;
+
+    snprintf(path, sizeof(path), PATH_THREAD_NAME, tid);
+    if ((fp = fopen(path, "r"))) {
+        procName = fgets(procNameBuf, sizeof(procNameBuf), fp);
+        fclose(fp);
+    } else {
+        ALOGE("%s: Failed to open %s", __FUNCTION__, path);
+    }
+
+    // Strip ending newline
+    strtok(procName, "\n");
+
+    return String8(procName);
+}
+
+static String8 getTimeString(struct tm tm) {
+    char timestr[MAX_TIME_STRING];
+    // i.e. '2013-10-22 14:42:05'
+    strftime(timestr, sizeof(timestr), "%F %T", &tm);
+
+    return String8(timestr);
+}
+
+/*
+ * Implementation of ProcessCallStack
+ */
+ProcessCallStack::ProcessCallStack() {
+}
+
+ProcessCallStack::ProcessCallStack(const ProcessCallStack& rhs) :
+        mThreadMap(rhs.mThreadMap),
+        mTimeUpdated(rhs.mTimeUpdated) {
+}
+
+ProcessCallStack::~ProcessCallStack() {
+}
+
+void ProcessCallStack::clear() {
+    mThreadMap.clear();
+    mTimeUpdated = tm();
+}
+
+void ProcessCallStack::update(int32_t maxDepth) {
+    DIR *dp;
+    struct dirent *ep;
+    struct dirent entry;
+
+    dp = opendir(PATH_SELF_TASK);
+    if (dp == NULL) {
+        ALOGE("%s: Failed to update the process's call stacks (errno = %d, '%s')",
+              __FUNCTION__, errno, strerror(errno));
+        return;
+    }
+
+    pid_t selfPid = getpid();
+
+    clear();
+
+    // Get current time.
+    {
+        time_t t = time(NULL);
+        struct tm tm;
+        localtime_r(&t, &tm);
+
+        mTimeUpdated = tm;
+    }
+
+    /*
+     * Each tid is a directory inside of /proc/self/task
+     * - Read every file in directory => get every tid
+     */
+    int code;
+    while ((code = readdir_r(dp, &entry, &ep)) == 0 && ep != NULL) {
+        pid_t tid = -1;
+        sscanf(ep->d_name, "%d", &tid);
+
+        if (tid < 0) {
+            // Ignore '.' and '..'
+            ALOGV("%s: Failed to read tid from %s/%s",
+                  __FUNCTION__, PATH_SELF_TASK, ep->d_name);
+            continue;
+        }
+
+        ssize_t idx = mThreadMap.add(tid, ThreadInfo());
+        if (idx < 0) { // returns negative error value on error
+            ALOGE("%s: Failed to add new ThreadInfo (errno = %zd, '%s')",
+                  __FUNCTION__, idx, strerror(-idx));
+            continue;
+        }
+
+        ThreadInfo& threadInfo = mThreadMap.editValueAt(static_cast<size_t>(idx));
+
+        /*
+         * Ignore CallStack::update and ProcessCallStack::update for current thread
+         * - Every other thread doesn't need this since we call update off-thread
+         */
+        int ignoreDepth = (selfPid == tid) ? IGNORE_DEPTH_CURRENT_THREAD : 0;
+
+        // Update thread's call stacks
+        CallStack& cs = threadInfo.callStack;
+        cs.update(ignoreDepth, maxDepth, tid);
+
+        // Read/save thread name
+        threadInfo.threadName = getThreadName(tid);
+
+        ALOGV("%s: Got call stack for tid %d (size %zu)",
+              __FUNCTION__, tid, cs.size());
+    }
+    if (code != 0) { // returns positive error value on error
+        ALOGE("%s: Failed to readdir from %s (errno = %d, '%s')",
+              __FUNCTION__, PATH_SELF_TASK, -code, strerror(code));
+    }
+
+    closedir(dp);
+}
+
+void ProcessCallStack::log(const char* logtag, android_LogPriority priority,
+                           const char* prefix) const {
+    LogPrinter printer(logtag, priority, prefix, /*ignoreBlankLines*/false);
+    print(printer);
+}
+
+void ProcessCallStack::print(Printer& printer) const {
+    /*
+     * Print the header/footer with the regular printer.
+     * Print the callstack with an additional two spaces as the prefix for legibility.
+     */
+    PrefixPrinter csPrinter(printer, CALL_STACK_PREFIX);
+    printInternal(printer, csPrinter);
+}
+
+void ProcessCallStack::printInternal(Printer& printer, Printer& csPrinter) const {
+    dumpProcessHeader(printer, getpid(),
+                      getTimeString(mTimeUpdated).string());
+
+    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);
+    }
+
+    dumpProcessFooter(printer, getpid());
+}
+
+void ProcessCallStack::dump(int fd, int indent, const char* prefix) const {
+
+    if (indent < 0) {
+        ALOGW("%s: Bad indent (%d)", __FUNCTION__, indent);
+        return;
+    }
+
+    FdPrinter printer(fd, static_cast<unsigned int>(indent), prefix);
+    print(printer);
+}
+
+String8 ProcessCallStack::toString(const char* prefix) const {
+
+    String8 dest;
+    String8Printer printer(&dest, prefix);
+    print(printer);
+
+    return dest;
+}
+
+size_t ProcessCallStack::size() const {
+    return mThreadMap.size();
+}
+
+}; //namespace android
