Merge "init: reap zombies only after kill(-pid, ...)" am: a51c40ce35 am: 0924b32c1f
am: 419a9ef8f1
Change-Id: I0f2e6b2b2dfed4dab480acf2562df78da8d2f65e
This commit is contained in:
commit
fc479afbb6
1 changed files with 20 additions and 11 deletions
|
|
@ -34,6 +34,7 @@
|
||||||
#include <android-base/logging.h>
|
#include <android-base/logging.h>
|
||||||
#include <android-base/parseint.h>
|
#include <android-base/parseint.h>
|
||||||
#include <android-base/properties.h>
|
#include <android-base/properties.h>
|
||||||
|
#include <android-base/scopeguard.h>
|
||||||
#include <android-base/stringprintf.h>
|
#include <android-base/stringprintf.h>
|
||||||
#include <android-base/strings.h>
|
#include <android-base/strings.h>
|
||||||
#include <processgroup/processgroup.h>
|
#include <processgroup/processgroup.h>
|
||||||
|
|
@ -47,6 +48,7 @@
|
||||||
using android::base::boot_clock;
|
using android::base::boot_clock;
|
||||||
using android::base::GetProperty;
|
using android::base::GetProperty;
|
||||||
using android::base::Join;
|
using android::base::Join;
|
||||||
|
using android::base::make_scope_guard;
|
||||||
using android::base::ParseInt;
|
using android::base::ParseInt;
|
||||||
using android::base::StartsWith;
|
using android::base::StartsWith;
|
||||||
using android::base::StringPrintf;
|
using android::base::StringPrintf;
|
||||||
|
|
@ -1088,14 +1090,24 @@ void ServiceManager::DumpState() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ServiceManager::ReapOneProcess() {
|
bool ServiceManager::ReapOneProcess() {
|
||||||
int status;
|
siginfo_t siginfo = {};
|
||||||
pid_t pid = TEMP_FAILURE_RETRY(waitpid(-1, &status, WNOHANG));
|
// This returns a zombie pid or informs us that there are no zombies left to be reaped.
|
||||||
if (pid == 0) {
|
// It does NOT reap the pid; that is done below.
|
||||||
|
if (TEMP_FAILURE_RETRY(waitid(P_ALL, 0, &siginfo, WEXITED | WNOHANG | WNOWAIT)) != 0) {
|
||||||
|
PLOG(ERROR) << "waitid failed";
|
||||||
return false;
|
return false;
|
||||||
} else if (pid == -1) {
|
}
|
||||||
PLOG(ERROR) << "waitpid failed";
|
|
||||||
return false;
|
auto pid = siginfo.si_pid;
|
||||||
} else if (PropertyChildReap(pid)) {
|
if (pid == 0) return false;
|
||||||
|
|
||||||
|
// At this point we know we have a zombie pid, so we use this scopeguard to reap the pid
|
||||||
|
// whenever the function returns from this point forward.
|
||||||
|
// We do NOT want to reap the zombie earlier as in Service::Reap(), we kill(-pid, ...) and we
|
||||||
|
// want the pid to remain valid throughout that (and potentially future) usages.
|
||||||
|
auto reaper = make_scope_guard([pid] { TEMP_FAILURE_RETRY(waitpid(pid, nullptr, WNOHANG)); });
|
||||||
|
|
||||||
|
if (PropertyChildReap(pid)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1112,14 +1124,11 @@ bool ServiceManager::ReapOneProcess() {
|
||||||
name = StringPrintf("Untracked pid %d", pid);
|
name = StringPrintf("Untracked pid %d", pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto status = siginfo.si_status;
|
||||||
if (WIFEXITED(status)) {
|
if (WIFEXITED(status)) {
|
||||||
LOG(INFO) << name << " exited with status " << WEXITSTATUS(status) << wait_string;
|
LOG(INFO) << name << " exited with status " << WEXITSTATUS(status) << wait_string;
|
||||||
} else if (WIFSIGNALED(status)) {
|
} else if (WIFSIGNALED(status)) {
|
||||||
LOG(INFO) << name << " killed by signal " << WTERMSIG(status) << wait_string;
|
LOG(INFO) << name << " killed by signal " << WTERMSIG(status) << wait_string;
|
||||||
} else if (WIFSTOPPED(status)) {
|
|
||||||
LOG(INFO) << name << " stopped by signal " << WSTOPSIG(status) << wait_string;
|
|
||||||
} else {
|
|
||||||
LOG(INFO) << name << " state changed" << wait_string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!svc) {
|
if (!svc) {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue