summaryrefslogtreecommitdiffstats
path: root/components/error_page
diff options
context:
space:
mode:
authormmenke <mmenke@chromium.org>2015-12-01 15:20:58 -0800
committerCommit bot <commit-bot@chromium.org>2015-12-01 23:21:56 +0000
commit5b69f5a09b685b2d6d8a846a5122fccecac5a5ad (patch)
tree8840e5bd8895d0f9368e8426b415bdd1865242e0 /components/error_page
parent0eb17a8618deb6913ad6a1ef0de65c57960c4f82 (diff)
downloadchromium_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.cc73
-rw-r--r--components/error_page/renderer/net_error_helper_core.h47
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