blob: f6254872b03d1bb0e3ab77313357fe704389bd38 [file] [log] [blame]
blundell8ae15622015-09-28 08:34:161// Copyright 2015 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "components/metrics/stability_metrics_helper.h"
6
avi26062922015-12-26 00:14:187#include <stdint.h>
8
blundell8ae15622015-09-28 08:34:169#include <vector>
10
11#include "base/logging.h"
asvitkine30330812016-08-30 04:01:0812#include "base/metrics/histogram_macros.h"
blundell8ae15622015-09-28 08:34:1613#include "base/metrics/sparse_histogram.h"
bratell0a7406f2017-03-28 07:46:3714#include "base/metrics/user_metrics.h"
avi26062922015-12-26 00:14:1815#include "build/build_config.h"
blundell8ae15622015-09-28 08:34:1616#include "components/metrics/metrics_pref_names.h"
17#include "components/metrics/proto/system_profile.pb.h"
brettwf00b9b42016-02-01 22:11:3818#include "components/prefs/pref_registry_simple.h"
19#include "components/prefs/pref_service.h"
blundell8ae15622015-09-28 08:34:1620
21#if defined(OS_WIN)
22#include <windows.h> // Needed for STATUS_* codes
23#endif
24
25#if defined(OS_CHROMEOS)
26#include "components/metrics/system_memory_stats_recorder.h"
27#endif
28
29namespace metrics {
30
31namespace {
32
33enum RendererType {
34 RENDERER_TYPE_RENDERER = 1,
35 RENDERER_TYPE_EXTENSION,
36 // NOTE: Add new action types only immediately above this line. Also,
37 // make sure the enum list in tools/metrics/histograms/histograms.xml is
38 // updated with any change in here.
39 RENDERER_TYPE_COUNT
40};
41
42// Converts an exit code into something that can be inserted into our
43// histograms (which expect non-negative numbers less than MAX_INT).
44int MapCrashExitCodeForHistogram(int exit_code) {
45#if defined(OS_WIN)
46 // Since |abs(STATUS_GUARD_PAGE_VIOLATION) == MAX_INT| it causes problems in
47 // histograms.cc. Solve this by remapping it to a smaller value, which
48 // hopefully doesn't conflict with other codes.
thakis7bf6418e2015-12-09 22:41:0049 if (static_cast<DWORD>(exit_code) == STATUS_GUARD_PAGE_VIOLATION)
blundell8ae15622015-09-28 08:34:1650 return 0x1FCF7EC3; // Randomly picked number.
51#endif
52
53 return std::abs(exit_code);
54}
55
56void RecordChildKills(int histogram_type) {
57 UMA_HISTOGRAM_ENUMERATION("BrowserRenderProcessHost.ChildKills",
58 histogram_type, RENDERER_TYPE_COUNT);
59}
60
61} // namespace
62
63StabilityMetricsHelper::StabilityMetricsHelper(PrefService* local_state)
64 : local_state_(local_state) {
65 DCHECK(local_state_);
66}
67
68StabilityMetricsHelper::~StabilityMetricsHelper() {}
69
70void StabilityMetricsHelper::ProvideStabilityMetrics(
71 SystemProfileProto* system_profile_proto) {
72 SystemProfileProto_Stability* stability_proto =
73 system_profile_proto->mutable_stability();
74
75 int count = local_state_->GetInteger(prefs::kStabilityPageLoadCount);
76 if (count) {
77 stability_proto->set_page_load_count(count);
78 local_state_->SetInteger(prefs::kStabilityPageLoadCount, 0);
79 }
80
81 count = local_state_->GetInteger(prefs::kStabilityChildProcessCrashCount);
82 if (count) {
83 stability_proto->set_child_process_crash_count(count);
84 local_state_->SetInteger(prefs::kStabilityChildProcessCrashCount, 0);
85 }
86
87 count = local_state_->GetInteger(prefs::kStabilityRendererCrashCount);
88 if (count) {
89 stability_proto->set_renderer_crash_count(count);
90 local_state_->SetInteger(prefs::kStabilityRendererCrashCount, 0);
91 }
92
93 count = local_state_->GetInteger(prefs::kStabilityRendererFailedLaunchCount);
94 if (count) {
95 stability_proto->set_renderer_failed_launch_count(count);
96 local_state_->SetInteger(prefs::kStabilityRendererFailedLaunchCount, 0);
97 }
98
wfh86b6c8c2016-07-15 20:48:3599 count = local_state_->GetInteger(prefs::kStabilityRendererLaunchCount);
100 if (count) {
101 stability_proto->set_renderer_launch_count(count);
102 local_state_->SetInteger(prefs::kStabilityRendererLaunchCount, 0);
103 }
104
blundell8ae15622015-09-28 08:34:16105 count =
106 local_state_->GetInteger(prefs::kStabilityExtensionRendererCrashCount);
107 if (count) {
108 stability_proto->set_extension_renderer_crash_count(count);
109 local_state_->SetInteger(prefs::kStabilityExtensionRendererCrashCount, 0);
110 }
111
112 count = local_state_->GetInteger(
113 prefs::kStabilityExtensionRendererFailedLaunchCount);
114 if (count) {
115 stability_proto->set_extension_renderer_failed_launch_count(count);
116 local_state_->SetInteger(
117 prefs::kStabilityExtensionRendererFailedLaunchCount, 0);
118 }
119
120 count = local_state_->GetInteger(prefs::kStabilityRendererHangCount);
121 if (count) {
122 stability_proto->set_renderer_hang_count(count);
123 local_state_->SetInteger(prefs::kStabilityRendererHangCount, 0);
124 }
wfh86b6c8c2016-07-15 20:48:35125
wfhe982eb42016-07-20 17:45:00126 count =
127 local_state_->GetInteger(prefs::kStabilityExtensionRendererLaunchCount);
wfh86b6c8c2016-07-15 20:48:35128 if (count) {
wfhe982eb42016-07-20 17:45:00129 stability_proto->set_extension_renderer_launch_count(count);
130 local_state_->SetInteger(prefs::kStabilityExtensionRendererLaunchCount, 0);
wfh86b6c8c2016-07-15 20:48:35131 }
blundell8ae15622015-09-28 08:34:16132}
133
134void StabilityMetricsHelper::ClearSavedStabilityMetrics() {
135 // Clear all the prefs used in this class in UMA reports (which doesn't
136 // include |kUninstallMetricsPageLoadCount| as it's not sent up by UMA).
137 local_state_->SetInteger(prefs::kStabilityChildProcessCrashCount, 0);
138 local_state_->SetInteger(prefs::kStabilityExtensionRendererCrashCount, 0);
139 local_state_->SetInteger(prefs::kStabilityExtensionRendererFailedLaunchCount,
140 0);
wfh86b6c8c2016-07-15 20:48:35141 local_state_->SetInteger(prefs::kStabilityExtensionRendererLaunchCount, 0);
blundell8ae15622015-09-28 08:34:16142 local_state_->SetInteger(prefs::kStabilityPageLoadCount, 0);
143 local_state_->SetInteger(prefs::kStabilityRendererCrashCount, 0);
144 local_state_->SetInteger(prefs::kStabilityRendererFailedLaunchCount, 0);
145 local_state_->SetInteger(prefs::kStabilityRendererHangCount, 0);
wfh86b6c8c2016-07-15 20:48:35146 local_state_->SetInteger(prefs::kStabilityRendererLaunchCount, 0);
blundell8ae15622015-09-28 08:34:16147}
148
149// static
150void StabilityMetricsHelper::RegisterPrefs(PrefRegistrySimple* registry) {
151 registry->RegisterIntegerPref(prefs::kStabilityChildProcessCrashCount, 0);
152 registry->RegisterIntegerPref(prefs::kStabilityExtensionRendererCrashCount,
153 0);
154 registry->RegisterIntegerPref(
155 prefs::kStabilityExtensionRendererFailedLaunchCount, 0);
wfh86b6c8c2016-07-15 20:48:35156 registry->RegisterIntegerPref(prefs::kStabilityExtensionRendererLaunchCount,
157 0);
blundell8ae15622015-09-28 08:34:16158 registry->RegisterIntegerPref(prefs::kStabilityPageLoadCount, 0);
159 registry->RegisterIntegerPref(prefs::kStabilityRendererCrashCount, 0);
160 registry->RegisterIntegerPref(prefs::kStabilityRendererFailedLaunchCount, 0);
161 registry->RegisterIntegerPref(prefs::kStabilityRendererHangCount, 0);
wfh86b6c8c2016-07-15 20:48:35162 registry->RegisterIntegerPref(prefs::kStabilityRendererLaunchCount, 0);
blundell8ae15622015-09-28 08:34:16163
164 registry->RegisterInt64Pref(prefs::kUninstallMetricsPageLoadCount, 0);
165}
166
167void StabilityMetricsHelper::BrowserChildProcessCrashed() {
168 IncrementPrefValue(prefs::kStabilityChildProcessCrashCount);
169}
170
171void StabilityMetricsHelper::LogLoadStarted() {
172 base::RecordAction(base::UserMetricsAction("PageLoad"));
173 // TODO(asvitkine): Check if this is used for anything and if not, remove.
174 LOCAL_HISTOGRAM_BOOLEAN("Chrome.UmaPageloadCounter", true);
175 IncrementPrefValue(prefs::kStabilityPageLoadCount);
176 IncrementLongPrefsValue(prefs::kUninstallMetricsPageLoadCount);
177 // We need to save the prefs, as page load count is a critical stat, and it
178 // might be lost due to a crash :-(.
179}
180
181void StabilityMetricsHelper::LogRendererCrash(bool was_extension_process,
182 base::TerminationStatus status,
183 int exit_code) {
184 int histogram_type =
185 was_extension_process ? RENDERER_TYPE_EXTENSION : RENDERER_TYPE_RENDERER;
blundell8ae15622015-09-28 08:34:16186
wfh1633bec62016-08-12 02:07:24187 switch (status) {
188 case base::TERMINATION_STATUS_NORMAL_TERMINATION:
189 break;
190 case base::TERMINATION_STATUS_PROCESS_CRASHED:
191 case base::TERMINATION_STATUS_ABNORMAL_TERMINATION:
192 case base::TERMINATION_STATUS_OOM:
193 if (was_extension_process) {
194 IncrementPrefValue(prefs::kStabilityExtensionRendererCrashCount);
blundell8ae15622015-09-28 08:34:16195
wfh1633bec62016-08-12 02:07:24196 UMA_HISTOGRAM_SPARSE_SLOWLY("CrashExitCodes.Extension",
197 MapCrashExitCodeForHistogram(exit_code));
198 } else {
199 IncrementPrefValue(prefs::kStabilityRendererCrashCount);
blundell8ae15622015-09-28 08:34:16200
wfh1633bec62016-08-12 02:07:24201 UMA_HISTOGRAM_SPARSE_SLOWLY("CrashExitCodes.Renderer",
202 MapCrashExitCodeForHistogram(exit_code));
203 }
204
205 UMA_HISTOGRAM_ENUMERATION("BrowserRenderProcessHost.ChildCrashes",
206 histogram_type, RENDERER_TYPE_COUNT);
207 break;
208 case base::TERMINATION_STATUS_PROCESS_WAS_KILLED:
209 RecordChildKills(histogram_type);
210 break;
211#if defined(OS_ANDROID)
212 case base::TERMINATION_STATUS_OOM_PROTECTED:
213 // TODO(wfh): Check if this should be a Kill or a Crash on Android.
214 break;
blundell8ae15622015-09-28 08:34:16215#endif
wfh1633bec62016-08-12 02:07:24216#if defined(OS_CHROMEOS)
217 case base::TERMINATION_STATUS_PROCESS_WAS_KILLED_BY_OOM:
218 RecordChildKills(histogram_type);
219 UMA_HISTOGRAM_ENUMERATION("BrowserRenderProcessHost.ChildKills.OOM",
220 was_extension_process ? 2 : 1, 3);
221 RecordMemoryStats(was_extension_process
222 ? RECORD_MEMORY_STATS_EXTENSIONS_OOM_KILLED
223 : RECORD_MEMORY_STATS_CONTENTS_OOM_KILLED);
224 break;
225#endif
226 case base::TERMINATION_STATUS_STILL_RUNNING:
227 UMA_HISTOGRAM_ENUMERATION("BrowserRenderProcessHost.DisconnectedAlive",
228 histogram_type, RENDERER_TYPE_COUNT);
229 break;
230 case base::TERMINATION_STATUS_LAUNCH_FAILED:
231 UMA_HISTOGRAM_ENUMERATION("BrowserRenderProcessHost.ChildLaunchFailures",
232 histogram_type, RENDERER_TYPE_COUNT);
233 UMA_HISTOGRAM_SPARSE_SLOWLY(
234 "BrowserRenderProcessHost.ChildLaunchFailureCodes", exit_code);
235 if (was_extension_process)
236 IncrementPrefValue(prefs::kStabilityExtensionRendererFailedLaunchCount);
237 else
238 IncrementPrefValue(prefs::kStabilityRendererFailedLaunchCount);
239 break;
240 case base::TERMINATION_STATUS_MAX_ENUM:
241 NOTREACHED();
242 break;
blundell8ae15622015-09-28 08:34:16243 }
244}
245
wfh86b6c8c2016-07-15 20:48:35246void StabilityMetricsHelper::LogRendererLaunched(bool was_extension_process) {
247 if (was_extension_process)
248 IncrementPrefValue(prefs::kStabilityExtensionRendererLaunchCount);
249 else
250 IncrementPrefValue(prefs::kStabilityRendererLaunchCount);
251}
252
blundell8ae15622015-09-28 08:34:16253void StabilityMetricsHelper::IncrementPrefValue(const char* path) {
254 int value = local_state_->GetInteger(path);
255 local_state_->SetInteger(path, value + 1);
256}
257
258void StabilityMetricsHelper::IncrementLongPrefsValue(const char* path) {
avi26062922015-12-26 00:14:18259 int64_t value = local_state_->GetInt64(path);
blundell8ae15622015-09-28 08:34:16260 local_state_->SetInt64(path, value + 1);
261}
262
263void StabilityMetricsHelper::LogRendererHang() {
264 IncrementPrefValue(prefs::kStabilityRendererHangCount);
265}
266
267} // namespace metrics