Merge "adb: rationalize fatal/error logging."
diff --git a/fs_mgr/fs_mgr_overlayfs.cpp b/fs_mgr/fs_mgr_overlayfs.cpp
index 6067a7d..64e9fb4 100644
--- a/fs_mgr/fs_mgr_overlayfs.cpp
+++ b/fs_mgr/fs_mgr_overlayfs.cpp
@@ -449,8 +449,10 @@
     if (!fs_mgr_access(top)) return fs_mgr_overlayfs_teardown_scratch(overlay, change);
 
     auto cleanup_all = mount_point.empty();
-    const auto oldpath = top + (cleanup_all ? "" : ("/" + mount_point));
-    const auto newpath = oldpath + ".teardown";
+    const auto partition_name = android::base::Basename(mount_point);
+    const auto oldpath = top + (cleanup_all ? "" : ("/" + partition_name));
+    const auto newpath = cleanup_all ? overlay + "/." + kOverlayTopDir.substr(1) + ".teardown"
+                                     : top + "/." + partition_name + ".teardown";
     auto ret = fs_mgr_rm_all(newpath);
     auto save_errno = errno;
     if (!rename(oldpath.c_str(), newpath.c_str())) {
@@ -476,12 +478,28 @@
         if (!rmdir(top.c_str())) {
             if (change) *change = true;
             cleanup_all = true;
-        } else if ((errno != ENOENT) && (errno != ENOTEMPTY)) {
+        } else if (errno == ENOTEMPTY) {
+            cleanup_all = true;
+            // cleanup all if the content is all hidden (leading .)
+            std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(top.c_str()), closedir);
+            if (!dir) {
+                PERROR << "opendir " << top;
+            } else {
+                dirent* entry;
+                while ((entry = readdir(dir.get()))) {
+                    if (entry->d_name[0] != '.') {
+                        cleanup_all = false;
+                        break;
+                    }
+                }
+            }
+            errno = save_errno;
+        } else if (errno == ENOENT) {
+            cleanup_all = true;
+            errno = save_errno;
+        } else {
             ret = false;
             PERROR << "rmdir " << top;
-        } else {
-            errno = save_errno;
-            cleanup_all = true;
         }
     }
     if (cleanup_all) ret &= fs_mgr_overlayfs_teardown_scratch(overlay, change);
diff --git a/init/init.cpp b/init/init.cpp
index 42ec88c..b12ba8c 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -61,6 +61,10 @@
 #include "ueventd.h"
 #include "util.h"
 
+#if __has_feature(address_sanitizer)
+#include <sanitizer/asan_interface.h>
+#endif
+
 using namespace std::chrono_literals;
 using namespace std::string_literals;
 
@@ -74,6 +78,25 @@
 namespace android {
 namespace init {
 
+#if __has_feature(address_sanitizer)
+// Load asan.options if it exists since these are not yet in the environment.
+// Always ensure detect_container_overflow=0 as there are false positives with this check.
+// Always ensure abort_on_error=1 to ensure we reboot to bootloader for development builds.
+extern "C" const char* __asan_default_options() {
+    return "include_if_exists=/system/asan.options:detect_container_overflow=0:abort_on_error=1";
+}
+
+__attribute__((no_sanitize("address", "memory", "thread", "undefined"))) extern "C" void
+__sanitizer_report_error_summary(const char* summary) {
+    LOG(ERROR) << "Main stage (error summary): " << summary;
+}
+
+__attribute__((no_sanitize("address", "memory", "thread", "undefined"))) static void
+AsanReportCallback(const char* str) {
+    LOG(ERROR) << "Main stage: " << str;
+}
+#endif
+
 static int property_triggers_enabled = 0;
 
 static char qemu[32];
@@ -619,6 +642,10 @@
 }
 
 int main(int argc, char** argv) {
+#if __has_feature(address_sanitizer)
+    __asan_set_error_report_callback(AsanReportCallback);
+#endif
+
     if (!strcmp(basename(argv[0]), "ueventd")) {
         return ueventd_main(argc, argv);
     }
diff --git a/logcat/logcat.cpp b/logcat/logcat.cpp
index 115b1a3..87bc6ae 100644
--- a/logcat/logcat.cpp
+++ b/logcat/logcat.cpp
@@ -478,10 +478,10 @@
                     "  -G <size>, --buffer-size=<size>\n"
                     "                  Set size of log ring buffer, may suffix with K or M.\n"
                     "  -L, --last      Dump logs from prior to last reboot\n"
-                    // Leave security (Device Owner only installations) and
-                    // kernel (userdebug and eng) buffers undocumented.
                     "  -b <buffer>, --buffer=<buffer>         Request alternate ring buffer, 'main',\n"
                     "                  'system', 'radio', 'events', 'crash', 'default' or 'all'.\n"
+                    "                  Additionally, 'kernel' for userdebug and eng builds, and\n"
+                    "                  'security' for Device Owner installations.\n"
                     "                  Multiple -b parameters or comma separated list of buffers are\n"
                     "                  allowed. Buffers interleaved. Default -b main,system,crash.\n"
                     "  -B, --binary    Output the log in binary.\n"
diff --git a/logd/LogReader.cpp b/logd/LogReader.cpp
index 13c7af3..9db8c00 100644
--- a/logd/LogReader.cpp
+++ b/logd/LogReader.cpp
@@ -212,6 +212,10 @@
         cli->getUid(), cli->getGid(), cli->getPid(), nonBlock ? 'n' : 'b', tail,
         logMask, (int)pid, sequence.nsec(), timeout);
 
+    if (sequence == log_time::EPOCH) {
+        timeout = 0;
+    }
+
     LogTimeEntry::wrlock();
     auto entry = std::make_unique<LogTimeEntry>(
         *this, cli, nonBlock, tail, logMask, pid, sequence, timeout);