Merge "zygote: use async signal safe log to record child process death"
This commit is contained in:
@@ -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",
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user