Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1446)

Unified Diff: android_webview/browser/aw_browser_terminator.cc

Issue 2651743006: Implement Crash Handle API (Closed)
Patch Set: Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: android_webview/browser/aw_browser_terminator.cc
diff --git a/android_webview/browser/aw_browser_terminator.cc b/android_webview/browser/aw_browser_terminator.cc
index 23c42856fdf84fbebcd58067417c979c8f91c7db..34052e0a0994061b923adf220440b694cdf84f89 100644
--- a/android_webview/browser/aw_browser_terminator.cc
+++ b/android_webview/browser/aw_browser_terminator.cc
@@ -6,6 +6,7 @@
#include <unistd.h>
+#include "android_webview/browser/aw_render_process_gone_delegate.h"
#include "android_webview/common/aw_descriptors.h"
#include "android_webview/common/crash_reporter/aw_microdump_crash_reporter.h"
#include "base/bind.h"
@@ -17,11 +18,64 @@
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/render_view_host.h"
+#include "content/public/browser/render_widget_host.h"
+#include "content/public/browser/render_widget_host_iterator.h"
+#include "content/public/browser/web_contents.h"
using content::BrowserThread;
namespace android_webview {
+namespace {
+
+void GetAwRenderProcessGoneDelegatesForRenderProcess(
+ int render_process_id,
+ std::vector<AwRenderProcessGoneDelegate*>* delegates) {
+ content::RenderProcessHost* rph =
+ content::RenderProcessHost::FromID(render_process_id);
+ if (!rph)
+ return;
+
+ std::unique_ptr<content::RenderWidgetHostIterator> widgets(
+ content::RenderWidgetHost::GetRenderWidgetHosts());
+ while (content::RenderWidgetHost* widget = widgets->GetNextHost()) {
+ content::RenderViewHost* view = content::RenderViewHost::From(widget);
+ if (view && rph == view->GetProcess()) {
+ content::WebContents* wc = content::WebContents::FromRenderViewHost(view);
+ if (wc) {
+ AwRenderProcessGoneDelegate* delegate =
+ AwRenderProcessGoneDelegate::FromWebContents(wc);
+ if (delegate)
+ delegates->push_back(delegate);
+ }
+ }
+ }
+}
+
+void OnRenderProcessGone(int child_process_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ std::vector<AwRenderProcessGoneDelegate*> delegates;
+ GetAwRenderProcessGoneDelegatesForRenderProcess(child_process_id, &delegates);
+ for (auto delegate : delegates)
+ delegate->OnRenderProcessGone(child_process_id);
+}
+
+void OnRenderProcessGoneDetail(int child_process_id, bool crashed) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ std::vector<AwRenderProcessGoneDelegate*> delegates;
+ GetAwRenderProcessGoneDelegatesForRenderProcess(child_process_id, &delegates);
+ for (auto delegate : delegates) {
+ if (!delegate->OnRenderProcessGoneDetail(child_process_id, crashed)) {
+ // Keeps this log unchanged, CTS test uses it to detect crash.
+ LOG(FATAL) << "Render process's abnormal termination wasn't handled by"
+ << " all associated webviews, triggering application crash";
+ }
+ }
+}
+
+} // namespace
+
AwBrowserTerminator::AwBrowserTerminator() {}
AwBrowserTerminator::~AwBrowserTerminator() {}
@@ -43,19 +97,23 @@ void AwBrowserTerminator::OnChildStart(int child_process_id,
}
void AwBrowserTerminator::ProcessTerminationStatus(
+ int child_process_id,
std::unique_ptr<base::SyncSocket> pipe) {
+ bool crashed = false;
+
+ // If the child process hasn't written anything into the pipe. This implies
+ // that it was terminated via SIGKILL by the low memory killer.
if (pipe->Peek() >= sizeof(int)) {
int exit_code;
pipe->Receive(&exit_code, sizeof(exit_code));
crash_reporter::SuppressDumpGeneration();
- LOG(FATAL) << "Renderer process crash detected (code " << exit_code
- << "). Terminating browser.";
- } else {
- // The child process hasn't written anything into the pipe. This implies
- // that it was terminated via SIGKILL by the low memory killer, and thus we
- // need to perform a clean exit.
- exit(0);
+ LOG(ERROR) << "Renderer process crash detected (code " << exit_code << ").";
+ crashed = true;
}
+
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&OnRenderProcessGoneDetail, child_process_id, crashed));
}
void AwBrowserTerminator::OnChildExit(
@@ -79,10 +137,12 @@ void AwBrowserTerminator::OnChildExit(
}
if (termination_status == base::TERMINATION_STATUS_NORMAL_TERMINATION)
return;
+ OnRenderProcessGone(child_process_id);
DCHECK(pipe->handle() != base::SyncSocket::kInvalidHandle);
BrowserThread::PostTask(
BrowserThread::FILE, FROM_HERE,
base::Bind(&AwBrowserTerminator::ProcessTerminationStatus,
+ child_process_id,
base::Passed(std::move(pipe))));
}
« no previous file with comments | « android_webview/browser/aw_browser_terminator.h ('k') | android_webview/browser/aw_render_process_gone_delegate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698