| Index: content/zygote/zygote_linux.cc
|
| diff --git a/content/zygote/zygote_linux.cc b/content/zygote/zygote_linux.cc
|
| index a5fb2038050c621f518a635e07203453ecf69c06..2ae6784c6a87005d915b2c3685338dc9c623f975 100644
|
| --- a/content/zygote/zygote_linux.cc
|
| +++ b/content/zygote/zygote_linux.cc
|
| @@ -204,9 +204,11 @@ void Zygote::HandleReapRequest(int fd,
|
| void Zygote::HandleGetTerminationStatus(int fd,
|
| const Pickle& pickle,
|
| PickleIterator iter) {
|
| + bool known_dead;
|
| base::ProcessHandle child;
|
|
|
| - if (!pickle.ReadInt(&iter, &child)) {
|
| + if (!pickle.ReadBool(&iter, &known_dead) ||
|
| + !pickle.ReadInt(&iter, &child)) {
|
| LOG(WARNING) << "Error parsing GetTerminationStatus request "
|
| << "from browser";
|
| return;
|
| @@ -217,7 +219,20 @@ void Zygote::HandleGetTerminationStatus(int fd,
|
| if (UsingSUIDSandbox())
|
| child = real_pids_to_sandbox_pids[child];
|
| if (child) {
|
| - status = base::GetTerminationStatus(child, &exit_code);
|
| + if (known_dead) {
|
| + // If we know that the process is already dead and the kernel is cleaning
|
| + // it up, we do want to wait until it becomes a zombie and not risk
|
| + // returning eroneously that it is still running. However, we do not
|
| + // want to risk a bug where we're told a process is dead when it's not.
|
| + // By sending SIGKILL, we make sure that WaitForTerminationStatus will
|
| + // return quickly even in this case.
|
| + if (kill(child, SIGKILL)) {
|
| + PLOG(ERROR) << "kill (" << child << ")";
|
| + }
|
| + status = base::WaitForTerminationStatus(child, &exit_code);
|
| + } else {
|
| + status = base::GetTerminationStatus(child, &exit_code);
|
| + }
|
| } else {
|
| // Assume that if we can't find the child in the sandbox, then
|
| // it terminated normally.
|
|
|