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

Side by Side Diff: chrome/app/breakpad_win.cc

Issue 23453032: Chrome.BrowserCrashDumpAttempts needs to account for multiple dumps from the same browser process. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 7 years, 3 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
« no previous file with comments | « no previous file | chrome/browser/metrics/metrics_service.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/app/breakpad_win.h" 5 #include "chrome/app/breakpad_win.h"
6 6
7 #include <shellapi.h> 7 #include <shellapi.h>
8 #include <tchar.h> 8 #include <tchar.h>
9 #include <userenv.h> 9 #include <userenv.h>
10 #include <windows.h> 10 #include <windows.h>
11 #include <winnt.h> 11 #include <winnt.h>
12 12
13 #include <algorithm> 13 #include <algorithm>
14 #include <vector> 14 #include <vector>
15 15
16 #include "base/atomicops.h"
16 #include "base/basictypes.h" 17 #include "base/basictypes.h"
17 #include "base/base_switches.h" 18 #include "base/base_switches.h"
18 #include "base/command_line.h" 19 #include "base/command_line.h"
19 #include "base/debug/crash_logging.h" 20 #include "base/debug/crash_logging.h"
20 #include "base/environment.h" 21 #include "base/environment.h"
21 #include "base/memory/scoped_ptr.h" 22 #include "base/memory/scoped_ptr.h"
22 #include "base/strings/string16.h" 23 #include "base/strings/string16.h"
23 #include "base/strings/string_split.h" 24 #include "base/strings/string_split.h"
24 #include "base/strings/string_util.h" 25 #include "base/strings/string_util.h"
25 #include "base/strings/stringprintf.h" 26 #include "base/strings/stringprintf.h"
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
120 121
121 // Maximum length for plugin path to include in plugin crash reports. 122 // Maximum length for plugin path to include in plugin crash reports.
122 const size_t kMaxPluginPathLength = 256; 123 const size_t kMaxPluginPathLength = 256;
123 124
124 // These values track the browser crash dump registry key and pre-computed 125 // These values track the browser crash dump registry key and pre-computed
125 // registry value name, which we use as a "smoke-signal" for counting dumps. 126 // registry value name, which we use as a "smoke-signal" for counting dumps.
126 static HKEY g_browser_crash_dump_regkey = NULL; 127 static HKEY g_browser_crash_dump_regkey = NULL;
127 static const wchar_t kBrowserCrashDumpValueFormatStr[] = L"%08x-%08x"; 128 static const wchar_t kBrowserCrashDumpValueFormatStr[] = L"%08x-%08x";
128 static const int kBrowserCrashDumpValueLength = 17; 129 static const int kBrowserCrashDumpValueLength = 17;
129 static wchar_t g_browser_crash_dump_value[kBrowserCrashDumpValueLength+1] = {0}; 130 static wchar_t g_browser_crash_dump_value[kBrowserCrashDumpValueLength+1] = {0};
131 static base::subtle::Atomic32 g_browser_crash_dump_count = 0;
cpu_(ooo_6.6-7.5) 2013/09/04 23:29:45 aka int32 btw
Roger McFarlane (Chromium) 2013/09/05 13:57:53 Yes, I know. But this communicates the intended us
130 132
131 void InitBrowserCrashDumpsRegKey() { 133 void InitBrowserCrashDumpsRegKey() {
132 DCHECK(g_browser_crash_dump_regkey == NULL); 134 DCHECK(g_browser_crash_dump_regkey == NULL);
133 135
134 base::string16 key_str(chrome::kBrowserCrashDumpAttemptsRegistryPath); 136 base::string16 key_str(chrome::kBrowserCrashDumpAttemptsRegistryPath);
135 key_str += L"\\"; 137 key_str += L"\\";
136 key_str += UTF8ToWide(chrome::kChromeVersion); 138 key_str += UTF8ToWide(chrome::kChromeVersion);
137 139
138 base::win::RegKey regkey; 140 base::win::RegKey regkey;
139 if (regkey.Create(HKEY_CURRENT_USER, 141 if (regkey.Create(HKEY_CURRENT_USER,
grt (UTC plus 2) 2013/09/05 21:09:13 when are these keys deleted?
grt (UTC plus 2) 2013/09/06 02:21:35 one possibility: the installer could delete the ke
Roger McFarlane (Chromium) 2013/09/06 02:59:20 Indeed. I got another ping from a concerned dev s
Roger McFarlane (Chromium) 2013/09/06 02:59:20 That sounds like the makings of a plan.
140 key_str.c_str(), 142 key_str.c_str(),
141 KEY_ALL_ACCESS) != ERROR_SUCCESS) { 143 KEY_ALL_ACCESS) != ERROR_SUCCESS) {
142 return; 144 return;
143 } 145 }
144 146
147 // Hold the registry key in a global for update on crash dump.
145 g_browser_crash_dump_regkey = regkey.Take(); 148 g_browser_crash_dump_regkey = regkey.Take();
146 149
147 // We use the current process id and the curren tick count as a (hopefully) 150 // We use the current process id and the curren tick count as a (hopefully)
148 // unique combination for the crash dump value. There's a small chance that 151 // unique combination for the crash dump value. There's a small chance that
149 // across a reboot we might have a crash dump signal written, and the next 152 // across a reboot we might have a crash dump signal written, and the next
150 // browser process might have the same process id and tick count, but crash 153 // browser process might have the same process id and tick count, but crash
151 // before consuming the signal (overwriting the signal with an identical one). 154 // before consuming the signal (overwriting the signal with an identical one).
152 // For now, we're willing to live with that risk. 155 // For now, we're willing to live with that risk.
153 int length = swprintf(g_browser_crash_dump_value, 156 int length = swprintf(g_browser_crash_dump_value,
154 arraysize(g_browser_crash_dump_value), 157 arraysize(g_browser_crash_dump_value),
155 kBrowserCrashDumpValueFormatStr, 158 kBrowserCrashDumpValueFormatStr,
156 ::GetCurrentProcessId(), 159 ::GetCurrentProcessId(),
157 ::GetTickCount()); 160 ::GetTickCount());
158 DCHECK_EQ(kBrowserCrashDumpValueLength, length); 161 DCHECK_EQ(kBrowserCrashDumpValueLength, length);
159 } 162 }
160 163
161 void SendSmokeSignalForCrashDump() { 164 void SendSmokeSignalForCrashDump() {
162 if (g_browser_crash_dump_regkey != NULL) { 165 // If we're not a browser (or the registry is unavailable to us for some
163 base::win::RegKey regkey(g_browser_crash_dump_regkey); 166 // reason) then there's nothing to do.
164 regkey.WriteValue(g_browser_crash_dump_value, 1); 167 if (g_browser_crash_dump_regkey == NULL)
165 g_browser_crash_dump_regkey = NULL; 168 return;
166 } 169
170 // Increment the number of crash dumps and persist it to the registry.
171 // Note that there is a race condition here: the final count could be off by
172 // one if two dumps are triggered at the same moment and the registry writes
173 // happen to be committed in the reverse order of the atomic increments.
174 // We'll live with this, as we don't want to attempt any "real" work while
175 // we may be in a crashing state.
176 base::win::RegKey regkey(g_browser_crash_dump_regkey);
177 regkey.WriteValue(
178 g_browser_crash_dump_value,
179 base::subtle::NoBarrier_AtomicIncrement(&g_browser_crash_dump_count, 1));
180
181 // Don't let regkey auto-close the key. More crash dumps may follow.
182 ignore_result(regkey.Take());
167 } 183 }
168 184
169 // Dumps the current process memory. 185 // Dumps the current process memory.
170 extern "C" void __declspec(dllexport) __cdecl DumpProcess() { 186 extern "C" void __declspec(dllexport) __cdecl DumpProcess() {
171 if (g_breakpad) { 187 if (g_breakpad) {
172 SendSmokeSignalForCrashDump(); 188 SendSmokeSignalForCrashDump();
173 g_breakpad->WriteMinidump(); 189 g_breakpad->WriteMinidump();
174 } 190 }
175 } 191 }
176 192
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after
569 // facilities such as the i18n helpers. 585 // facilities such as the i18n helpers.
570 bool DumpDoneCallback(const wchar_t*, const wchar_t*, void*, 586 bool DumpDoneCallback(const wchar_t*, const wchar_t*, void*,
571 EXCEPTION_POINTERS* ex_info, 587 EXCEPTION_POINTERS* ex_info,
572 MDRawAssertionInfo*, bool) { 588 MDRawAssertionInfo*, bool) {
573 // Check if the exception is one of the kind which would not be solved 589 // Check if the exception is one of the kind which would not be solved
574 // by simply restarting chrome. In this case we show a message box with 590 // by simply restarting chrome. In this case we show a message box with
575 // and exit silently. Remember that chrome is in a crashed state so we 591 // and exit silently. Remember that chrome is in a crashed state so we
576 // can't show our own UI from this process. 592 // can't show our own UI from this process.
577 if (HardErrorHandler(ex_info)) 593 if (HardErrorHandler(ex_info))
578 return true; 594 return true;
579 595
cpu_(ooo_6.6-7.5) 2013/09/04 23:32:20 we don't have the smoke signal here ...
Roger McFarlane (Chromium) 2013/09/05 13:57:53 We send the smoke signal before generating the dum
Roger McFarlane (Chromium) 2013/09/06 02:59:20 I moved the call to the filter callbacks (which ar
580 if (!breakpad::GetBreakpadClient()->AboutToRestart()) 596 if (!breakpad::GetBreakpadClient()->AboutToRestart())
581 return true; 597 return true;
582 598
583 // Now we just start chrome browser with the same command line. 599 // Now we just start chrome browser with the same command line.
584 STARTUPINFOW si = {sizeof(si)}; 600 STARTUPINFOW si = {sizeof(si)};
585 PROCESS_INFORMATION pi; 601 PROCESS_INFORMATION pi;
586 if (::CreateProcessW(NULL, ::GetCommandLineW(), NULL, NULL, FALSE, 602 if (::CreateProcessW(NULL, ::GetCommandLineW(), NULL, NULL, FALSE,
587 CREATE_UNICODE_ENVIRONMENT, NULL, NULL, &si, &pi)) { 603 CREATE_UNICODE_ENVIRONMENT, NULL, NULL, &si, &pi)) {
588 ::CloseHandle(pi.hProcess); 604 ::CloseHandle(pi.hProcess);
589 ::CloseHandle(pi.hThread); 605 ::CloseHandle(pi.hThread);
(...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after
1056 previous_filter = SetUnhandledExceptionFilter(filter); 1072 previous_filter = SetUnhandledExceptionFilter(filter);
1057 } 1073 }
1058 1074
1059 void StringVectorToCStringVector(const std::vector<std::wstring>& wstrings, 1075 void StringVectorToCStringVector(const std::vector<std::wstring>& wstrings,
1060 std::vector<const wchar_t*>* cstrings) { 1076 std::vector<const wchar_t*>* cstrings) {
1061 cstrings->clear(); 1077 cstrings->clear();
1062 cstrings->reserve(wstrings.size()); 1078 cstrings->reserve(wstrings.size());
1063 for (size_t i = 0; i < wstrings.size(); ++i) 1079 for (size_t i = 0; i < wstrings.size(); ++i)
1064 cstrings->push_back(wstrings[i].c_str()); 1080 cstrings->push_back(wstrings[i].c_str());
1065 } 1081 }
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/metrics/metrics_service.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698