Merge "GCC compiler warning fix for sprintf into snprintf"
diff --git a/adb/commandline.cpp b/adb/commandline.cpp
index d8b1654..45c6142 100644
--- a/adb/commandline.cpp
+++ b/adb/commandline.cpp
@@ -1613,6 +1613,11 @@
     else if (!strcmp(argv[0], "exec-in") || !strcmp(argv[0], "exec-out")) {
         int exec_in = !strcmp(argv[0], "exec-in");
 
+        if (argc < 2) {
+            fprintf(stderr, "Usage: adb %s command\n", argv[0]);
+            return 1;
+        }
+
         std::string cmd = "exec:";
         cmd += argv[1];
         argc -= 2;
diff --git a/adb/transport.cpp b/adb/transport.cpp
index 1cf4c49..55082a5 100644
--- a/adb/transport.cpp
+++ b/adb/transport.cpp
@@ -613,7 +613,6 @@
     t->ref_count--;
     if (t->ref_count == 0) {
         D("transport: %s unref (kicking and closing)", t->serial);
-        t->Kick();
         t->close(t);
         remove_transport(t);
     } else {
diff --git a/adb/usb_linux_client.cpp b/adb/usb_linux_client.cpp
index c863ed2..0ba6b4b 100644
--- a/adb/usb_linux_client.cpp
+++ b/adb/usb_linux_client.cpp
@@ -31,6 +31,9 @@
 #include <unistd.h>
 
 #include <algorithm>
+#include <atomic>
+
+#include <android-base/logging.h>
 
 #include "adb.h"
 #include "transport.h"
@@ -49,14 +52,19 @@
 #define cpu_to_le16(x)  htole16(x)
 #define cpu_to_le32(x)  htole32(x)
 
+static int dummy_fd = -1;
+
 struct usb_handle
 {
     adb_cond_t notify;
     adb_mutex_t lock;
+    bool open_new_connection;
+    std::atomic<bool> kicked;
 
     int (*write)(usb_handle *h, const void *data, int len);
     int (*read)(usb_handle *h, void *data, int len);
     void (*kick)(usb_handle *h);
+    void (*close)(usb_handle *h);
 
     // Legacy f_adb
     int fd;
@@ -241,8 +249,10 @@
     while (true) {
         // wait until the USB device needs opening
         adb_mutex_lock(&usb->lock);
-        while (usb->fd != -1)
+        while (!usb->open_new_connection) {
             adb_cond_wait(&usb->notify, &usb->lock);
+        }
+        usb->open_new_connection = false;
         adb_mutex_unlock(&usb->lock);
 
         D("[ usb_thread - opening device ]");
@@ -281,6 +291,10 @@
             h->fd, n, errno, strerror(errno));
         return -1;
     }
+    if (h->kicked) {
+        D("usb_adb_write finished due to kicked");
+        return -1;
+    }
     D("[ done fd=%d ]", h->fd);
     return 0;
 }
@@ -299,6 +313,10 @@
                 h->fd, n, errno, strerror(errno));
             return -1;
         }
+        if (h->kicked) {
+            D("usb_adb_read finished due to kicked");
+            return -1;
+        }
         len -= n;
         data = ((char*)data) + n;
     }
@@ -306,14 +324,23 @@
     return 0;
 }
 
-static void usb_adb_kick(usb_handle *h)
-{
+static void usb_adb_kick(usb_handle *h) {
     D("usb_kick");
-    adb_mutex_lock(&h->lock);
-    unix_close(h->fd);
-    h->fd = -1;
+    // Other threads may be calling usb_adb_read/usb_adb_write at the same time.
+    // If we close h->fd, the file descriptor will be reused to open other files,
+    // and the read/write thread may operate on the wrong file. So instead
+    // we set the kicked flag and reopen h->fd to a dummy file here. After read/write
+    // threads finish, we close h->fd in usb_adb_close().
+    h->kicked = true;
+    TEMP_FAILURE_RETRY(dup2(dummy_fd, h->fd));
+}
 
-    // notify usb_adb_open_thread that we are disconnected
+static void usb_adb_close(usb_handle *h) {
+    h->kicked = false;
+    adb_close(h->fd);
+    // Notify usb_adb_open_thread to open a new connection.
+    adb_mutex_lock(&h->lock);
+    h->open_new_connection = true;
     adb_cond_signal(&h->notify);
     adb_mutex_unlock(&h->lock);
 }
@@ -326,8 +353,11 @@
     h->write = usb_adb_write;
     h->read = usb_adb_read;
     h->kick = usb_adb_kick;
+    h->close = usb_adb_close;
+    h->kicked = false;
     h->fd = -1;
 
+    h->open_new_connection = true;
     adb_cond_init(&h->notify, 0);
     adb_mutex_init(&h->lock, 0);
 
@@ -350,7 +380,7 @@
 }
 
 
