am ac3ab308: Merge "Fix Mac OS build for libziparchive."

* commit 'ac3ab308f657f70e2747734d5ff2158aa943b25e':
  Fix Mac OS build for libziparchive.
diff --git a/adb/services.c b/adb/services.c
index f0d5878..951048e 100644
--- a/adb/services.c
+++ b/adb/services.c
@@ -144,7 +144,11 @@
     if (ret < 0) {
         snprintf(buf, sizeof(buf), "reboot failed: %d\n", ret);
         writex(fd, buf, strlen(buf));
+        goto cleanup;
     }
+    // Don't return early. Give the reboot command time to take effect
+    // to avoid messing up scripts which do "adb reboot && adb wait-for-device"
+    while(1) { pause(); }
 cleanup:
     free(arg);
     adb_close(fd);
diff --git a/include/utils/CallStack.h b/include/utils/CallStack.h
index 61dc832..2056751 100644
--- a/include/utils/CallStack.h
+++ b/include/utils/CallStack.h
@@ -17,50 +17,72 @@
 #ifndef ANDROID_CALLSTACK_H
 #define ANDROID_CALLSTACK_H
 
-#include <stdint.h>
-#include <sys/types.h>
-
+#include <android/log.h>
 #include <utils/String8.h>
 #include <corkscrew/backtrace.h>
 
