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

Side by Side Diff: remoting/base/breakpad_win.cc

Issue 10535082: /C++ readability/ - Make Chromoting Host report crashes to Breakpad (Windows only). The user must e… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixing a bad merge. Created 8 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « remoting/base/breakpad_mac.mm ('k') | remoting/base/breakpad_win_unittest.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 // This module contains the necessary code to register the Breakpad exception 5 // This module contains the necessary code to register the Breakpad exception
6 // handler. This implementation is based on Chrome/Crome Frame crash reporitng 6 // handler. This implementation is based on Chrome/Chrome Frame crash reporting
7 // code. See: 7 // code. See:
8 // - src/chrome/app/breakpad_win.cc 8 // - src/chrome/app/breakpad_win.cc
9 // - src/chrome_frame/crash_server_init.cc 9 // - src/chrome_frame/crash_server_init.cc
10 // - src/chrome/installer/setup/setup_main.cc 10 // - src/chrome/installer/setup/setup_main.cc
11 // - src/chrome_frame/crash_reporting/crash_report.cc 11 // - src/chrome_frame/crash_reporting/crash_report.cc
12 12
13 #include "remoting/base/breakpad.h" 13 #include "remoting/base/breakpad.h"
14 14
15 #include <windows.h> 15 #include <windows.h>
16 #include <string>
16 17
17 #include "base/atomicops.h" 18 #include "base/atomicops.h"
18 #include "base/logging.h" 19 #include "base/logging.h"
19 #include "base/file_version_info.h" 20 #include "base/file_version_info.h"
20 #include "base/lazy_instance.h" 21 #include "base/lazy_instance.h"
21 #include "base/memory/scoped_ptr.h" 22 #include "base/memory/scoped_ptr.h"
22 #include "base/process_util.h" 23 #include "base/process_util.h"
23 #include "base/string16.h" 24 #include "base/utf_string_conversions.h"
24 #include "base/win/wrapped_window_proc.h" 25 #include "base/win/wrapped_window_proc.h"
25 #include "breakpad/src/client/windows/handler/exception_handler.h" 26 #include "breakpad/src/client/windows/handler/exception_handler.h"
26 27
27 namespace remoting { 28 namespace remoting {
28 void InitializeCrashReportingForTest(const wchar_t*); 29 void InitializeCrashReportingForTest(const wchar_t* pipe_name);
29 } // namespace remoting 30 } // namespace remoting
30 31
31 namespace { 32 namespace {
32 33
33 const wchar_t kBreakpadProductName[] = L"Chromoting"; 34 const wchar_t kBreakpadProductName[] = L"Chromoting";
34 const wchar_t kBreakpadVersionEntry[] = L"ver"; 35 const wchar_t kBreakpadVersionEntry[] = L"ver";
35 const wchar_t kBreakpadVersionDefault[] = L"0.1.0.0"; 36 const wchar_t kBreakpadVersionDefault[] = L"0.1.0.0";
36 const wchar_t kBreakpadProdEntry[] = L"prod"; 37 const wchar_t kBreakpadProdEntry[] = L"prod";
37 const wchar_t kBreakpadPlatformEntry[] = L"plat"; 38 const wchar_t kBreakpadPlatformEntry[] = L"plat";
38 const wchar_t kBreakpadPlatformWin32[] = L"Win32"; 39 const wchar_t kBreakpadPlatformWin32[] = L"Win32";
(...skipping 12 matching lines...) Expand all
51 #endif 52 #endif
52 53
53 using base::subtle::AtomicWord; 54 using base::subtle::AtomicWord;
54 using base::subtle::NoBarrier_CompareAndSwap; 55 using base::subtle::NoBarrier_CompareAndSwap;
55 56
56 class BreakpadWin { 57 class BreakpadWin {
57 public: 58 public:
58 BreakpadWin(); 59 BreakpadWin();
59 ~BreakpadWin(); 60 ~BreakpadWin();
60 61
61 static BreakpadWin& GetInstance(); 62 static BreakpadWin* GetInstance();
62 63
63 private: 64 private:
64 // Returns the Custom information to be used for crash reporting. 65 // Returns the Custom information to be used for crash reporting.
65 google_breakpad::CustomClientInfo* GetCustomInfo(); 66 google_breakpad::CustomClientInfo* GetCustomInfo();
66 67
67 // Checks whether crash dump collection is allowed by the user. 68 // Checks whether crash dump collection is allowed by the user.
68 bool IsCrashReportingEnabled(); 69 bool IsCrashReportingEnabled();
69 70
70 // This callback is executed when the process has crashed and *before* 71 // This callback is executed when the process has crashed and *before*
71 // the crash dump is created. To prevent duplicate crash reports we 72 // the crash dump is created. To prevent duplicate crash reports we
72 // make every thread calling this method, except the very first one, 73 // make every thread calling this method, except the very first one,
73 // go to sleep. 74 // go to sleep.
74 static bool OnExceptionCallback(void*, EXCEPTION_POINTERS*, 75 static bool OnExceptionCallback(void* context,
75 MDRawAssertionInfo*); 76 EXCEPTION_POINTERS* exinfo,
77 MDRawAssertionInfo* assertion);
76 78
77 // Crashes the process after generating a dump for the provided exception. 79 // Crashes the process after generating a dump for the provided exception.
78 // Note that the crash reporter should be initialized before calling this 80 // Note that the crash reporter should be initialized before calling this
79 // function for it to do anything. 81 // function for it to do anything.
80 static int OnWindowProcedureException(EXCEPTION_POINTERS* info); 82 static int OnWindowProcedureException(EXCEPTION_POINTERS* exinfo);
81 83
82 // Breakpad's exception handler. 84 // Breakpad's exception handler.
83 scoped_ptr<google_breakpad::ExceptionHandler> breakpad_; 85 scoped_ptr<google_breakpad::ExceptionHandler> breakpad_;
84 86
85 // This flag is used to indicate that an exception is already being handled. 87 // This flag is used to indicate that an exception is already being handled.
86 volatile AtomicWord handling_exception_; 88 volatile AtomicWord handling_exception_;
87 89
88 // The testing hook below allows overriding the crash server pipe name. 90 // The testing hook below allows overriding the crash server pipe name.
89 static const wchar_t* pipe_name_; 91 static const wchar_t* pipe_name_;
90 92
91 friend void ::remoting::InitializeCrashReportingForTest(const wchar_t*); 93 friend void ::remoting::InitializeCrashReportingForTest(const wchar_t*);
92 94
93 DISALLOW_COPY_AND_ASSIGN(BreakpadWin); 95 DISALLOW_COPY_AND_ASSIGN(BreakpadWin);
94 }; 96 };
95 97
96 // |LazyInstance| is used to guarantee that the exception handler will be 98 // |LazyInstance| is used to guarantee that the exception handler will be
97 // initialized exactly once. 99 // initialized exactly once.
98 // N.B. LazyInstance does not allow this to be a static member of the class. 100 // N.B. LazyInstance does not allow this to be a static member of the class.
99 static base::LazyInstance<BreakpadWin>::Leaky g_instance = 101 static base::LazyInstance<BreakpadWin>::Leaky g_instance =
100 LAZY_INSTANCE_INITIALIZER; 102 LAZY_INSTANCE_INITIALIZER;
101 103
102 const wchar_t* BreakpadWin::pipe_name_ = kGoogleUpdatePipeName; 104 const wchar_t* BreakpadWin::pipe_name_ = kGoogleUpdatePipeName;
103 105
104 BreakpadWin::BreakpadWin() : handling_exception_(0) { 106 BreakpadWin::BreakpadWin() : handling_exception_(0) {
105 // Disable the message box for assertions. 107 // Disable the message box for assertions.
106 _CrtSetReportMode(_CRT_ASSERT, 0); 108 _CrtSetReportMode(_CRT_ASSERT, 0);
107 109
108 // Get the alternate dump directory. We use the temp path. 110 // Get the alternate dump directory. We use the temp path.
111 // N.B. We don't use base::GetTempDir() here to avoid running more code then
112 // necessary before crashes can be properly reported.
109 wchar_t temp_directory[MAX_PATH + 1] = { 0 }; 113 wchar_t temp_directory[MAX_PATH + 1] = { 0 };
110 DWORD length = ::GetTempPath(MAX_PATH, temp_directory); 114 DWORD length = GetTempPath(MAX_PATH, temp_directory);
111 if (length == 0) 115 if (length == 0)
112 return; 116 return;
113 117
114 // Minidump with stacks, PEB, TEB, unloaded module list and memory referenced 118 // Minidump with stacks, PEB, TEB, unloaded module list and memory referenced
115 // from stack. 119 // from stack.
116 MINIDUMP_TYPE dump_type = static_cast<MINIDUMP_TYPE>( 120 MINIDUMP_TYPE dump_type = static_cast<MINIDUMP_TYPE>(
117 MiniDumpWithProcessThreadData | 121 MiniDumpWithProcessThreadData |
118 MiniDumpWithUnloadedModules | 122 MiniDumpWithUnloadedModules |
119 MiniDumpWithIndirectlyReferencedMemory); 123 MiniDumpWithIndirectlyReferencedMemory);
120 breakpad_.reset( 124 breakpad_.reset(
(...skipping 13 matching lines...) Expand all
134 CHECK(!exception_filter); 138 CHECK(!exception_filter);
135 } 139 }
136 140
137 BreakpadWin::~BreakpadWin() { 141 BreakpadWin::~BreakpadWin() {
138 // This object should be leaked so that crashes occurred during the process 142 // This object should be leaked so that crashes occurred during the process
139 // shutdown will be caught. 143 // shutdown will be caught.
140 NOTREACHED(); 144 NOTREACHED();
141 } 145 }
142 146
143 // static 147 // static
144 BreakpadWin& BreakpadWin::GetInstance() { 148 BreakpadWin* BreakpadWin::GetInstance() {
145 return g_instance.Get(); 149 return &g_instance.Get();
146 } 150 }
147 151
148 // Returns the Custom information to be used for crash reporting. 152 // Returns the Custom information to be used for crash reporting.
149 google_breakpad::CustomClientInfo* BreakpadWin::GetCustomInfo() { 153 google_breakpad::CustomClientInfo* BreakpadWin::GetCustomInfo() {
150 HMODULE binary = base::GetModuleFromAddress( 154 HMODULE binary = base::GetModuleFromAddress(
151 reinterpret_cast<void*>(&remoting::InitializeCrashReporting)); 155 reinterpret_cast<void*>(&remoting::InitializeCrashReporting));
152 scoped_ptr<FileVersionInfo> version_info( 156 scoped_ptr<FileVersionInfo> version_info(
153 FileVersionInfo::CreateFileVersionInfoForModule(binary)); 157 FileVersionInfo::CreateFileVersionInfoForModule(binary));
154 158
155 string16 version; 159 std::wstring version;
156 if (version_info.get()) 160 if (version_info.get())
157 version = version_info->product_version(); 161 version = UTF16ToWide(version_info->product_version());
158 if (version.empty()) 162 if (version.empty())
159 version = kBreakpadVersionDefault; 163 version = kBreakpadVersionDefault;
160 164
161 static google_breakpad::CustomInfoEntry ver_entry( 165 static google_breakpad::CustomInfoEntry ver_entry(
162 kBreakpadVersionEntry, version.c_str()); 166 kBreakpadVersionEntry, version.c_str());
163 static google_breakpad::CustomInfoEntry prod_entry( 167 static google_breakpad::CustomInfoEntry prod_entry(
164 kBreakpadProdEntry, kBreakpadProductName); 168 kBreakpadProdEntry, kBreakpadProductName);
165 static google_breakpad::CustomInfoEntry plat_entry( 169 static google_breakpad::CustomInfoEntry plat_entry(
166 kBreakpadPlatformEntry, kBreakpadPlatformWin32); 170 kBreakpadPlatformEntry, kBreakpadPlatformWin32);
167 static google_breakpad::CustomInfoEntry entries[] = { 171 static google_breakpad::CustomInfoEntry entries[] = {
168 ver_entry, prod_entry, plat_entry }; 172 ver_entry, prod_entry, plat_entry };
169 static google_breakpad::CustomClientInfo custom_info = { 173 static google_breakpad::CustomClientInfo custom_info = {
170 entries, arraysize(entries) }; 174 entries, arraysize(entries) };
171 return &custom_info; 175 return &custom_info;
172 } 176 }
173 177
174 // static 178 // static
175 bool BreakpadWin::OnExceptionCallback( 179 bool BreakpadWin::OnExceptionCallback(void* /* context */,
176 void*, EXCEPTION_POINTERS*, MDRawAssertionInfo*) { 180 EXCEPTION_POINTERS* /* exinfo */,
177 BreakpadWin& self = BreakpadWin::GetInstance(); 181 MDRawAssertionInfo* /* assertion */) {
178 if (NoBarrier_CompareAndSwap(&self.handling_exception_, 0, 1) != 0) { 182 BreakpadWin* self = BreakpadWin::GetInstance();
183 if (NoBarrier_CompareAndSwap(&self->handling_exception_, 0, 1) != 0) {
179 // Capture every thread except the first one in the sleep. We don't 184 // Capture every thread except the first one in the sleep. We don't
180 // want multiple threads to concurrently report exceptions. 185 // want multiple threads to concurrently report exceptions.
181 ::Sleep(INFINITE); 186 ::Sleep(INFINITE);
182 } 187 }
183 return true; 188 return true;
184 } 189 }
185 190
186 // static 191 // static
187 int BreakpadWin::OnWindowProcedureException(EXCEPTION_POINTERS* info) { 192 int BreakpadWin::OnWindowProcedureException(EXCEPTION_POINTERS* exinfo) {
188 BreakpadWin& self = BreakpadWin::GetInstance(); 193 BreakpadWin* self = BreakpadWin::GetInstance();
189 if (self.breakpad_.get() != NULL) { 194 if (self->breakpad_.get() != NULL) {
190 self.breakpad_->WriteMinidumpForException(info); 195 self->breakpad_->WriteMinidumpForException(exinfo);
191 ::TerminateProcess(::GetCurrentProcess(), 196 TerminateProcess(GetCurrentProcess(),
192 info->ExceptionRecord->ExceptionCode); 197 exinfo->ExceptionRecord->ExceptionCode);
193 } 198 }
194 return EXCEPTION_CONTINUE_SEARCH; 199 return EXCEPTION_CONTINUE_SEARCH;
195 } 200 }
196 201
197 } // namespace 202 } // namespace
198 203
199 namespace remoting { 204 namespace remoting {
200 205
201 void InitializeCrashReporting() { 206 void InitializeCrashReporting() {
202 // Touch the object to make sure it is initialized. 207 // Touch the object to make sure it is initialized.
203 BreakpadWin::GetInstance(); 208 BreakpadWin::GetInstance();
204 } 209 }
205 210
206 void InitializeCrashReportingForTest(const wchar_t* pipe_name) { 211 void InitializeCrashReportingForTest(const wchar_t* pipe_name) {
207 BreakpadWin::pipe_name_ = pipe_name; 212 BreakpadWin::pipe_name_ = pipe_name;
208 213 InitializeCrashReporting();
209 // Touch the object to make sure it is initialized.
210 BreakpadWin::GetInstance();
211 } 214 }
212 215
213 } // namespace remoting 216 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/base/breakpad_mac.mm ('k') | remoting/base/breakpad_win_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698