summaryrefslogtreecommitdiffstats
path: root/base/process
diff options
context:
space:
mode:
authorccameron@chromium.org <ccameron@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-09-17 03:50:22 +0000
committerccameron@chromium.org <ccameron@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-09-17 03:50:22 +0000
commit0dac68b42cf4742c6e3d03dfaa14d2aa1ada0ea1 (patch)
tree7cc6e737dc44ce6833e8923cceed4e67294c1092 /base/process
parent50412714e3a37f4d5a4aaae3437aef9909db30e2 (diff)
downloadchromium_src-0dac68b42cf4742c6e3d03dfaa14d2aa1ada0ea1.zip
chromium_src-0dac68b42cf4742c6e3d03dfaa14d2aa1ada0ea1.tar.gz
chromium_src-0dac68b42cf4742c6e3d03dfaa14d2aa1ada0ea1.tar.bz2
Fix a bug where killing pages doesn't yield a sad-tab
The determination of whether or not to put up a sad tab page is made based on the termination status of the renderer process. The termination status of the renderer process is checked when the channel between the browser and the renderer stops working. There is a race here because there is no reason to believe that the renderer process has finished terminating at the time that the browser detects that its channel to the renderer is dead. If renderer process is believed to be still running at the moment when the decision to put up the sad tab page is taken, then no sad tab will be put up, the view of the renderer will be removed (eventually), and a transparent window will result. This bug was previously fixed on Linux with with https://chromiumcodereview.appspot.com/11316261 this patch expands that fix to Mac. In particular, if the renderer process is known to be dead, wait for the process to terminate before taking its termination status. To be sure that the browser does not wait forever on a renderer that is not exiting, send a kill signal to the renderer before doing the wait. BUG=167538 Review URL: https://chromiumcodereview.appspot.com/23866011 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@223526 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/process')
-rw-r--r--base/process/kill.h23
-rw-r--r--base/process/kill_posix.cc9
2 files changed, 24 insertions, 8 deletions
diff --git a/base/process/kill.h b/base/process/kill.h
index f81ea90..c828c71 100644
--- a/base/process/kill.h
+++ b/base/process/kill.h
@@ -67,12 +67,23 @@ BASE_EXPORT TerminationStatus GetTerminationStatus(ProcessHandle handle,
int* exit_code);
#if defined(OS_POSIX)
-// Wait for the process to exit and get the termination status. See
-// GetTerminationStatus for more information. On POSIX systems, we can't call
-// WaitForExitCode and then GetTerminationStatus as the child will be reaped
-// when WaitForExitCode return and this information will be lost.
-BASE_EXPORT TerminationStatus WaitForTerminationStatus(ProcessHandle handle,
- int* exit_code);
+// Send a kill signal to the process and then wait for the process to exit
+// and get the termination status.
+//
+// This is used in situations where it is believed that the process is dead
+// or dying (because communication with the child process has been cut).
+// In order to avoid erroneously returning that the process is still running
+// because the kernel is still cleaning it up, this will wait for the process
+// to terminate. In order to avoid the risk of hanging while waiting for the
+// process to terminate, send a SIGKILL to the process before waiting for the
+// termination status.
+//
+// Note that it is not an option to call WaitForExitCode and then
+// GetTerminationStatus as the child will be reaped when WaitForExitCode
+// returns, and this information will be lost.
+//
+BASE_EXPORT TerminationStatus GetKnownDeadTerminationStatus(
+ ProcessHandle handle, int* exit_code);
#endif // defined(OS_POSIX)
// Waits for process to exit. On POSIX systems, if the process hasn't been
diff --git a/base/process/kill_posix.cc b/base/process/kill_posix.cc
index 5938fa5..99d70d9 100644
--- a/base/process/kill_posix.cc
+++ b/base/process/kill_posix.cc
@@ -195,8 +195,13 @@ TerminationStatus GetTerminationStatus(ProcessHandle handle, int* exit_code) {
return GetTerminationStatusImpl(handle, false /* can_block */, exit_code);
}
-TerminationStatus WaitForTerminationStatus(ProcessHandle handle,
- int* exit_code) {
+TerminationStatus GetKnownDeadTerminationStatus(ProcessHandle handle,
+ int* exit_code) {
+ bool result = kill(handle, SIGKILL) == 0;
+
+ if (!result)
+ DPLOG(ERROR) << "Unable to terminate process " << handle;
+
return GetTerminationStatusImpl(handle, true /* can_block */, exit_code);
}