diff options
author | mmenke <mmenke@chromium.org> | 2015-12-01 15:20:58 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-12-01 23:21:56 +0000 |
commit | 5b69f5a09b685b2d6d8a846a5122fccecac5a5ad (patch) | |
tree | 8840e5bd8895d0f9368e8426b415bdd1865242e0 /components/error_page | |
parent | 0eb17a8618deb6913ad6a1ef0de65c57960c4f82 (diff) | |
download | chromium_src-5b69f5a09b685b2d6d8a846a5122fccecac5a5ad.zip chromium_src-5b69f5a09b685b2d6d8a846a5122fccecac5a5ad.tar.gz chromium_src-5b69f5a09b685b2d6d8a846a5122fccecac5a5ad.tar.bz2 |
Add code to network error page to figure out a renderer crash.
It looks like NetErrorHelperCore may be seeing events in an
unexpected order, so this CL logs events as they occur, and
when in a situation that is causing the crash, makes sure the
log is in the crash dump.
BUG=557541
Review URL: https://codereview.chromium.org/1482363005
Cr-Commit-Position: refs/heads/master@{#362542}
Diffstat (limited to 'components/error_page')
-rw-r--r-- | components/error_page/renderer/net_error_helper_core.cc | 73 | ||||
-rw-r--r-- | components/error_page/renderer/net_error_helper_core.h | 47 |
2 files changed, 120 insertions, 0 deletions
diff --git a/components/error_page/renderer/net_error_helper_core.cc b/components/error_page/renderer/net_error_helper_core.cc index e120307..abd1bb1 100644 --- a/components/error_page/renderer/net_error_helper_core.cc +++ b/components/error_page/renderer/net_error_helper_core.cc @@ -10,6 +10,8 @@ #include "base/bind.h" #include "base/callback.h" +#include "base/debug/alias.h" +#include "base/debug/dump_without_crashing.h" #include "base/i18n/rtl.h" #include "base/json/json_reader.h" #include "base/json/json_value_converter.h" @@ -38,6 +40,8 @@ namespace error_page { namespace { +#define MAX_DEBUG_HISTORY_EVENTS 50 + struct CorrectionTypeToResourceTable { int resource_id; const char* correction_type; @@ -487,6 +491,8 @@ NetErrorHelperCore::~NetErrorHelperCore() { } void NetErrorHelperCore::CancelPendingFetches() { + RecordHistoryDebugEvent(HistoryDebugEvent::CANCEL_PENDING_FETCHES); + // Cancel loading the alternate error page, and prevent any pending error page // load from starting a new error page load. Swapping in the error page when // it's finished loading could abort the navigation, otherwise. @@ -500,6 +506,8 @@ void NetErrorHelperCore::CancelPendingFetches() { } void NetErrorHelperCore::OnStop() { + RecordHistoryDebugEvent(HistoryDebugEvent::ON_STOP); + if (committed_error_page_info_ && committed_error_page_info_->auto_reload_triggered) { ReportAutoReloadFailure(committed_error_page_info_->error, @@ -512,6 +520,8 @@ void NetErrorHelperCore::OnStop() { } void NetErrorHelperCore::OnWasShown() { + RecordHistoryDebugEvent(HistoryDebugEvent::ON_WAS_SHOWN); + visible_ = true; if (!auto_reload_visible_only_) return; @@ -520,6 +530,8 @@ void NetErrorHelperCore::OnWasShown() { } void NetErrorHelperCore::OnWasHidden() { + RecordHistoryDebugEvent(HistoryDebugEvent::ON_WAS_HIDDEN); + visible_ = false; if (!auto_reload_visible_only_) return; @@ -530,6 +542,8 @@ void NetErrorHelperCore::OnStartLoad(FrameType frame_type, PageType page_type) { if (frame_type != MAIN_FRAME) return; + RecordHistoryDebugEvent(HistoryDebugEvent::ON_START_LOAD); + uncommitted_load_started_ = true; // If there's no pending error page information associated with the page load, @@ -542,6 +556,8 @@ void NetErrorHelperCore::OnCommitLoad(FrameType frame_type, const GURL& url) { if (frame_type != MAIN_FRAME) return; + RecordHistoryDebugEvent(HistoryDebugEvent::ON_COMMIT_LOAD); + // If a page is committing, either it's an error page and autoreload will be // started again below, or it's a success page and we need to clear autoreload // state. @@ -580,14 +596,20 @@ void NetErrorHelperCore::OnCommitLoad(FrameType frame_type, const GURL& url) { } committed_error_page_info_.reset(pending_error_page_info_.release()); + + RecordHistoryDebugEvent(HistoryDebugEvent::ON_COMMIT_LOAD_END); } void NetErrorHelperCore::OnFinishLoad(FrameType frame_type) { if (frame_type != MAIN_FRAME) return; + RecordHistoryDebugEvent(HistoryDebugEvent::ON_FINISH_LOAD); + if (!committed_error_page_info_) { auto_reload_count_ = 0; + RecordHistoryDebugEvent( + HistoryDebugEvent::ON_FINISH_LOAD_END_NOT_ERROR_PAGE); return; } @@ -633,10 +655,12 @@ void NetErrorHelperCore::OnFinishLoad(FrameType frame_type) { if (!committed_error_page_info_->needs_dns_updates || last_probe_status_ == DNS_PROBE_POSSIBLE) { + RecordHistoryDebugEvent(HistoryDebugEvent::ON_FINISH_LOAD_END_DNS_PROBE); return; } DVLOG(1) << "Error page finished loading; sending saved status."; UpdateErrorPage(); + RecordHistoryDebugEvent(HistoryDebugEvent::ON_FINISH_LOAD_END_NO_DNS_PROBE); } void NetErrorHelperCore::GetErrorHTML(FrameType frame_type, @@ -649,6 +673,7 @@ void NetErrorHelperCore::GetErrorHTML(FrameType frame_type, // cancelled earlier by starting a new page load (Which has now failed). DCHECK(!committed_error_page_info_ || !committed_error_page_info_->needs_load_navigation_corrections); + RecordHistoryDebugEvent(HistoryDebugEvent::GET_ERROR_HTML); pending_error_page_info_.reset( new ErrorPageInfo(error, is_failed_post, is_ignoring_cache)); @@ -677,6 +702,8 @@ void NetErrorHelperCore::GetErrorHTML(FrameType frame_type, void NetErrorHelperCore::OnNetErrorInfo(DnsProbeStatus status) { DCHECK_NE(DNS_PROBE_POSSIBLE, status); + RecordHistoryDebugEvent(HistoryDebugEvent::NET_ERROR_INFO_RECEIVED); + last_probe_status_ = status; if (!committed_error_page_info_ || @@ -755,6 +782,8 @@ void NetErrorHelperCore::UpdateErrorPage() { DCHECK(committed_error_page_info_->is_finished_loading); DCHECK_NE(DNS_PROBE_POSSIBLE, last_probe_status_); + RecordHistoryDebugEvent(HistoryDebugEvent::UPDATE_ERROR_PAGE); + UMA_HISTOGRAM_ENUMERATION("DnsProbe.ErrorPageUpdateStatus", last_probe_status_, DNS_PROBE_MAX); @@ -785,6 +814,8 @@ void NetErrorHelperCore::OnNavigationCorrectionsFetched( DCHECK(committed_error_page_info_->needs_load_navigation_corrections); DCHECK(committed_error_page_info_->navigation_correction_params); + RecordHistoryDebugEvent(HistoryDebugEvent::NAVIGATION_CORRECTIONS_FETCHED); + pending_error_page_info_.reset(new ErrorPageInfo( committed_error_page_info_->error, committed_error_page_info_->was_failed_post, @@ -848,6 +879,8 @@ blink::WebURLError NetErrorHelperCore::GetUpdatedError( } void NetErrorHelperCore::Reload(bool ignore_cache) { + RecordHistoryDebugEvent(HistoryDebugEvent::RELOAD); + if (!committed_error_page_info_) { return; } @@ -855,6 +888,8 @@ void NetErrorHelperCore::Reload(bool ignore_cache) { } bool NetErrorHelperCore::MaybeStartAutoReloadTimer() { + RecordHistoryDebugEvent(HistoryDebugEvent::MAYBE_RELOAD); + if (!committed_error_page_info_ || !committed_error_page_info_->is_finished_loading || pending_error_page_info_ || @@ -870,9 +905,12 @@ void NetErrorHelperCore::StartAutoReloadTimer() { DCHECK(committed_error_page_info_); DCHECK(IsReloadableError(*committed_error_page_info_)); + RecordHistoryDebugEvent(HistoryDebugEvent::START_RELOAD_TIMER); + committed_error_page_info_->auto_reload_triggered = true; if (!online_ || (!visible_ && auto_reload_visible_only_)) { + RecordHistoryDebugEvent(HistoryDebugEvent::START_RELOAD_TIMER_PAUSED); auto_reload_paused_ = true; return; } @@ -893,12 +931,29 @@ void NetErrorHelperCore::AutoReloadTimerFired() { // auto-reload timer. DCHECK(committed_error_page_info_); + RecordHistoryDebugEvent(HistoryDebugEvent::RELOAD_TIMER_FIRED); + auto_reload_count_++; auto_reload_in_flight_ = true; + + if (!committed_error_page_info_) { + HistoryDebugEvent history_debug_events[MAX_DEBUG_HISTORY_EVENTS]; + size_t num_history_debug_events = history_debug_events_.size(); + for (size_t i = 0; i < num_history_debug_events; ++i) { + history_debug_events[i] = history_debug_events_[i]; + } + base::debug::Alias(history_debug_events); + base::debug::Alias(&num_history_debug_events); + base::debug::DumpWithoutCrashing(); + return; + } + Reload(committed_error_page_info_->was_ignoring_cache); } void NetErrorHelperCore::PauseAutoReloadTimer() { + RecordHistoryDebugEvent(HistoryDebugEvent::PAUSE_RELOAD_TIMER); + if (!auto_reload_timer_->IsRunning()) return; DCHECK(committed_error_page_info_); @@ -909,6 +964,8 @@ void NetErrorHelperCore::PauseAutoReloadTimer() { } void NetErrorHelperCore::NetworkStateChanged(bool online) { + RecordHistoryDebugEvent(HistoryDebugEvent::NETWORK_STATE_CHANGED); + bool was_online = online_; online_ = online; if (!was_online && online) { @@ -929,6 +986,8 @@ bool NetErrorHelperCore::ShouldSuppressErrorPage(FrameType frame_type, if (frame_type != MAIN_FRAME) return false; + RecordHistoryDebugEvent(HistoryDebugEvent::SHOULD_SUPPRESS_ERROR_PAGE); + // If there's no auto reload attempt in flight, this error page didn't come // from auto reload, so don't suppress it. if (!auto_reload_in_flight_) @@ -947,6 +1006,8 @@ void NetErrorHelperCore::ExecuteButtonPress(Button button) { // If there's no committed error page, should not be invoked. DCHECK(committed_error_page_info_); + RecordHistoryDebugEvent(HistoryDebugEvent::EXECUTE_BUTTON_PRESS); + switch (button) { case RELOAD_BUTTON: RecordEvent(NETWORK_ERROR_PAGE_RELOAD_BUTTON_CLICKED); @@ -1039,4 +1100,16 @@ OfflinePageStatus NetErrorHelperCore::GetOfflinePageStatus() const { #endif // defined(OS_ANDROID) } +void NetErrorHelperCore::RecordHistoryDebugEvent( + HistoryDebugEvent::EventType event_type) { + if (history_debug_events_.size() > MAX_DEBUG_HISTORY_EVENTS) + history_debug_events_.erase(history_debug_events_.begin()); + HistoryDebugEvent event; + event.event_type = event_type; + event.pending_error_page_info_exists = !!pending_error_page_info_; + event.committed_error_page_info_exists = !!committed_error_page_info_; + event.timer_running = auto_reload_timer_->IsRunning(); + history_debug_events_.push_back(event); +} + } // namespace error_page diff --git a/components/error_page/renderer/net_error_helper_core.h b/components/error_page/renderer/net_error_helper_core.h index 0d955513..e95b221 100644 --- a/components/error_page/renderer/net_error_helper_core.h +++ b/components/error_page/renderer/net_error_helper_core.h @@ -6,6 +6,7 @@ #define COMPONENTS_ERROR_PAGE_RENDERER_NET_ERROR_HELPER_CORE_H_ #include <string> +#include <vector> #include "base/callback.h" #include "base/memory/scoped_ptr.h" @@ -225,6 +226,43 @@ class NetErrorHelperCore { private: struct ErrorPageInfo; + // Represents an event that has occured, and the initial state of the + // NetErrorHelperCore when it occured. + // TODO(mmenke): Remove once https://crbug.com/557541 is fixed. + struct HistoryDebugEvent { + enum EventType { + GET_ERROR_HTML = 0, + ON_START_LOAD = 1, + ON_COMMIT_LOAD = 2, + ON_COMMIT_LOAD_END = 3, + ON_FINISH_LOAD = 4, + ON_FINISH_LOAD_END_NOT_ERROR_PAGE = 5, + ON_FINISH_LOAD_END_DNS_PROBE = 6, + ON_FINISH_LOAD_END_NO_DNS_PROBE = 7, + ON_STOP = 8, + ON_WAS_SHOWN = 9, + ON_WAS_HIDDEN = 10, + CANCEL_PENDING_FETCHES = 11, + NAVIGATION_CORRECTIONS_FETCHED = 12, + NET_ERROR_INFO_RECEIVED = 13, + NETWORK_STATE_CHANGED = 14, + SHOULD_SUPPRESS_ERROR_PAGE = 15, + EXECUTE_BUTTON_PRESS = 16, + MAYBE_RELOAD = 17, + RELOAD = 18, + START_RELOAD_TIMER = 19, + RELOAD_TIMER_FIRED = 20, + PAUSE_RELOAD_TIMER = 21, + UPDATE_ERROR_PAGE = 22, + START_RELOAD_TIMER_PAUSED = 23, + }; + + EventType event_type; + bool pending_error_page_info_exists; + bool committed_error_page_info_exists; + bool timer_running; + }; + // Gets HTML for a main frame error page. Depending on // |pending_error_page_info|, may use the navigation correction service, or // show a DNS probe error page. May modify |pending_error_page_info|. @@ -248,6 +286,11 @@ class NetErrorHelperCore { static bool IsReloadableError(const ErrorPageInfo& info); + // Adds the specified event, along with information about the current state of + // |this|, to |history_|. + // TODO(mmenke): Remove once https://crbug.com/557541 is fixed. + void RecordHistoryDebugEvent(HistoryDebugEvent::EventType event_type); + Delegate* delegate_; // The last DnsProbeStatus received from the browser. @@ -308,6 +351,10 @@ class NetErrorHelperCore { // the error page. It is used to detect when such navigations result // in errors. Button navigation_from_button_; + + // Record of the most recent events that have occurred. + // TODO(mmenke): Remove once https://crbug.com/557541 is fixed. + std::vector<HistoryDebugEvent> history_debug_events_; }; } // namespace error_page |