-// ---------------------------------------------------------------------------
+#include <stdint.h>
+#include <sys/types.h>
 
 namespace android {
 
-class CallStack
-{
+class Printer;
+
+// Collect/print the call stack (function, file, line) traces for a single thread.
+class CallStack {
 public:
     enum {
-        MAX_DEPTH = 31
+        // 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();
 
+    // 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 update(int32_t ignoreDepth=1, int32_t maxDepth=MAX_DEPTH);
+    // 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);
 
-    // Dump a stack trace to the log using the supplied logtag
-    void dump(const char* logtag, const char* prefix = 0) const;
+    // Dump a stack trace to the log using the supplied logtag.
+    void log(const char* logtag,
+             android_LogPriority priority = ANDROID_LOG_DEBUG,
+             const char* prefix = 0) const;
 
-    // Return a string (possibly very long) containing the complete stack trace
+    // Dump a stack trace to the specified file descriptor.
+    void dump(int fd, int indent = 0, const char* prefix = 0) const;
+
+    // Return a string (possibly very long) containing the complete stack trace.
     String8 toString(const char* prefix = 0) const;
-    
+
+    // Dump a serialized representation of the stack trace to the specified printer.
+    void print(Printer& printer) const;
+
+    // Get the count of stack frames that are in this call stack.
     size_t size() const { return mCount; }
 
 private:
@@ -70,7 +92,4 @@
 
 }; // namespace android
 
-
-// ---------------------------------------------------------------------------
-
 #endif // ANDROID_CALLSTACK_H
diff --git a/include/utils/Printer.h b/include/utils/Printer.h
new file mode 100644
index 0000000..bb66287
--- /dev/null
+++ b/include/utils/Printer.h
@@ -0,0 +1,119 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_PRINTER_H
+#define ANDROID_PRINTER_H
+
+#include <android/log.h>
+
+namespace android {
+
+// Interface for printing to an arbitrary data stream
+class Printer {
+public:
+    // Print a new line specified by 'string'. \n is appended automatically.
+    // -- Assumes that the string has no new line in it.
+    virtual void printLine(const char* string = "") = 0;
+
+    // Print a new line specified by the format string. \n is appended automatically.
+    // -- Assumes that the resulting string has no new line in it.
+    virtual void printFormatLine(const char* format, ...) __attribute__((format (printf, 2, 3)));
+
+protected:
+    Printer();
+    virtual ~Printer();
+}; // class Printer
+
+// Print to logcat
+class LogPrinter : public Printer {
+public:
+    // Create a printer using the specified logcat and log priority
+    // - Unless ignoreBlankLines is false, print blank lines to logcat
+    // (Note that the default ALOG behavior is to ignore blank lines)
+    LogPrinter(const char* logtag,
+               android_LogPriority priority = ANDROID_LOG_DEBUG,
+               const char* prefix = 0,
+               bool ignoreBlankLines = false);
+
+    // Print the specified line to logcat. No \n at the end is necessary.
+    virtual void printLine(const char* string);
+
+private:
+    void printRaw(const char* string);
+
+    const char* mLogTag;
+    android_LogPriority mPriority;
+    const char* mPrefix;
+    bool mIgnoreBlankLines;
+}; // class LogPrinter
+
+// Print to a file descriptor
+class FdPrinter : public Printer {
+public:
+    // Create a printer using the specified file descriptor.
+    // - Each line will be prefixed with 'indent' number of blank spaces.
+    // - In addition, each line will be prefixed with the 'prefix' string.
+    FdPrinter(int fd, unsigned int indent = 0, const char* prefix = 0);
+
+    // Print the specified line to the file descriptor. \n is appended automatically.
+    virtual void printLine(const char* string);
+
+private:
+    enum {
+        MAX_FORMAT_STRING = 20,
+    };
+
+    int mFd;
+    unsigned int mIndent;
+    const char* mPrefix;
+    char mFormatString[MAX_FORMAT_STRING];
+}; // class FdPrinter
+
+class String8;
+
+// Print to a String8
+class String8Printer : public Printer {
+public:
+    // Create a printer using the specified String8 as the target.
+    // - In addition, each line will be prefixed with the 'prefix' string.
+    // - target's memory lifetime must be a superset of this String8Printer.
+    String8Printer(String8* target, const char* prefix = 0);
+
+    // Append the specified line to the String8. \n is appended automatically.
+    virtual void printLine(const char* string);
+
+private:
+    String8* mTarget;
+    const char* mPrefix;
+}; // class String8Printer
+
+// Print to an existing Printer by adding a prefix to each line
+class PrefixPrinter : public Printer {
+public:
+    // Create a printer using the specified printer as the target.
+    PrefixPrinter(Printer& printer, const char* prefix);
+
+    // Print the line (prefixed with prefix) using the printer.
+    virtual void printLine(const char* string);
+
+private:
+    Printer& mPrinter;
+    const char* mPrefix;
+};
+
+}; // namespace android
+
+#endif // ANDROID_PRINTER_H
diff --git a/include/utils/ProcessCallStack.h b/include/utils/ProcessCallStack.h
new file mode 100644
index 0000000..4a86869
--- /dev/null
+++ b/include/utils/ProcessCallStack.h
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_PROCESS_CALLSTACK_H
+#define ANDROID_PROCESS_CALLSTACK_H
+
+#include <utils/CallStack.h>
+#include <android/log.h>
+#include <utils/KeyedVector.h>
+#include <utils/String8.h>
+
+#include <time.h>
+#include <sys/types.h>
+
+namespace android {
+
+class Printer;
+
+// Collect/print the call stack (function, file, line) traces for all threads in a process.
+class ProcessCallStack {
+public:
+    // Create an empty call stack. No-op.
+    ProcessCallStack();
+    // Copy the existing process callstack (no other side effects).
+    ProcessCallStack(const ProcessCallStack& rhs);
+    ~ProcessCallStack();
+
+    // Immediately collect the stack traces for all threads.
+    void update(int32_t maxDepth = CallStack::MAX_DEPTH);
+
+    // Print all stack traces to the log using the supplied logtag.
+    void log(const char* logtag, android_LogPriority priority = ANDROID_LOG_DEBUG,
+             const char* prefix = 0) const;
+
+    // Dump all stack traces to the specified file descriptor.
+    void dump(int fd, int indent = 0, const char* prefix = 0) const;
+
+    // Return a string (possibly very long) containing all the stack traces.
+    String8 toString(const char* prefix = 0) const;
+
+    // Dump a serialized representation of all the stack traces to the specified printer.
+    void print(Printer& printer) const;
+
+    // Get the number of threads whose stack traces were collected.
+    size_t size() const;
+
+private:
+    void printInternal(Printer& printer, Printer& csPrinter) const;
+
+    // Reset the process's stack frames and metadata.
+    void clear();
+
+    struct ThreadInfo {
+        CallStack callStack;
+        String8 threadName;
+    };
+
+    // tid -> ThreadInfo
+    KeyedVector<pid_t, ThreadInfo> mThreadMap;
+    // Time that update() was last called
+    struct tm mTimeUpdated;
+};
+
+}; // namespace android
+
+#endif // ANDROID_PROCESS_CALLSTACK_H
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..ac729e0
--- /dev/null
+++ b/libutils/Printer.cpp
@@ -0,0 +1,163 @@
+/*
+ * 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;
+
+#ifndef USE_MINGW
+    if (vasprintf(&formattedString, format, arglist) < 0) { // returns -1 on error
+        ALOGE("%s: Failed to format string", __FUNCTION__);
+        return;
+    }
+#else
+    return;
+#endif
+
+    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;
+    }
+
+#ifndef USE_MINGW
+    fdprintf(mFd, mFormatString, mPrefix, string);
+#endif
+}
+
+/*
+ * 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..f9340c5
--- /dev/null
+++ b/libutils/ProcessCallStack.cpp
@@ -0,0 +1,260 @@
+/*
+ * 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>
+
+#include <limits.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.
+#ifndef USE_MINGW
+    {
+        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));
+    }
+#endif
+
+    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
diff --git a/libutils/VectorImpl.cpp b/libutils/VectorImpl.cpp
index 5a79647..30ca663 100644
--- a/libutils/VectorImpl.cpp
+++ b/libutils/VectorImpl.cpp
@@ -384,7 +384,11 @@
         {
             const SharedBuffer* cur_sb = SharedBuffer::bufferFromData(mStorage);
             SharedBuffer* sb = cur_sb->editResize(new_capacity * mItemSize);
-            mStorage = sb->data();
+            if (sb) {
+                mStorage = sb->data();
+            } else {
+                return NULL;
+            }
         } else {
             SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize);
             if (sb) {
@@ -399,6 +403,8 @@
                 }
                 release_storage();
                 mStorage = const_cast<void*>(array);
+            } else {
+                return NULL;
             }
         }
     } else {
@@ -436,7 +442,11 @@
         {
             const SharedBuffer* cur_sb = SharedBuffer::bufferFromData(mStorage);
             SharedBuffer* sb = cur_sb->editResize(new_capacity * mItemSize);
-            mStorage = sb->data();
+            if (sb) {
+                mStorage = sb->data();
+            } else {
+                return;
+            }
         } else {
             SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize);
             if (sb) {
@@ -451,6 +461,8 @@
                 }
                 release_storage();
                 mStorage = const_cast<void*>(array);
+            } else{
+                return;
             }
         }
     } else {
diff --git a/reboot/reboot.c b/reboot/reboot.c
index 0e5170d..d9a4227 100644
--- a/reboot/reboot.c
+++ b/reboot/reboot.c
@@ -68,6 +68,11 @@
         perror("reboot");
         exit(EXIT_FAILURE);
     }
+
+    // Don't return early. Give the reboot command time to take effect
+    // to avoid messing up scripts which do "adb shell reboot && adb wait-for-device"
+    while(1) { pause(); }
+
     fprintf(stderr, "Done\n");
     return 0;
 }
diff --git a/rootdir/init.rc b/rootdir/init.rc
index cfc3d35..109f15b 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -69,8 +69,6 @@
 
     # Directory for putting things only root should see.
     mkdir /mnt/secure 0700 root root
-    # Create private mountpoint so we can MS_MOVE from staging
-    mount tmpfs tmpfs /mnt/secure mode=0700,uid=0,gid=0
 
     # Directory for staging bindmounts
     mkdir /mnt/secure/staging 0700 root root
@@ -146,7 +144,6 @@
     mount rootfs rootfs / ro remount
     # mount shared so changes propagate into child namespaces
     mount rootfs rootfs / shared rec
-    mount tmpfs tmpfs /mnt/secure private rec
 
     # We chown/chmod /cache again so because mount is run as root + defaults
     chown system cache /cache