summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/app/breakpad.cc37
-rw-r--r--chrome/app/chrome_exe.vcproj8
-rw-r--r--chrome/browser/browser_main.cc12
-rw-r--r--chrome/browser/metrics_log.cc12
-rw-r--r--chrome/browser/metrics_service.cc74
-rw-r--r--chrome/browser/metrics_service.h11
-rw-r--r--chrome/common/env_vars.cc12
-rw-r--r--chrome/common/env_vars.h1
-rw-r--r--chrome/common/pref_names.cc16
-rw-r--r--chrome/common/pref_names.h5
10 files changed, 131 insertions, 57 deletions
diff --git a/chrome/app/breakpad.cc b/chrome/app/breakpad.cc
index dd0aebf..bd66618 100644
--- a/chrome/app/breakpad.cc
+++ b/chrome/app/breakpad.cc
@@ -42,6 +42,7 @@
#include "base/win_util.h"
#include "chrome/app/google_update_client.h"
#include "chrome/app/google_update_settings.h"
+#include "chrome/common/env_vars.h"
#include "breakpad/src/client/windows/handler/exception_handler.h"
namespace {
@@ -100,15 +101,6 @@ struct CrashReporterInfo {
std::wstring process_type;
};
-// Environment variable name that has the actual dialog strings.
-const wchar_t kEnvRestartInfo[] = L"CHROME_RESTART";
-// If this environment variable is present, chrome has crashed.
-const wchar_t kEnvShowRestart[] = L"CHROME_CRASHED";
-// The following two names correspond to the text directionality for the
-// current locale.
-const wchar_t kRtlLocaleDirection[] = L"RIGHT_TO_LEFT";
-const wchar_t kLtrLocaleDirection[] = L"LEFT_TO_RIGHT";
-
// This callback is executed when the browser process has crashed, after
// the crash dump has been created. We need to minimize the amount of work
// done here since we have potentially corrupted process. Our job is to
@@ -120,9 +112,9 @@ bool DumpDoneCallback(const wchar_t*, const wchar_t*, void*,
MDRawAssertionInfo*, bool) {
// We set CHROME_CRASHED env var. If the CHROME_RESTART is present.
// This signals the child process to show the 'chrome has crashed' dialog.
- if (!::GetEnvironmentVariableW(kEnvRestartInfo, NULL, 0))
+ if (!::GetEnvironmentVariableW(env_vars::kRestartInfo, NULL, 0))
return true;
- ::SetEnvironmentVariableW(kEnvShowRestart, L"1");
+ ::SetEnvironmentVariableW(env_vars::kShowRestart, L"1");
// Now we just start chrome browser with the same command line.
STARTUPINFOW si = {sizeof(si)};
PROCESS_INFORMATION pi;
@@ -157,13 +149,13 @@ long WINAPI ChromeExceptionFilter(EXCEPTION_POINTERS* info) {
// spawned and basically just shows the 'chrome has crashed' dialog if
// the CHROME_CRASHED environment variable is present.
bool ShowRestartDialogIfCrashed(bool* exit_now) {
- if (!::GetEnvironmentVariableW(kEnvShowRestart, NULL, 0))
+ if (!::GetEnvironmentVariableW(env_vars::kShowRestart, NULL, 0))
return false;
- DWORD len = ::GetEnvironmentVariableW(kEnvRestartInfo, NULL, 0);
+ DWORD len = ::GetEnvironmentVariableW(env_vars::kRestartInfo, NULL, 0);
if (!len)
return false;
wchar_t* restart_data = new wchar_t[len + 1];
- ::GetEnvironmentVariableW(kEnvRestartInfo, restart_data, len);
+ ::GetEnvironmentVariableW(env_vars::kRestartInfo, restart_data, len);
restart_data[len] = 0;
// The CHROME_RESTART var contains the dialog strings separated by '|'.
// See PrepareRestartOnCrashEnviroment() function for details.
@@ -176,7 +168,7 @@ bool ShowRestartDialogIfCrashed(bool* exit_now) {
// If the UI layout is right-to-left, we need to pass the appropriate MB_XXX
// flags so that an RTL message box is displayed.
UINT flags = MB_OKCANCEL | MB_ICONWARNING;
- if (dlg_strings[2] == kRtlLocaleDirection)
+ if (dlg_strings[2] == env_vars::kRtlLocale)
flags |= MB_RIGHT | MB_RTLREADING;
// Show the dialog now. It is ok if another chrome is started by the
@@ -237,13 +229,18 @@ unsigned __stdcall InitCrashReporterThread(void* param) {
NULL, google_breakpad::ExceptionHandler::HANDLER_ALL,
dump_type, pipe_name.c_str(), info->custom_info);
- // Tells breakpad to handle breakpoint and single step exceptions.
- // This might break JIT debuggers, but at least it will always
- // generate a crashdump for these exceptions.
- g_breakpad->set_handle_debug_exceptions(true);
+ if (!g_breakpad->IsOutOfProcess()) {
+ // The out-of-process handler is unavailable.
+ ::SetEnvironmentVariable(env_vars::kNoOOBreakpad,
+ info->process_type.c_str());
+ } else {
+ // Tells breakpad to handle breakpoint and single step exceptions.
+ // This might break JIT debuggers, but at least it will always
+ // generate a crashdump for these exceptions.
+ g_breakpad->set_handle_debug_exceptions(true);
+ }
delete info;
-
return 0;
}
diff --git a/chrome/app/chrome_exe.vcproj b/chrome/app/chrome_exe.vcproj
index 61110a0..321814d 100644
--- a/chrome/app/chrome_exe.vcproj
+++ b/chrome/app/chrome_exe.vcproj
@@ -197,6 +197,14 @@
>
</File>
<File
+ RelativePath="..\common\env_vars.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\common\env_vars.h"
+ >
+ </File>
+ <File
RelativePath=".\google_update_client.cc"
>
</File>
diff --git a/chrome/browser/browser_main.cc b/chrome/browser/browser_main.cc
index 45308d9..c3531a2 100644
--- a/chrome/browser/browser_main.cc
+++ b/chrome/browser/browser_main.cc
@@ -61,6 +61,7 @@
#include "chrome/browser/shell_integration.h"
#include "chrome/browser/url_fixer_upper.h"
#include "chrome/browser/user_data_dir_dialog.h"
+#include "chrome/browser/user_metrics.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
@@ -247,6 +248,15 @@ bool CreateUniqueChromeEvent() {
return already_running;
}
+// We record in UMA the conditions that can prevent breakpad from generating
+// and sending crash reports. Namely that the crash reporting registration
+// failed and that the process is being debugged.
+void RecordBreakpadStatusUMA(MetricsService* metrics) {
+ DWORD len = ::GetEnvironmentVariableW(env_vars::kNoOOBreakpad, NULL, 0);
+ metrics->RecordBreakpadRegistration((len == 0));
+ metrics->RecordBreakpadHasDebugger(TRUE == ::IsDebuggerPresent());
+}
+
} // namespace
// Main routine for running as the Browser process.
@@ -488,6 +498,8 @@ int BrowserMain(CommandLine &parsed_command_line, int show_command,
HandleErrorTestParameters(parsed_command_line);
+ RecordBreakpadStatusUMA(metrics);
+
int result_code = ResultCodes::NORMAL_EXIT;
if (BrowserInit::ProcessCommandLine(parsed_command_line, L"", local_state,
show_command, true, profile,
diff --git a/chrome/browser/metrics_log.cc b/chrome/browser/metrics_log.cc
index a563ed5..eb0b5be 100644
--- a/chrome/browser/metrics_log.cc
+++ b/chrome/browser/metrics_log.cc
@@ -362,6 +362,18 @@ void MetricsLog::WriteStabilityElement() {
WriteIntAttribute("rendererhangcount",
pref->GetInteger(prefs::kStabilityRendererHangCount));
pref->SetInteger(prefs::kStabilityRendererHangCount, 0);
+ WriteIntAttribute("breakpadregistrationok",
+ pref->GetInteger(prefs::kStabilityBreakpadRegistrationSuccess));
+ pref->SetInteger(prefs::kStabilityBreakpadRegistrationSuccess, 0);
+ WriteIntAttribute("breakpadregistrationfail",
+ pref->GetInteger(prefs::kStabilityBreakpadRegistrationFail));
+ pref->SetInteger(prefs::kStabilityBreakpadRegistrationFail, 0);
+ WriteIntAttribute("debuggerpresent",
+ pref->GetInteger(prefs::kStabilityDebuggerPresent));
+ pref->SetInteger(prefs::kStabilityDebuggerPresent, 0);
+ WriteIntAttribute("debuggernotpresent",
+ pref->GetInteger(prefs::kStabilityDebuggerNotPresent));
+ pref->SetInteger(prefs::kStabilityDebuggerNotPresent, 0);
// Uptime is stored as a string, since there's no int64 in Value/JSON.
WriteAttribute("uptimesec",
diff --git a/chrome/browser/metrics_service.cc b/chrome/browser/metrics_service.cc
index 268e57d..85690a8 100644
--- a/chrome/browser/metrics_service.cc
+++ b/chrome/browser/metrics_service.cc
@@ -327,6 +327,13 @@ void MetricsService::RegisterPrefs(PrefService* local_state) {
local_state->RegisterIntegerPref(prefs::kSecurityRendererOnDefaultDesktop, 0);
local_state->RegisterIntegerPref(prefs::kStabilityRendererCrashCount, 0);
local_state->RegisterIntegerPref(prefs::kStabilityRendererHangCount, 0);
+ local_state->RegisterIntegerPref(prefs::kStabilityBreakpadRegistrationFail,
+ 0);
+ local_state->RegisterIntegerPref(prefs::kStabilityBreakpadRegistrationSuccess,
+ 0);
+ local_state->RegisterIntegerPref(prefs::kStabilityDebuggerPresent, 0);
+ local_state->RegisterIntegerPref(prefs::kStabilityDebuggerNotPresent, 0);
+
local_state->RegisterDictionaryPref(prefs::kProfileMetrics);
local_state->RegisterIntegerPref(prefs::kNumBookmarksOnBookmarkBar, 0);
local_state->RegisterIntegerPref(prefs::kNumFoldersOnBookmarkBar, 0);
@@ -486,6 +493,20 @@ void MetricsService::RecordCompletedSessionEnd() {
RecordBooleanPrefValue(prefs::kStabilitySessionEndCompleted, true);
}
+void MetricsService:: RecordBreakpadRegistration(bool success) {
+ if (!success)
+ IncrementPrefValue(prefs::kStabilityBreakpadRegistrationFail);
+ else
+ IncrementPrefValue(prefs::kStabilityBreakpadRegistrationSuccess);
+}
+
+void MetricsService::RecordBreakpadHasDebugger(bool has_debugger) {
+ if (!has_debugger)
+ IncrementPrefValue(prefs::kStabilityDebuggerNotPresent);
+ else
+ IncrementPrefValue(prefs::kStabilityDebuggerPresent);
+}
+
//------------------------------------------------------------------------------
// private methods
//------------------------------------------------------------------------------
@@ -517,23 +538,17 @@ void MetricsService::InitializeMetricsState() {
DCHECK(done);
// Stability bookkeeping
- int launches = pref->GetInteger(prefs::kStabilityLaunchCount);
- pref->SetInteger(prefs::kStabilityLaunchCount, launches + 1);
+ IncrementPrefValue(prefs::kStabilityLaunchCount);
- bool exited_cleanly = pref->GetBoolean(prefs::kStabilityExitedCleanly);
- if (!exited_cleanly) {
- int crashes = pref->GetInteger(prefs::kStabilityCrashCount);
- pref->SetInteger(prefs::kStabilityCrashCount, crashes + 1);
+ if (!pref->GetBoolean(prefs::kStabilityExitedCleanly)) {
+ IncrementPrefValue(prefs::kStabilityCrashCount);
}
+
+ // This will be set to 'true' if we exit cleanly.
pref->SetBoolean(prefs::kStabilityExitedCleanly, false);
- bool shutdown_cleanly =
- pref->GetBoolean(prefs::kStabilitySessionEndCompleted);
- if (!shutdown_cleanly) {
- int incomplete_session_end_count = pref->GetInteger(
- prefs::kStabilityIncompleteSessionEndCount);
- pref->SetInteger(prefs::kStabilityIncompleteSessionEndCount,
- incomplete_session_end_count + 1);
+ if (!pref->GetBoolean(prefs::kStabilitySessionEndCompleted)) {
+ IncrementPrefValue(prefs::kStabilityIncompleteSessionEndCount);
}
// This is marked false when we get a WM_ENDSESSION.
pref->SetBoolean(prefs::kStabilitySessionEndCompleted, true);
@@ -1219,11 +1234,15 @@ void MetricsService::LogLoadComplete(NotificationType type,
load_details->load_time());
}
+void MetricsService::IncrementPrefValue(const wchar_t* path) {
+ PrefService* pref = g_browser_process->local_state();
+ DCHECK(pref);
+ int value = pref->GetInteger(path);
+ pref->SetInteger(path, value + 1);
+}
+
void MetricsService::LogLoadStarted() {
- PrefService* prefs = g_browser_process->local_state();
- DCHECK(prefs);
- int loads = prefs->GetInteger(prefs::kStabilityPageLoadCount);
- prefs->SetInteger(prefs::kStabilityPageLoadCount, loads + 1);
+ IncrementPrefValue(prefs::kStabilityPageLoadCount);
// We need to save the prefs, as page load count is a critical stat, and
// it might be lost due to a crash :-(.
}
@@ -1231,27 +1250,18 @@ void MetricsService::LogLoadStarted() {
void MetricsService::LogRendererInSandbox(bool on_sandbox_desktop) {
PrefService* prefs = g_browser_process->local_state();
DCHECK(prefs);
- if (on_sandbox_desktop) {
- int count = prefs->GetInteger(prefs::kSecurityRendererOnSboxDesktop);
- prefs->SetInteger(prefs::kSecurityRendererOnSboxDesktop, count + 1);
- } else {
- int count = prefs->GetInteger(prefs::kSecurityRendererOnDefaultDesktop);
- prefs->SetInteger(prefs::kSecurityRendererOnDefaultDesktop, count + 1);
- }
+ if (on_sandbox_desktop)
+ IncrementPrefValue(prefs::kSecurityRendererOnSboxDesktop);
+ else
+ IncrementPrefValue(prefs::kSecurityRendererOnDefaultDesktop);
}
void MetricsService::LogRendererCrash() {
- PrefService* prefs = g_browser_process->local_state();
- DCHECK(prefs);
- int crashes = prefs->GetInteger(prefs::kStabilityRendererCrashCount);
- prefs->SetInteger(prefs::kStabilityRendererCrashCount, crashes + 1);
+ IncrementPrefValue(prefs::kStabilityRendererCrashCount);
}
void MetricsService::LogRendererHang() {
- PrefService* prefs = g_browser_process->local_state();
- DCHECK(prefs);
- int hangs = prefs->GetInteger(prefs::kStabilityRendererHangCount);
- prefs->SetInteger(prefs::kStabilityRendererHangCount, hangs + 1);
+ IncrementPrefValue(prefs::kStabilityRendererHangCount);
}
void MetricsService::LogPluginChange(NotificationType type,
diff --git a/chrome/browser/metrics_service.h b/chrome/browser/metrics_service.h
index dc65d45..4524bc6 100644
--- a/chrome/browser/metrics_service.h
+++ b/chrome/browser/metrics_service.h
@@ -116,6 +116,14 @@ class MetricsService : public NotificationObserver,
// that session end was successful.
void RecordCompletedSessionEnd();
+ // Saves in the preferences if the crash report registration was successful.
+ // This count is eventually send via UMA logs.
+ void RecordBreakpadRegistration(bool success);
+
+ // Saves in the preferences if the browser is running under a debugger.
+ // This count is eventually send via UMA logs.
+ void RecordBreakpadHasDebugger(bool has_debugger);
+
// Callback to let us knew that the plugin list is warmed up.
void OnGetPluginListTaskComplete();
@@ -226,6 +234,9 @@ class MetricsService : public NotificationObserver,
const NotificationSource& source,
const NotificationDetails& details);
+ // Reads, increments and then sets the specified integer preference.
+ void IncrementPrefValue(const wchar_t* path);
+
// Records a renderer process crash.
void LogRendererCrash();
diff --git a/chrome/common/env_vars.cc b/chrome/common/env_vars.cc
index 17ac68f..971669f 100644
--- a/chrome/common/env_vars.cc
+++ b/chrome/common/env_vars.cc
@@ -42,15 +42,17 @@ const wchar_t kLogFileName[] = L"CHROME_LOG_FILE";
// CHROME_CRASHED exists if a previous instance of chrome has crashed. This
// triggers the 'restart chrome' dialog. CHROME_RESTART contains the strings
// that are needed to show the dialog.
-//
+const wchar_t kShowRestart[] = L"CHROME_CRASHED";
+const wchar_t kRestartInfo[] = L"CHROME_RESTART";
+
// The strings RIGHT_TO_LEFT and LEFT_TO_RIGHT indicate the locale direction.
// For example, for Hebrew and Arabic locales, we use RIGHT_TO_LEFT so that the
// dialog is displayed using the right orientation.
-//
-// If you modify these constants, you also need to modify them in breakpad.cc.
-const wchar_t kShowRestart[] = L"CHROME_CRASHED";
-const wchar_t kRestartInfo[] = L"CHROME_RESTART";
const wchar_t kRtlLocale[] = L"RIGHT_TO_LEFT";
const wchar_t kLtrLocale[] = L"LEFT_TO_RIGHT";
+// If the out-of-process breakpad could not be installed, we set this variable
+// according to the process.
+const wchar_t kNoOOBreakpad[] = L"NO_OO_BREAKPAD";
+
} // namespace env_vars
diff --git a/chrome/common/env_vars.h b/chrome/common/env_vars.h
index 51b18ad..5ba9743 100644
--- a/chrome/common/env_vars.h
+++ b/chrome/common/env_vars.h
@@ -40,6 +40,7 @@ extern const wchar_t kShowRestart[];
extern const wchar_t kRestartInfo[];
extern const wchar_t kRtlLocale[];
extern const wchar_t kLtrLocale[];
+extern const wchar_t kNoOOBreakpad[];
} // namespace env_vars
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index ea7ec00..123cdee 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -325,6 +325,22 @@ const wchar_t kStabilityPluginStats[] =
const wchar_t kStabilityRendererHangCount[] =
L"user_experience_metrics.stability.renderer_hang_count";
+// Number of times the browser has been able to register crash reporting.
+const wchar_t kStabilityBreakpadRegistrationSuccess[] =
+ L"user_experience_metrics.stability.breakpad_registration_ok";
+
+// Number of times the browser has failed to register crash reporting.
+const wchar_t kStabilityBreakpadRegistrationFail[] =
+ L"user_experience_metrics.stability.breakpad_registration_fail";
+
+// Number of times the browser has been run under a debugger.
+const wchar_t kStabilityDebuggerPresent[] =
+ L"user_experience_metrics.stability.debugger_present";
+
+// Number of times the browser has not been run under a debugger.
+const wchar_t kStabilityDebuggerNotPresent[] =
+ L"user_experience_metrics.stability.debugger_not_present";
+
// The keys below are used for the dictionaries in the
// kStabilityPluginStats list.
const wchar_t kStabilityPluginPath[] = L"path";
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index 610f2ed..ceb3a9b 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -115,6 +115,11 @@ extern const wchar_t kStabilityLastTimestampSec[];
extern const wchar_t kStabilityUptimeSec[];
extern const wchar_t kStabilityRendererHangCount[];
+extern const wchar_t kStabilityBreakpadRegistrationSuccess[];
+extern const wchar_t kStabilityBreakpadRegistrationFail[];
+extern const wchar_t kStabilityDebuggerPresent[];
+extern const wchar_t kStabilityDebuggerNotPresent[];
+
extern const wchar_t kSecurityRendererOnSboxDesktop[];
extern const wchar_t kSecurityRendererOnDefaultDesktop[];