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

Side by Side Diff: content/browser/renderer_host/render_view_host_impl.cc

Issue 10907182: Add UMA counter for hung renderers on cross-site navigation. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebasing on current tree. Created 8 years, 2 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/renderer_host/render_view_host_impl.h" 5 #include "content/browser/renderer_host/render_view_host_impl.h"
6 6
7 #include <set> 7 #include <set>
8 #include <string> 8 #include <string>
9 #include <utility> 9 #include <utility>
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/i18n/rtl.h" 12 #include "base/i18n/rtl.h"
13 #include "base/json/json_reader.h" 13 #include "base/json/json_reader.h"
14 #include "base/json/json_writer.h" 14 #include "base/json/json_writer.h"
15 #include "base/command_line.h" 15 #include "base/command_line.h"
16 #include "base/message_loop.h" 16 #include "base/message_loop.h"
17 #include "base/metrics/histogram.h"
17 #include "base/stl_util.h" 18 #include "base/stl_util.h"
18 #include "base/string_util.h" 19 #include "base/string_util.h"
19 #include "base/time.h" 20 #include "base/time.h"
20 #include "base/utf_string_conversions.h" 21 #include "base/utf_string_conversions.h"
21 #include "base/values.h" 22 #include "base/values.h"
22 #include "content/browser/accessibility/browser_accessibility_state_impl.h" 23 #include "content/browser/accessibility/browser_accessibility_state_impl.h"
23 #include "content/browser/child_process_security_policy_impl.h" 24 #include "content/browser/child_process_security_policy_impl.h"
24 #include "content/browser/cross_site_request_manager.h" 25 #include "content/browser/cross_site_request_manager.h"
25 #include "content/browser/dom_storage/session_storage_namespace_impl.h" 26 #include "content/browser/dom_storage/session_storage_namespace_impl.h"
26 #include "content/browser/gpu/gpu_surface_tracker.h" 27 #include "content/browser/gpu/gpu_surface_tracker.h"
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 waiting_for_drag_context_response_(false), 164 waiting_for_drag_context_response_(false),
164 enabled_bindings_(0), 165 enabled_bindings_(0),
165 pending_request_id_(-1), 166 pending_request_id_(-1),
166 navigations_suspended_(false), 167 navigations_suspended_(false),
167 suspended_nav_message_(NULL), 168 suspended_nav_message_(NULL),
168 is_swapped_out_(swapped_out), 169 is_swapped_out_(swapped_out),
169 run_modal_reply_msg_(NULL), 170 run_modal_reply_msg_(NULL),
170 run_modal_opener_id_(MSG_ROUTING_NONE), 171 run_modal_opener_id_(MSG_ROUTING_NONE),
171 is_waiting_for_beforeunload_ack_(false), 172 is_waiting_for_beforeunload_ack_(false),
172 is_waiting_for_unload_ack_(false), 173 is_waiting_for_unload_ack_(false),
174 has_timed_out_on_unload_(false),
173 unload_ack_is_for_cross_site_transition_(false), 175 unload_ack_is_for_cross_site_transition_(false),
174 are_javascript_messages_suppressed_(false), 176 are_javascript_messages_suppressed_(false),
175 sudden_termination_allowed_(false), 177 sudden_termination_allowed_(false),
176 session_storage_namespace_( 178 session_storage_namespace_(
177 static_cast<SessionStorageNamespaceImpl*>(session_storage)), 179 static_cast<SessionStorageNamespaceImpl*>(session_storage)),
178 save_accessibility_tree_for_testing_(false), 180 save_accessibility_tree_for_testing_(false),
179 render_view_termination_status_(base::TERMINATION_STATUS_STILL_RUNNING) { 181 render_view_termination_status_(base::TERMINATION_STATUS_STILL_RUNNING) {
180 DCHECK(session_storage_namespace_); 182 DCHECK(session_storage_namespace_);
181 DCHECK(instance_); 183 DCHECK(instance_);
182 CHECK(delegate_); // http://crbug.com/82827 184 CHECK(delegate_); // http://crbug.com/82827
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
441 // which we will do through the RenderProcessHost's widget helper. 443 // which we will do through the RenderProcessHost's widget helper.
442 GetProcess()->SimulateSwapOutACK(params); 444 GetProcess()->SimulateSwapOutACK(params);
443 } 445 }
444 } 446 }
445 447
446 void RenderViewHostImpl::OnSwapOutACK(bool timed_out) { 448 void RenderViewHostImpl::OnSwapOutACK(bool timed_out) {
447 // Stop the hang monitor now that the unload handler has finished. 449 // Stop the hang monitor now that the unload handler has finished.
448 decrement_in_flight_event_count(); 450 decrement_in_flight_event_count();
449 StopHangMonitorTimeout(); 451 StopHangMonitorTimeout();
450 is_waiting_for_unload_ack_ = false; 452 is_waiting_for_unload_ack_ = false;
453 has_timed_out_on_unload_ = timed_out;
451 delegate_->SwappedOut(this); 454 delegate_->SwappedOut(this);
452 } 455 }
453 456
454 void RenderViewHostImpl::WasSwappedOut() { 457 void RenderViewHostImpl::WasSwappedOut() {
455 // Don't bother reporting hung state anymore. 458 // Don't bother reporting hung state anymore.
456 StopHangMonitorTimeout(); 459 StopHangMonitorTimeout();
457 460
461 // If we have timed out on running the unload handler, we consider
462 // the process hung and we should terminate it if there are no other tabs
463 // using the process. If there are other views using this process, the
464 // unresponsive renderer timeout will catch it.
465 bool hung = has_timed_out_on_unload_;
466
458 // Now that we're no longer the active RVH in the tab, start filtering out 467 // Now that we're no longer the active RVH in the tab, start filtering out
459 // most IPC messages. Usually the renderer will have stopped sending 468 // most IPC messages. Usually the renderer will have stopped sending
460 // messages as of OnSwapOutACK. However, we may have timed out waiting 469 // messages as of OnSwapOutACK. However, we may have timed out waiting
461 // for that message, and additional IPC messages may keep streaming in. 470 // for that message, and additional IPC messages may keep streaming in.
462 // We filter them out, as long as that won't cause problems (e.g., we 471 // We filter them out, as long as that won't cause problems (e.g., we
463 // still allow synchronous messages through). 472 // still allow synchronous messages through).
464 SetSwappedOut(true); 473 SetSwappedOut(true);
465 474
475 // If we are not running the renderer in process and no other tab is using
476 // the hung process, consider it eligible to be killed, assuming it is a real
477 // process (unit tests don't have real processes).
478 if (hung) {
479 base::ProcessHandle process_handle = GetProcess()->GetHandle();
480 int views = 0;
481
482 // Count the number of widget hosts for the process, which is equivalent to
483 // views using the process as of this writing.
484 content::RenderProcessHost::RenderWidgetHostsIterator iter(
485 GetProcess()->GetRenderWidgetHostsIterator());
486 for (; !iter.IsAtEnd(); iter.Advance())
487 ++views;
488
489 if (!content::RenderProcessHost::run_renderer_in_process() &&
490 process_handle && views <= 1) {
491 // The process can safely be terminated, only if WebContents sets
492 // SuddenTerminationAllowed, which indicates that the timer has expired.
493 // This is not the case if we load data URLs or about:blank. The reason
494 // is that those have no network requests and this code is hit without
495 // setting the unresponsiveness timer. This allows a corner case where a
496 // navigation to a data URL will leave a process running, if the
497 // beforeunload handler completes fine, but the unload handler hangs.
498 // At this time, the complexity to solve this edge case is not worthwhile.
499 if (SuddenTerminationAllowed()) {
500 // We should kill the process, but for now, just log the data so we can
501 // diagnose the kill rate and investigate if separate timer is needed.
502 // http://crbug.com/104346.
503
504 // Log a histogram point to help us diagnose how many of those kills
505 // we have performed. 1 is the enum value for RendererType Normal for
506 // the histogram.
507 UMA_HISTOGRAM_PERCENTAGE(
508 "BrowserRenderProcessHost.ChildKillsUnresponsive", 1);
509 }
510 }
511 }
512
466 // Inform the renderer that it can exit if no one else is using it. 513 // Inform the renderer that it can exit if no one else is using it.
467 Send(new ViewMsg_WasSwappedOut(GetRoutingID())); 514 Send(new ViewMsg_WasSwappedOut(GetRoutingID()));
468 } 515 }
469 516
470 void RenderViewHostImpl::ClosePage() { 517 void RenderViewHostImpl::ClosePage() {
471 // Start the hang monitor in case the renderer hangs in the unload handler. 518 // Start the hang monitor in case the renderer hangs in the unload handler.
472 is_waiting_for_unload_ack_ = true; 519 is_waiting_for_unload_ack_ = true;
473 StartHangMonitorTimeout(TimeDelta::FromMilliseconds(kUnloadTimeoutMS)); 520 StartHangMonitorTimeout(TimeDelta::FromMilliseconds(kUnloadTimeoutMS));
474 521
475 if (IsRenderViewLive()) { 522 if (IsRenderViewLive()) {
(...skipping 1480 matching lines...) Expand 10 before | Expand all | Expand 10 after
1956 } 2003 }
1957 2004
1958 void RenderViewHostImpl::SetSwappedOut(bool is_swapped_out) { 2005 void RenderViewHostImpl::SetSwappedOut(bool is_swapped_out) {
1959 is_swapped_out_ = is_swapped_out; 2006 is_swapped_out_ = is_swapped_out;
1960 2007
1961 // Whenever we change swap out state, we should not be waiting for 2008 // Whenever we change swap out state, we should not be waiting for
1962 // beforeunload or unload acks. We clear them here to be safe, since they 2009 // beforeunload or unload acks. We clear them here to be safe, since they
1963 // can cause navigations to be ignored in OnMsgNavigate. 2010 // can cause navigations to be ignored in OnMsgNavigate.
1964 is_waiting_for_beforeunload_ack_ = false; 2011 is_waiting_for_beforeunload_ack_ = false;
1965 is_waiting_for_unload_ack_ = false; 2012 is_waiting_for_unload_ack_ = false;
2013 has_timed_out_on_unload_ = false;
1966 } 2014 }
1967 2015
1968 void RenderViewHostImpl::ClearPowerSaveBlockers() { 2016 void RenderViewHostImpl::ClearPowerSaveBlockers() {
1969 STLDeleteValues(&power_save_blockers_); 2017 STLDeleteValues(&power_save_blockers_);
1970 } 2018 }
1971 2019
1972 } // namespace content 2020 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/renderer_host/render_view_host_impl.h ('k') | content/browser/web_contents/render_view_host_manager.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698