-static void init_functionfs(struct usb_handle *h)
+static bool init_functionfs(struct usb_handle *h)
 {
     ssize_t ret;
     struct desc_v1 v1_descriptor;
@@ -413,7 +443,7 @@
         goto err;
     }
 
-    return;
+    return true;
 
 err:
     if (h->bulk_in > 0) {
@@ -428,7 +458,7 @@
         adb_close(h->control);
         h->control = -1;
     }
-    return;
+    return false;
 }
 
 static void usb_ffs_open_thread(void* x) {
@@ -439,16 +469,16 @@
     while (true) {
         // wait until the USB device needs opening
         adb_mutex_lock(&usb->lock);
-        while (usb->control != -1 && usb->bulk_in != -1 && usb->bulk_out != -1)
+        while (!usb->open_new_connection) {
             adb_cond_wait(&usb->notify, &usb->lock);
+        }
+        usb->open_new_connection = false;
         adb_mutex_unlock(&usb->lock);
 
         while (true) {
-            init_functionfs(usb);
-
-            if (usb->control >= 0 && usb->bulk_in >= 0 && usb->bulk_out >= 0)
+            if (init_functionfs(usb)) {
                 break;
-
+            }
             adb_sleep_ms(1000);
         }
         property_set("sys.usb.ffs.ready", "1");
@@ -513,16 +543,22 @@
         D("[ kick: sink (fd=%d) clear halt failed (%d) ]", h->bulk_out, errno);
     }
 
-    adb_mutex_lock(&h->lock);
-
     // don't close ep0 here, since we may not need to reinitialize it with
     // the same descriptors again. if however ep1/ep2 fail to re-open in
     // init_functionfs, only then would we close and open ep0 again.
+    // Ditto the comment in usb_adb_kick.
+    h->kicked = true;
+    TEMP_FAILURE_RETRY(dup2(dummy_fd, h->bulk_out));
+    TEMP_FAILURE_RETRY(dup2(dummy_fd, h->bulk_in));
+}
+
+static void usb_ffs_close(usb_handle *h) {
+    h->kicked = false;
     adb_close(h->bulk_out);
     adb_close(h->bulk_in);
-    h->bulk_out = h->bulk_in = -1;
-
-    // notify usb_ffs_open_thread that we are disconnected
+    // Notify usb_adb_open_thread to open a new connection.
+    adb_mutex_lock(&h->lock);
+    h->open_new_connection = true;
     adb_cond_signal(&h->notify);
     adb_mutex_unlock(&h->lock);
 }
@@ -537,10 +573,13 @@
     h->write = usb_ffs_write;
     h->read = usb_ffs_read;
     h->kick = usb_ffs_kick;
+    h->close = usb_ffs_close;
+    h->kicked = false;
     h->control = -1;
     h->bulk_out = -1;
     h->bulk_out = -1;
 
+    h->open_new_connection = true;
     adb_cond_init(&h->notify, 0);
     adb_mutex_init(&h->lock, 0);
 
@@ -552,6 +591,8 @@
 
 void usb_init()
 {
+    dummy_fd = adb_open("/dev/null", O_WRONLY);
+    CHECK_NE(dummy_fd, -1);
     if (access(USB_FFS_ADB_EP0, F_OK) == 0)
         usb_ffs_init();
     else
@@ -569,6 +610,7 @@
 }
 int usb_close(usb_handle *h)
 {
+    h->close(h);
     return 0;
 }
 
