OSDN Git Service

Do not create property_watch_loop thread for zygote
authorPirama Arumuga Nainar <pirama@google.com>
Wed, 29 May 2019 21:18:18 +0000 (14:18 -0700)
committerOliver Nguyen <olivernguyen@google.com>
Mon, 3 Jun 2019 18:55:09 +0000 (11:55 -0700)
Bug: http://b/116873221
Bug: http://b/133872559

Do not create thread running property_watch_loop for zygote (which is
essentially /system/bin/app_process invoked with a specific argument to
start the zygote).

The reason this is needed is because when the zygote forks system_server
or an app, it waits for all threads to stop.  But the thread created
here doesn't know that it has to stop.  So zygote gets stuck waiting and
the device doesn't boot.

This check is only needed for the platform, but can be done on any
version after Android L, when getprogname() was added.

Test: cuttlefish with coverage enabled can boot.
Change-Id: I65aa603a88bf8da1f14b5c4ada3adf3776f33275
(cherry picked from commit 4cedcc68d4dfedf96474973de1e7e22d0ce0a523)

toolchain-extras/profile-extras.cpp

index 3af46a1..21bbfed 100644 (file)
@@ -17,7 +17,9 @@
 #include <errno.h>
 #include <pthread.h>
 #include <signal.h>
+#include <stdlib.h>
 #include <string.h>
+#include <libgen.h> // For POSIX basename().
 
 // Use _system_properties.h to use __system_property_wait_any()
 #define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
@@ -84,6 +86,20 @@ __attribute__((constructor)) int init_profile_extras(void) {
     return -1;
   }
 
+  // Do not create thread running property_watch_loop for zygote (it can get
+  // invoked as zygote or app_process).  This check is only needed for the
+  // platform, but can be done on any version after Android L, when
+  // getprogname() was added.
+#if defined(__ANDROID_API__) && __ANDROID_API__ >= __ANDROID_API_L__
+  const char *prog_basename = basename(getprogname());
+  if (strncmp(prog_basename, "zygote", strlen("zygote")) == 0) {
+    return 0;
+  }
+  if (strncmp(prog_basename, "app_process", strlen("app_process")) == 0) {
+    return 0;
+  }
+#endif
+
   pthread_t thread;
   int error = pthread_create(&thread, nullptr, property_watch_loop, nullptr);
   if (error != 0) {