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,
- ¬ificationIterator);
+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