Merge "zygote: use async signal safe log to record child process death"

This commit is contained in:
Elliott Hughes
2019-02-16 00:12:51 +00:00
committed by Gerrit Code Review
2 changed files with 18 additions and 16 deletions

View File

@@ -41,7 +41,7 @@ cc_library_shared {
"com_google_android_gles_jni_EGLImpl.cpp", "com_google_android_gles_jni_EGLImpl.cpp",
"com_google_android_gles_jni_GLImpl.cpp", // TODO: .arm "com_google_android_gles_jni_GLImpl.cpp", // TODO: .arm
"android_app_Activity.cpp", "android_app_Activity.cpp",
"android_app_ActivityThread.cpp", "android_app_ActivityThread.cpp",
"android_app_NativeActivity.cpp", "android_app_NativeActivity.cpp",
"android_app_admin_SecurityLog.cpp", "android_app_admin_SecurityLog.cpp",
"android_opengl_EGL14.cpp", "android_opengl_EGL14.cpp",
@@ -225,6 +225,7 @@ cc_library_shared {
], ],
static_libs: [ static_libs: [
"libasync_safe",
"libgif", "libgif",
"libseccomp_policy", "libseccomp_policy",
"libgrallocusage", "libgrallocusage",

View File

@@ -25,6 +25,8 @@
#define LOG_TAG "Zygote" #define LOG_TAG "Zygote"
#include <async_safe/log.h>
// sys/mount.h has to come before linux/fs.h due to redefinition of MS_RDONLY, MS_BIND, etc // sys/mount.h has to come before linux/fs.h due to redefinition of MS_RDONLY, MS_BIND, etc
#include <sys/mount.h> #include <sys/mount.h>
#include <linux/fs.h> #include <linux/fs.h>
@@ -296,27 +298,23 @@ static void SigChldHandler(int /*signal_number*/) {
int saved_errno = errno; int saved_errno = errno;
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
// Log process-death status that we care about. In general it is // Log process-death status that we care about.
// not safe to call LOG(...) from a signal handler because of
// possible reentrancy. However, we know a priori that the
// current implementation of LOG() is safe to call from a SIGCHLD
// handler in the zygote process. If the LOG() implementation
// changes its locking strategy or its use of syscalls within the
// lazy-init critical section, its use here may become unsafe.
if (WIFEXITED(status)) { if (WIFEXITED(status)) {
ALOGI("Process %d exited cleanly (%d)", pid, WEXITSTATUS(status)); async_safe_format_log(ANDROID_LOG_INFO, LOG_TAG,
"Process %d exited cleanly (%d)", pid, WEXITSTATUS(status));
} else if (WIFSIGNALED(status)) { } else if (WIFSIGNALED(status)) {
ALOGI("Process %d exited due to signal (%d)", pid, WTERMSIG(status)); async_safe_format_log(ANDROID_LOG_INFO, LOG_TAG,
if (WCOREDUMP(status)) { "Process %d exited due to signal %d (%s)%s", pid,
ALOGI("Process %d dumped core.", pid); WTERMSIG(status), strsignal(WTERMSIG(status)),
} WCOREDUMP(status) ? "; core dumped" : "");
} }
// If the just-crashed process is the system_server, bring down zygote // If the just-crashed process is the system_server, bring down zygote
// so that it is restarted by init and system server will be restarted // so that it is restarted by init and system server will be restarted
// from there. // from there.
if (pid == gSystemServerPid) { if (pid == gSystemServerPid) {
ALOGE("Exit zygote because system server (%d) has terminated", pid); async_safe_format_log(ANDROID_LOG_ERROR, LOG_TAG,
"Exit zygote because system server (pid %d) has terminated", pid);
kill(getpid(), SIGKILL); kill(getpid(), SIGKILL);
} }
@@ -329,14 +327,17 @@ static void SigChldHandler(int /*signal_number*/) {
// Note that we shouldn't consider ECHILD an error because // Note that we shouldn't consider ECHILD an error because
// the secondary zygote might have no children left to wait for. // the secondary zygote might have no children left to wait for.
if (pid < 0 && errno != ECHILD) { if (pid < 0 && errno != ECHILD) {
ALOGW("Zygote SIGCHLD error in waitpid: %s", strerror(errno)); async_safe_format_log(ANDROID_LOG_WARN, LOG_TAG,
"Zygote SIGCHLD error in waitpid: %s", strerror(errno));
} }
if (blastulas_removed > 0) { if (blastulas_removed > 0) {
if (write(gBlastulaPoolEventFD, &blastulas_removed, sizeof(blastulas_removed)) == -1) { if (write(gBlastulaPoolEventFD, &blastulas_removed, sizeof(blastulas_removed)) == -1) {
// If this write fails something went terribly wrong. We will now kill // If this write fails something went terribly wrong. We will now kill
// the zygote and let the system bring it back up. // the zygote and let the system bring it back up.
ALOGE("Zygote failed to write to blastula pool event FD: %s", strerror(errno)); async_safe_format_log(ANDROID_LOG_ERROR, LOG_TAG,
"Zygote failed to write to blastula pool event FD: %s",
strerror(errno));
kill(getpid(), SIGKILL); kill(getpid(), SIGKILL);
} }
} }