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

Side by Side Diff: components/browser_watcher/crash_reporting_metrics_win.cc

Issue 1922473003: Scrub the vestigal breakpad crash dump attempts metrics code. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address Greg's comments. Created 4 years, 7 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
OLDNEW
(Empty)
1 // 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/browser_watcher/crash_reporting_metrics_win.h"
6
7 #include <stddef.h>
8
9 #include <algorithm>
10 #include "base/atomicops.h"
11 #include "base/guid.h"
12 #include "base/logging.h"
13 #include "base/macros.h"
14 #include "base/strings/safe_sprintf.h"
15 #include "base/strings/string_util.h"
16 #include "base/strings/utf_string_conversions.h"
17 #include "base/win/registry.h"
18
19 namespace browser_watcher {
20
21 namespace {
22
23 // The prior implementation used 0 and 1. Its data collection is inconsistent
24 // with ours and it's best to just ignore its records. So we start at 2.
25 const DWORD kCrashDumpAttempt = 2;
26 const DWORD kDumpWithoutCrashAttempt = 3;
27 const DWORD kCrashDumpSuccess = 4;
28 const DWORD kCrashDumpFailure = 5;
29 const DWORD kDumpWithoutCrashSuccess = 6;
30 const DWORD kDumpWithoutCrashFailure = 7;
31
32 // A prefix intended to avoid registry value name collisions with other
33 // processes (or modules within a single process). It is not necessary for the
34 // reading and writing instances to share the prefix value. This array is sized
35 // to hold a null-terminated string as generated by base::GenerateGUID.
36 char g_unique_prefix[36 + 1] = {0};
37
38 // An atomic counter intended to make each registry value name unique within
39 // this process and module.
40 base::subtle::Atomic32 g_record_count = 0;
41
42 // The length of a null-terminated string consisting of "{GUID}-{COUNT}".
43 const size_t kValueNameSize = 36 + 1 + 8 + 1;
44
45 void WriteValue(const base::string16& key_path, DWORD value) {
46 // Generate the final value name we'll use (appends the crash number to the
47 // base value name).
48 char value_name_ascii[kValueNameSize] = "";
49 base::char16 value_name_utf16[kValueNameSize] = L"";
50
51 if (base::strings::SafeSPrintf(
52 value_name_ascii, "%s-%x", g_unique_prefix,
53 base::subtle::NoBarrier_AtomicIncrement(&g_record_count, 1)) <= 0) {
54 NOTREACHED();
55 } else {
56 // Since it's an ASCII string, the UTF-16 form is identical with leading 0
57 // bytes. We're avoiding unnecessary heap operations since we're running in
58 // a compromised process.
59 std::copy(value_name_ascii, value_name_ascii + kValueNameSize,
60 value_name_utf16);
61
62 base::win::RegKey reg_key;
63 if (reg_key.Create(HKEY_CURRENT_USER, key_path.c_str(), KEY_SET_VALUE) !=
64 ERROR_SUCCESS) {
65 NOTREACHED();
66 } else {
67 reg_key.WriteValue(value_name_utf16, value);
68 }
69 }
70
71 }
72
73 } // namespace
74
75 CrashReportingMetrics::CrashReportingMetrics(
76 const base::string16& registry_path)
77 : registry_path_(registry_path) {
78 if (g_unique_prefix[0] == 0) {
79 std::string guid = base::GenerateGUID();
80 // It seems reasonable to assume that the worst possible outcome of two
81 // separate threads trying to do the following would be to store a GUID
82 // value that is a hybrid of the two intended values. Hence we can avoid any
83 // thread-safety caveats in our public API.
84 size_t copied_size = base::strlcpy(g_unique_prefix, guid.c_str(),
85 arraysize(g_unique_prefix));
86 DCHECK_EQ(copied_size, guid.length());
87 }
88 }
89
90 void CrashReportingMetrics::RecordCrashDumpAttempt() {
91 WriteValue(registry_path_, kCrashDumpAttempt);
92 }
93
94 void CrashReportingMetrics::RecordDumpWithoutCrashAttempt() {
95 WriteValue(registry_path_, kDumpWithoutCrashAttempt);
96 }
97 void CrashReportingMetrics::RecordCrashDumpAttemptResult(bool succeeded) {
98 WriteValue(registry_path_, succeeded ? kCrashDumpSuccess : kCrashDumpFailure);
99 }
100 void CrashReportingMetrics::RecordDumpWithoutCrashAttemptResult(
101 bool succeeded) {
102 WriteValue(registry_path_,
103 succeeded ? kDumpWithoutCrashSuccess : kDumpWithoutCrashFailure);
104 }
105
106 CrashReportingMetrics::Values CrashReportingMetrics::RetrieveAndResetMetrics() {
107 Values values = {0};
108
109 // Open the registry key for iteration.
110 base::win::RegKey regkey;
111 if (regkey.Open(HKEY_CURRENT_USER, registry_path_.c_str(),
112 KEY_QUERY_VALUE | KEY_SET_VALUE) != ERROR_SUCCESS) {
113 return values;
114 }
115
116 // Track a list of values to delete. We don't modify the registry key while
117 // we're iterating over its values.
118 typedef std::vector<base::string16> StringVector;
119 StringVector to_delete;
120
121 // Iterate over the values in the key counting dumps with and without crashes.
122 // We directly walk the values instead of using RegistryValueIterator in order
123 // to read all of the values as DWORDS instead of strings.
124 base::string16 name;
125 DWORD value = 0;
126 for (int i = regkey.GetValueCount() - 1; i >= 0; --i) {
127 if (regkey.GetValueNameAt(i, &name) == ERROR_SUCCESS &&
128 regkey.ReadValueDW(name.c_str(), &value) == ERROR_SUCCESS) {
129 to_delete.push_back(name);
130 switch (value) {
131 case kCrashDumpAttempt:
132 ++values.crash_dump_attempts;
133 break;
134 case kCrashDumpSuccess:
135 ++values.successful_crash_dumps;
136 break;
137 case kCrashDumpFailure:
138 ++values.failed_crash_dumps;
139 break;
140 case kDumpWithoutCrashAttempt:
141 ++values.dump_without_crash_attempts;
142 break;
143 case kDumpWithoutCrashSuccess:
144 ++values.successful_dumps_without_crash;
145 break;
146 case kDumpWithoutCrashFailure:
147 ++values.failed_dumps_without_crash;
148 break;
149 default:
150 // Presumably a pre-existing record from the previous implementation.
151 // We will delete it.
152 break;
153 }
154 }
155 }
156
157 // Delete the registry keys we've just counted.
158 for (const auto& value_name : to_delete)
159 regkey.DeleteValue(value_name.c_str());
160
161 return values;
162 }
163
164 } // namespace browser_watcher
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698