diff --git a/adb/usb_osx.cpp b/adb/usb_osx.cpp
index 54d4c6c..ddde454 100644
--- a/adb/usb_osx.cpp
+++ b/adb/usb_osx.cpp
@@ -29,86 +29,96 @@
 #include <inttypes.h>
 #include <stdio.h>
 
+#include <atomic>
+#include <memory>
+#include <mutex>
+#include <vector>
+
 #include <android-base/logging.h>
 #include <android-base/stringprintf.h>
 
 #include "adb.h"
 #include "transport.h"
 
-#define  DBG   D
-
-// There's no strerror equivalent for the errors returned by IOKit.
-// https://developer.apple.com/library/mac/documentation/DeviceDrivers/Conceptual/AccessingHardware/AH_Handling_Errors/AH_Handling_Errors.html
-// Search the web for "IOReturn.h" to find a complete up to date list.
-
-static IONotificationPortRef    notificationPort = 0;
-static io_iterator_t            notificationIterator;
-
 struct usb_handle
 {
     UInt8 bulkIn;
     UInt8 bulkOut;
     IOUSBInterfaceInterface190** interface;
-    io_object_t usbNotification;
     unsigned int zero_mask;
+
+    // For garbage collecting disconnected devices.
+    bool mark;
+    std::string devpath;
+    std::atomic<bool> dead;
+
+    usb_handle() : bulkIn(0), bulkOut(0), interface(nullptr),
+        zero_mask(0), mark(false), dead(false) {
+    }
 };
 
-static CFRunLoopRef currentRunLoop = 0;
-static pthread_mutex_t start_lock;
-static pthread_cond_t start_cond;
+static std::atomic<bool> usb_inited_flag;
 
+static auto& g_usb_handles_mutex = *new std::mutex();
+static auto& g_usb_handles = *new std::vector<std::unique_ptr<usb_handle>>();
 
-static void AndroidInterfaceAdded(void *refCon, io_iterator_t iterator);
-static void AndroidInterfaceNotify(void *refCon, io_iterator_t iterator,
-                                   natural_t messageType,
-                                   void *messageArgument);
-static usb_handle* CheckInterface(IOUSBInterfaceInterface190 **iface,
-                                  UInt16 vendor, UInt16 product);
-
-static int
-InitUSB()
-{
-    CFMutableDictionaryRef  matchingDict;
-    CFRunLoopSourceRef      runLoopSource;
-
-    //* To set up asynchronous notifications, create a notification port and
-    //* add its run loop event source to the program's run loop
-    notificationPort = IONotificationPortCreate(kIOMasterPortDefault);
-    runLoopSource = IONotificationPortGetRunLoopSource(notificationPort);
-    CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopDefaultMode);
-
-    //* Create our matching dictionary to find the Android device's
-    //* adb interface
-    //* IOServiceAddMatchingNotification consumes the reference, so we do
-    //* not need to release this
-    matchingDict = IOServiceMatching(kIOUSBInterfaceClassName);
-
-    if (!matchingDict) {
-        LOG(ERROR) << "Couldn't create USB matching dictionary.";
-        return -1;
+static bool IsKnownDevice(const std::string& devpath) {
+    std::lock_guard<std::mutex> lock_guard(g_usb_handles_mutex);
+    for (auto& usb : g_usb_handles) {
+        if (usb->devpath == devpath) {
+            // Set mark flag to indicate this device is still alive.
+            usb->mark = true;
+            return true;
+        }
     }
+    return false;
+}
 
-    //* We have to get notifications for all potential candidates and test them
-    //* at connection time because the matching rules don't allow for a
-    //* USB interface class of 0xff for class+subclass+protocol matches
-    //* See https://developer.apple.com/library/mac/qa/qa1076/_index.html
-    IOServiceAddMatchingNotification(
-            notificationPort,
-            kIOFirstMatchNotification,
-            matchingDict,
-            AndroidInterfaceAdded,
-            NULL,
-            &notificationIterator);
+static void usb_kick_locked(usb_handle* handle);
 
-    //* Iterate over set of matching interfaces to access already-present
-    //* devices and to arm the notification
-    AndroidInterfaceAdded(NULL, notificationIterator);
+static void KickDisconnectedDevices() {
+    std::lock_guard<std::mutex> lock_guard(g_usb_handles_mutex);
+    for (auto& usb : g_usb_handles) {
+        if (!usb->mark) {
+            usb_kick_locked(usb.get());
+        } else {
+            usb->mark = false;
+        }
+    }
+}
 
-    return 0;
+static void AddDevice(std::unique_ptr<usb_handle> handle) {
+    handle->mark = true;
+    std::lock_guard<std::mutex> lock(g_usb_handles_mutex);
+    g_usb_handles.push_back(std::move(handle));
+}
+
+static void AndroidInterfaceAdded(io_iterator_t iterator);
+static std::unique_ptr<usb_handle> CheckInterface(IOUSBInterfaceInterface190 **iface,
+                                                  UInt16 vendor, UInt16 product);
+
+static bool FindUSBDevices() {
+    // Create the matching dictionary to find the Android device's adb interface.
+    CFMutableDictionaryRef matchingDict = IOServiceMatching(kIOUSBInterfaceClassName);
+    if (!matchingDict) {
+        LOG(ERROR) << "couldn't create USB matching dictionary";
+        return false;
+    }
+    // Create an iterator for all I/O Registry objects that match the dictionary.
+    io_iterator_t iter = 0;
+    kern_return_t kr = IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, &iter);
+    if (kr != KERN_SUCCESS) {
+        LOG(ERROR) << "failed to get matching services";
+        return false;
+    }
+    // Iterate over all matching objects.
+    AndroidInterfaceAdded(iter);
+    IOObjectRelease(iter);
+    return true;
 }
 
 static void
