diff --git a/adb/adb.cpp b/adb/adb.cpp index fa935f61b..eb01da82b 100644 --- a/adb/adb.cpp +++ b/adb/adb.cpp @@ -670,10 +670,12 @@ static unsigned _redirect_pipe_thread(HANDLE h, DWORD nStdHandle) { } static unsigned __stdcall _redirect_stdout_thread(HANDLE h) { + adb_thread_setname("stdout redirect"); return _redirect_pipe_thread(h, STD_OUTPUT_HANDLE); } static unsigned __stdcall _redirect_stderr_thread(HANDLE h) { + adb_thread_setname("stderr redirect"); return _redirect_pipe_thread(h, STD_ERROR_HANDLE); } diff --git a/adb/commandline.cpp b/adb/commandline.cpp index ed25f3b8d..4ca5c5a53 100644 --- a/adb/commandline.cpp +++ b/adb/commandline.cpp @@ -382,6 +382,8 @@ static void *stdin_read_thread(void *x) fdi = fds[1]; free(fds); + adb_thread_setname("stdin reader"); + while (true) { /* fdi is really the client's stdin, so use read, not adb_read here */ D("stdin_read_thread(): pre unix_read(fdi=%d,...)\n", fdi); diff --git a/adb/services.cpp b/adb/services.cpp index c8c2d5469..4606804e0 100644 --- a/adb/services.cpp +++ b/adb/services.cpp @@ -67,6 +67,7 @@ enum class SubprocessType { void *service_bootstrap_func(void *x) { stinfo* sti = reinterpret_cast(x); + adb_thread_setname(android::base::StringPrintf("service %d", sti->fd)); sti->func(sti->fd, sti->cookie); free(sti); return 0; diff --git a/adb/sysdeps.h b/adb/sysdeps.h index a58a76286..5918a94f0 100644 --- a/adb/sysdeps.h +++ b/adb/sysdeps.h @@ -111,6 +111,13 @@ static __inline__ bool adb_thread_create(adb_thread_func_t func, void* arg) { return (tid != static_cast(-1L)); } +static __inline__ int adb_thread_setname(const std::string& name) { + // TODO: See https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx for how to set + // the thread name in Windows. Unfortunately, it only works during debugging, but + // our build process doesn't generate PDB files needed for debugging. + return 0; +} + static __inline__ unsigned long adb_thread_id() { return GetCurrentThreadId(); @@ -617,7 +624,26 @@ static __inline__ bool adb_thread_create(adb_thread_func_t start, void* arg) { return (errno == 0); } -static __inline__ int adb_socket_setbufsize( int fd, int bufsize ) +static __inline__ int adb_thread_setname(const std::string& name) { +#ifdef __APPLE__ + return pthread_setname_np(name.c_str()); +#else + const char *s = name.c_str(); + + // pthread_setname_np fails rather than truncating long strings. + const int max_task_comm_len = 16; // including the null terminator + if (name.length() > (max_task_comm_len - 1)) { + char buf[max_task_comm_len]; + strncpy(buf, name.c_str(), sizeof(buf) - 1); + buf[sizeof(buf) - 1] = '\0'; + s = buf; + } + + return pthread_setname_np(pthread_self(), s) ; +#endif +} + +static __inline__ int adb_socket_setbufsize(int fd, int bufsize ) { int opt = bufsize; return setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt)); diff --git a/adb/transport.cpp b/adb/transport.cpp index 6ce5d7f51..bd3bf1663 100644 --- a/adb/transport.cpp +++ b/adb/transport.cpp @@ -193,6 +193,7 @@ static void *output_thread(void *_t) atransport *t = reinterpret_cast(_t); apacket *p; + adb_thread_setname("to transport"); D("%s: starting transport output thread on fd %d, SYNC online (%d)\n", t->serial, t->fd, t->sync_token + 1); p = get_apacket(); @@ -249,6 +250,7 @@ static void *input_thread(void *_t) apacket *p; int active = 0; + adb_thread_setname("from transport"); D("%s: starting transport input thread, reading from fd %d\n", t->serial, t->fd); diff --git a/adb/transport_local.cpp b/adb/transport_local.cpp index 6a174973a..6821cfcce 100644 --- a/adb/transport_local.cpp +++ b/adb/transport_local.cpp @@ -123,6 +123,7 @@ int local_connect_arbitrary_ports(int console_port, int adb_port, std::string* e #if ADB_HOST static void *client_socket_thread(void *x) { + adb_thread_setname("client_socket_thread"); D("transport: client_socket_thread() starting\n"); while (true) { int port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT; @@ -146,6 +147,7 @@ static void *server_socket_thread(void * arg) socklen_t alen; int port = (int) (uintptr_t) arg; + adb_thread_setname("server socket"); D("transport: server_socket_thread() starting\n"); serverfd = -1; for(;;) { @@ -231,6 +233,7 @@ static const char _ok_resp[] = "ok"; char tmp[256]; char con_name[32]; + adb_thread_setname("qemu socket"); D("transport: qemu_socket_thread() starting\n"); /* adb QEMUD service connection request. */ diff --git a/adb/usb_linux.cpp b/adb/usb_linux.cpp index dd2271218..6ccc8e28c 100644 --- a/adb/usb_linux.cpp +++ b/adb/usb_linux.cpp @@ -572,6 +572,7 @@ static void register_device(const char* dev_name, const char* dev_path, } static void* device_poll_thread(void* unused) { + adb_thread_setname("device poll"); D("Created device thread\n"); while (true) { // TODO: Use inotify. diff --git a/adb/usb_linux_client.cpp b/adb/usb_linux_client.cpp index dc44f16fe..e1d759438 100644 --- a/adb/usb_linux_client.cpp +++ b/adb/usb_linux_client.cpp @@ -209,6 +209,8 @@ static void *usb_adb_open_thread(void *x) struct usb_handle *usb = (struct usb_handle *)x; int fd; + adb_thread_setname("usb open"); + while (true) { // wait until the USB device needs opening adb_mutex_lock(&usb->lock); @@ -403,6 +405,8 @@ static void *usb_ffs_open_thread(void *x) { struct usb_handle *usb = (struct usb_handle *)x; + adb_thread_setname("usb ffs open"); + while (true) { // wait until the USB device needs opening adb_mutex_lock(&usb->lock); diff --git a/adb/usb_osx.cpp b/adb/usb_osx.cpp index 0ce85f35c..d9e2fb284 100644 --- a/adb/usb_osx.cpp +++ b/adb/usb_osx.cpp @@ -403,6 +403,7 @@ err_get_num_ep: void* RunLoopThread(void* unused) { + adb_thread_setname("RunLoop"); InitUSB(); currentRunLoop = CFRunLoopGetCurrent(); diff --git a/adb/usb_windows.cpp b/adb/usb_windows.cpp index b8cc5cf93..ab3647527 100644 --- a/adb/usb_windows.cpp +++ b/adb/usb_windows.cpp @@ -171,6 +171,7 @@ int register_new_device(usb_handle* handle) { } void* device_poll_thread(void* unused) { + adb_thread_setname("Device Poll"); D("Created device thread\n"); while(1) { @@ -208,6 +209,7 @@ static void* _power_notification_thread(void* unused) { // of a developer's interactive session, a window message pump is more // appropriate. D("Created power notification thread\n"); + adb_thread_setname("Power Notifier"); // Window class names are process specific. static const WCHAR kPowerNotificationWindowClassName[] =