-AndroidInterfaceAdded(void *refCon, io_iterator_t iterator)
+AndroidInterfaceAdded(io_iterator_t iterator)
 {
     kern_return_t            kr;
     io_service_t             usbDevice;
@@ -124,8 +134,7 @@
     UInt16                   product;
     UInt8                    serialIndex;
     char                     serial[256];
-    char                     devpathBuf[64];
-    char                     *devpath = NULL;
+    std::string devpath;
 
     while ((usbInterface = IOIteratorNext(iterator))) {
         //* Create an intermediate interface plugin
@@ -199,9 +208,11 @@
         kr = (*dev)->GetDeviceVendor(dev, &vendor);
         kr = (*dev)->GetDeviceProduct(dev, &product);
         kr = (*dev)->GetLocationID(dev, &locationId);
-        if (kr == 0) {
-            snprintf(devpathBuf, sizeof(devpathBuf), "usb:%" PRIu32 "X", locationId);
-            devpath = devpathBuf;
+        if (kr == KERN_SUCCESS) {
+            devpath = android::base::StringPrintf("usb:%" PRIu32 "X", locationId);
+            if (IsKnownDevice(devpath)) {
+                continue;
+            }
         }
         kr = (*dev)->USBGetSerialNumberStringIndex(dev, &serialIndex);
 
@@ -256,49 +267,29 @@
 
         (*dev)->Release(dev);
 
-        LOG(INFO) << android::base::StringPrintf("Found vid=%04x pid=%04x serial=%s\n",
+        VLOG(USB) << android::base::StringPrintf("Found vid=%04x pid=%04x serial=%s\n",
                         vendor, product, serial);
-
-        usb_handle* handle = CheckInterface((IOUSBInterfaceInterface190**)iface,
-                                            vendor, product);
-        if (handle == NULL) {
-            LOG(ERROR) << "Could not find device interface";
+        if (devpath.empty()) {
+            devpath = serial;
+        }
+        if (IsKnownDevice(devpath)) {
+            (*iface)->USBInterfaceClose(iface);
             (*iface)->Release(iface);
             continue;
         }
 
-        LOG(DEBUG) << "AndroidDeviceAdded calling register_usb_transport";
-        register_usb_transport(handle, (serial[0] ? serial : NULL), devpath, 1);
-
-        // Register for an interest notification of this device being removed.
-        // Pass the reference to our private data as the refCon for the
-        // notification.
-        kr = IOServiceAddInterestNotification(notificationPort,
-                usbInterface,
-                kIOGeneralInterest,
-                AndroidInterfaceNotify,
-                handle,
-                &handle->usbNotification);
-
-        if (kIOReturnSuccess != kr) {
-            LOG(ERROR) << "Unable to create interest notification (" << std::hex << kr << ")";
+        std::unique_ptr<usb_handle> handle = CheckInterface((IOUSBInterfaceInterface190**)iface,
+                                                            vendor, product);
+        if (handle == nullptr) {
+            LOG(ERROR) << "Could not find device interface";
+            (*iface)->Release(iface);
+            continue;
         }
-    }
-}
-
-static void
-AndroidInterfaceNotify(void *refCon, io_service_t service, natural_t messageType, void *messageArgument)
-{
-    usb_handle *handle = (usb_handle *)refCon;
-
-    if (messageType == kIOMessageServiceIsTerminated) {
-        if (!handle) {
-            LOG(ERROR) << "NULL handle";
-            return;
-        }
-        LOG(DEBUG) << "AndroidInterfaceNotify";
-        IOObjectRelease(handle->usbNotification);
-        usb_kick(handle);
+        handle->devpath = devpath;
+        usb_handle* handle_p = handle.get();
+        VLOG(USB) << "Add usb device " << serial;
+        AddDevice(std::move(handle));
+        register_usb_transport(handle_p, serial, devpath.c_str(), 1);
     }
 }
 
@@ -316,10 +307,10 @@
 
 //* TODO: simplify this further since we only register to get ADB interface
 //* subclass+protocol events
-static usb_handle*
+static std::unique_ptr<usb_handle>
 CheckInterface(IOUSBInterfaceInterface190 **interface, UInt16 vendor, UInt16 product)
 {
-    usb_handle* handle;
+    std::unique_ptr<usb_handle> handle;
     IOReturn kr;
     UInt8 interfaceNumEndpoints, interfaceClass, interfaceSubClass, interfaceProtocol;
     UInt8 endpoint;
@@ -353,8 +344,10 @@
         goto err_bad_adb_interface;
     }
 
-    handle = reinterpret_cast<usb_handle*>(calloc(1, sizeof(usb_handle)));
-    if (handle == nullptr) goto err_bad_adb_interface;
+    handle.reset(new usb_handle);
+    if (handle == nullptr) {
+        goto err_bad_adb_interface;
+    }
 
     //* Iterate over the endpoints for this interface and find the first
     //* bulk in/out pipes available.  These will be our read/write pipes.
@@ -392,39 +385,37 @@
     return handle;
 
 err_get_pipe_props:
-    free(handle);
 err_bad_adb_interface:
 err_get_interface_class:
 err_get_num_ep:
     (*interface)->USBInterfaceClose(interface);
-    return NULL;
+    return nullptr;
 }
 
+std::mutex& operate_device_lock = *new std::mutex();
+
 static void RunLoopThread(void* unused) {
     adb_thread_setname("RunLoop");
-    InitUSB();
 
-    currentRunLoop = CFRunLoopGetCurrent();
-
-    // Signal the parent that we are running
-    adb_mutex_lock(&start_lock);
-    adb_cond_signal(&start_cond);
-    adb_mutex_unlock(&start_lock);
-
-    CFRunLoopRun();
-    currentRunLoop = 0;
-
-    IOObjectRelease(notificationIterator);
-    IONotificationPortDestroy(notificationPort);
-
-    LOG(DEBUG) << "RunLoopThread done";
+    VLOG(USB) << "RunLoopThread started";
+    while (true) {
+        {
+            std::lock_guard<std::mutex> lock_guard(operate_device_lock);
+            FindUSBDevices();
+            KickDisconnectedDevices();
+        }
+        // Signal the parent that we are running
+        usb_inited_flag = true;
+        adb_sleep_ms(1000);
+    }
+    VLOG(USB) << "RunLoopThread done";
 }
 
 static void usb_cleanup() {
-    LOG(DEBUG) << "usb_cleanup";
+    VLOG(USB) << "usb_cleanup";
+    // Wait until usb operations in RunLoopThread finish, and prevent further operations.
+    operate_device_lock.lock();
     close_usb_devices();
-    if (currentRunLoop)
-        CFRunLoopStop(currentRunLoop);
 }
 
 void usb_init() {
@@ -432,20 +423,16 @@
     if (!initialized) {
         atexit(usb_cleanup);
 
-        adb_mutex_init(&start_lock, NULL);
-        adb_cond_init(&start_cond, NULL);
+        usb_inited_flag = false;
 
         if (!adb_thread_create(RunLoopThread, nullptr)) {
             fatal_errno("cannot create RunLoop thread");
         }
 
         // Wait for initialization to finish
-        adb_mutex_lock(&start_lock);
-        adb_cond_wait(&start_cond, &start_lock);
-        adb_mutex_unlock(&start_lock);
-
-        adb_mutex_destroy(&start_lock);
-        adb_cond_destroy(&start_cond);
+        while (!usb_inited_flag) {
+            adb_sleep_ms(100);
+        }
 
         initialized = true;
     }
@@ -458,7 +445,7 @@
     if (!len)
         return 0;
 
-    if (!handle)
+    if (!handle || handle->dead)
         return -1;
 
     if (NULL == handle->interface) {
@@ -499,7 +486,7 @@
         return 0;
     }
 
-    if (!handle) {
+    if (!handle || handle->dead) {
         return -1;
     }
 
@@ -532,20 +519,33 @@
 
 int usb_close(usb_handle *handle)
 {
+    std::lock_guard<std::mutex> lock(g_usb_handles_mutex);
+    for (auto it = g_usb_handles.begin(); it != g_usb_handles.end(); ++it) {
+        if ((*it).get() == handle) {
+            g_usb_handles.erase(it);
+            break;
+        }
+    }
     return 0;
 }
 
-void usb_kick(usb_handle *handle)
+static void usb_kick_locked(usb_handle *handle)
 {
     LOG(INFO) << "Kicking handle";
     /* release the interface */
     if (!handle)
         return;
 
-    if (handle->interface)
+    if (!handle->dead)
     {
+        handle->dead = true;
         (*handle->interface)->USBInterfaceClose(handle->interface);
         (*handle->interface)->Release(handle->interface);
-        handle->interface = 0;
     }
 }
+
+void usb_kick(usb_handle *handle) {
+    // Use the lock to avoid multiple thread kicking the device at the same time.
+    std::lock_guard<std::mutex> lock_guard(g_usb_handles_mutex);
+    usb_kick_locked(handle);
+}
diff --git a/base/include/android-base/unique_fd.h b/base/include/android-base/unique_fd.h
index 8bc49ce..ab41c55 100644
--- a/base/include/android-base/unique_fd.h
+++ b/base/include/android-base/unique_fd.h
@@ -19,7 +19,10 @@
 
 #include <unistd.h>
 
-#include <android-base/macros.h>
+// DO NOT INCLUDE OTHER LIBBASE HEADERS!
+// This file gets used in libbinder, and libbinder is used everywhere.
+// Including other headers from libbase frequently results in inclusion of
+// android-base/macros.h, which causes macro collisions.
 
 // Container for a file descriptor that automatically closes the descriptor as
 // it goes out of scope.
@@ -75,7 +78,8 @@
  private:
   int value_;
 
-  DISALLOW_COPY_AND_ASSIGN(unique_fd);
+  unique_fd(const unique_fd&);
+  void operator=(const unique_fd&);
 };
 
 }  // namespace base
diff --git a/debuggerd/debuggerd.cpp b/debuggerd/debuggerd.cpp
index 6064568..258bd76 100644
--- a/debuggerd/debuggerd.cpp
+++ b/debuggerd/debuggerd.cpp
@@ -25,9 +25,11 @@
 #include <sys/poll.h>
 #include <sys/prctl.h>
 #include <sys/ptrace.h>
+#include <sys/socket.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/wait.h>
+#include <sys/un.h>
 #include <time.h>
 
 #include <set>
@@ -248,6 +250,43 @@
   return 0;
 }
 
+static int activity_manager_connect() {
+  android::base::unique_fd amfd(socket(PF_UNIX, SOCK_STREAM, 0));
+  if (amfd.get() < -1) {
+    ALOGE("debuggerd: Unable to connect to activity manager (socket failed: %s)", strerror(errno));
+    return -1;
+  }
+
+  struct sockaddr_un address;
+  memset(&address, 0, sizeof(address));
+  address.sun_family = AF_UNIX;
+  // The path used here must match the value defined in NativeCrashListener.java.
+  strncpy(address.sun_path, "/data/system/ndebugsocket", sizeof(address.sun_path));
+  if (TEMP_FAILURE_RETRY(connect(amfd.get(), reinterpret_cast<struct sockaddr*>(&address),
+                                 sizeof(address))) == -1) {
+    ALOGE("debuggerd: Unable to connect to activity manager (connect failed: %s)", strerror(errno));
+    return -1;
+  }
+
+  struct timeval tv;
+  memset(&tv, 0, sizeof(tv));
+  tv.tv_sec = 1;  // tight leash
+  if (setsockopt(amfd.get(), SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) == -1) {
+    ALOGE("debuggerd: Unable to connect to activity manager (setsockopt SO_SNDTIMEO failed: %s)",
+          strerror(errno));
+    return -1;
+  }
+
+  tv.tv_sec = 3;  // 3 seconds on handshake read
+  if (setsockopt(amfd.get(), SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) == -1) {
+    ALOGE("debuggerd: Unable to connect to activity manager (setsockopt SO_RCVTIMEO failed: %s)",
+          strerror(errno));
+    return -1;
+  }
+
+  return amfd.release();
+}
+
 static bool should_attach_gdb(const debugger_request_t& request) {
   if (request.action == DEBUGGER_ACTION_CRASH) {
     return property_get_bool("debug.debuggerd.wait_for_gdb", false);
@@ -375,7 +414,7 @@
 
 static bool perform_dump(const debugger_request_t& request, int fd, int tombstone_fd,
                          BacktraceMap* backtrace_map, const std::set<pid_t>& siblings,
-                         int* crash_signal) {
+                         int* crash_signal, int amfd) {
   if (TEMP_FAILURE_RETRY(write(fd, "\0", 1)) != 1) {
     ALOGE("debuggerd: failed to respond to client: %s\n", strerror(errno));
     return false;
@@ -393,7 +432,7 @@
         if (request.action == DEBUGGER_ACTION_DUMP_TOMBSTONE) {
           ALOGV("debuggerd: stopped -- dumping to tombstone");
           engrave_tombstone(tombstone_fd, backtrace_map, request.pid, request.tid, siblings, signal,
-                            request.original_si_code, request.abort_msg_address);
+                            request.original_si_code, request.abort_msg_address, amfd);
         } else if (request.action == DEBUGGER_ACTION_DUMP_BACKTRACE) {
           ALOGV("debuggerd: stopped -- dumping to fd");
           dump_backtrace(fd, -1, backtrace_map, request.pid, request.tid, siblings);
@@ -419,7 +458,7 @@
         ALOGV("stopped -- fatal signal\n");
         *crash_signal = signal;
         engrave_tombstone(tombstone_fd, backtrace_map, request.pid, request.tid, siblings, signal,
-                          request.original_si_code, request.abort_msg_address);
+                          request.original_si_code, request.abort_msg_address, amfd);
         break;
 
       default:
@@ -505,6 +544,12 @@
   // Generate the backtrace map before dropping privileges.
   std::unique_ptr<BacktraceMap> backtrace_map(BacktraceMap::Create(request.pid));
 
+  int amfd = -1;
+  if (request.action == DEBUGGER_ACTION_CRASH) {
+    // Connect to the activity manager before dropping privileges.
+    amfd = activity_manager_connect();
+  }
+
   bool succeeded = false;
 
   // Now that we've done everything that requires privileges, we can drop them.
@@ -514,7 +559,8 @@
   }
 
   int crash_signal = SIGKILL;
-  succeeded = perform_dump(request, fd, tombstone_fd, backtrace_map.get(), siblings, &crash_signal);
+  succeeded = perform_dump(request, fd, tombstone_fd, backtrace_map.get(), siblings,
+                           &crash_signal, amfd);
   if (succeeded) {
     if (request.action == DEBUGGER_ACTION_DUMP_TOMBSTONE) {
       if (!tombstone_path.empty()) {
@@ -558,6 +604,8 @@
     uninit_getevent();
   }
 
+  close(amfd);
+
   exit(!succeeded);
 }
 
diff --git a/debuggerd/tombstone.cpp b/debuggerd/tombstone.cpp
index 7cf2ffc..d802c8c 100644
--- a/debuggerd/tombstone.cpp
+++ b/debuggerd/tombstone.cpp
@@ -28,9 +28,7 @@
 #include <string.h>
 #include <time.h>
 #include <sys/ptrace.h>
-#include <sys/socket.h>
 #include <sys/stat.h>
-#include <sys/un.h>
 
 #include <memory>
 #include <string>
@@ -59,9 +57,6 @@
 #define TOMBSTONE_DIR   "/data/tombstones"
 #define TOMBSTONE_TEMPLATE (TOMBSTONE_DIR"/tombstone_%02d")
 
-// Must match the path defined in NativeCrashListener.java
-#define NCRASH_SOCKET_PATH "/data/system/ndebugsocket"
-
 static bool signal_has_si_addr(int sig) {
   switch (sig) {
     case SIGBUS:
@@ -711,39 +706,9 @@
   return fd;
 }
 
-static int activity_manager_connect() {
-  int amfd = socket(PF_UNIX, SOCK_STREAM, 0);
-  if (amfd >= 0) {
-    struct sockaddr_un address;
-    int err;
-
-    memset(&address, 0, sizeof(address));
-    address.sun_family = AF_UNIX;
-    strncpy(address.sun_path, NCRASH_SOCKET_PATH, sizeof(address.sun_path));
-    err = TEMP_FAILURE_RETRY(connect(
-        amfd, reinterpret_cast<struct sockaddr*>(&address), sizeof(address)));
-    if (!err) {
-      struct timeval tv;
-      memset(&tv, 0, sizeof(tv));
-      tv.tv_sec = 1;  // tight leash
-      err = setsockopt(amfd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
-      if (!err) {
-        tv.tv_sec = 3;  // 3 seconds on handshake read
-        err = setsockopt(amfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
-      }
-    }
-    if (err) {
-      close(amfd);
-      amfd = -1;
-    }
-  }
-
-  return amfd;
-}
-
 void engrave_tombstone(int tombstone_fd, BacktraceMap* map, pid_t pid, pid_t tid,
                        const std::set<pid_t>& siblings, int signal, int original_si_code,
-                       uintptr_t abort_msg_address) {
+                       uintptr_t abort_msg_address, int amfd) {
   log_t log;
   log.current_tid = tid;
   log.crashed_tid = tid;
@@ -756,10 +721,6 @@
   log.tfd = tombstone_fd;
   // Preserve amfd since it can be modified through the calls below without
   // being closed.
-  int amfd = activity_manager_connect();
   log.amfd = amfd;
   dump_crash(&log, map, pid, tid, siblings, signal, original_si_code, abort_msg_address);
-
-  // This file descriptor can be -1, any error is ignored.
-  close(amfd);
 }
diff --git a/debuggerd/tombstone.h b/debuggerd/tombstone.h
index 2b8b8be..7f3eebe 100644
--- a/debuggerd/tombstone.h
+++ b/debuggerd/tombstone.h
@@ -34,6 +34,6 @@
 /* Creates a tombstone file and writes the crash dump to it. */
 void engrave_tombstone(int tombstone_fd, BacktraceMap* map, pid_t pid, pid_t tid,
                        const std::set<pid_t>& siblings, int signal, int original_si_code,
-                       uintptr_t abort_msg_address);
+                       uintptr_t abort_msg_address, int amfd);
 
 #endif // _DEBUGGERD_TOMBSTONE_H
diff --git a/liblog/Android.bp b/liblog/Android.bp
index 302e63c..7a95dbd 100644
--- a/liblog/Android.bp
+++ b/liblog/Android.bp
@@ -56,7 +56,9 @@
         android: {
             srcs: liblog_target_sources,
             // AddressSanitizer runtime library depends on liblog.
-            sanitize: ["never"],
+            sanitize: {
+                never: true,
+            },
         },
         android_arm: {
             // TODO: This is to work around b/24465209. Remove after root cause is fixed