OLD | NEW |
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/tools/crash_service/crash_service.h" | 5 #include "components/breakpad/tools/crash_service.h" |
6 | 6 |
7 #include <windows.h> | 7 #include <windows.h> |
8 | 8 |
9 #include <sddl.h> | 9 #include <sddl.h> |
10 #include <fstream> | 10 #include <fstream> |
11 #include <map> | 11 #include <map> |
12 | 12 |
13 #include "base/command_line.h" | 13 #include "base/command_line.h" |
14 #include "base/file_util.h" | 14 #include "base/file_util.h" |
15 #include "base/logging.h" | 15 #include "base/logging.h" |
16 #include "base/path_service.h" | |
17 #include "base/win/windows_version.h" | 16 #include "base/win/windows_version.h" |
18 #include "breakpad/src/client/windows/crash_generation/client_info.h" | 17 #include "breakpad/src/client/windows/crash_generation/client_info.h" |
19 #include "breakpad/src/client/windows/crash_generation/crash_generation_server.h
" | 18 #include "breakpad/src/client/windows/crash_generation/crash_generation_server.h
" |
20 #include "breakpad/src/client/windows/sender/crash_report_sender.h" | 19 #include "breakpad/src/client/windows/sender/crash_report_sender.h" |
21 #include "chrome/common/chrome_constants.h" | 20 |
22 #include "chrome/common/chrome_paths.h" | 21 namespace breakpad { |
23 | 22 |
24 namespace { | 23 namespace { |
25 | 24 |
26 const wchar_t kTestPipeName[] = L"\\\\.\\pipe\\ChromeCrashServices"; | 25 const wchar_t kTestPipeName[] = L"\\\\.\\pipe\\ChromeCrashServices"; |
27 | 26 |
28 const wchar_t kCrashReportURL[] = L"https://clients2.google.com/cr/report"; | 27 const wchar_t kCrashReportURL[] = L"https://clients2.google.com/cr/report"; |
29 const wchar_t kCheckPointFile[] = L"crash_checkpoint.txt"; | 28 const wchar_t kCheckPointFile[] = L"crash_checkpoint.txt"; |
30 | 29 |
31 typedef std::map<std::wstring, std::wstring> CrashMap; | 30 typedef std::map<std::wstring, std::wstring> CrashMap; |
32 | 31 |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 | 144 |
146 } // namespace | 145 } // namespace |
147 | 146 |
148 // Command line switches: | 147 // Command line switches: |
149 const char CrashService::kMaxReports[] = "max-reports"; | 148 const char CrashService::kMaxReports[] = "max-reports"; |
150 const char CrashService::kNoWindow[] = "no-window"; | 149 const char CrashService::kNoWindow[] = "no-window"; |
151 const char CrashService::kReporterTag[] = "reporter"; | 150 const char CrashService::kReporterTag[] = "reporter"; |
152 const char CrashService::kDumpsDir[] = "dumps-dir"; | 151 const char CrashService::kDumpsDir[] = "dumps-dir"; |
153 const char CrashService::kPipeName[] = "pipe-name"; | 152 const char CrashService::kPipeName[] = "pipe-name"; |
154 | 153 |
155 CrashService::CrashService(const std::wstring& report_dir) | 154 CrashService::CrashService() |
156 : report_path_(report_dir), | 155 : sender_(NULL), |
157 sender_(NULL), | |
158 dumper_(NULL), | 156 dumper_(NULL), |
159 requests_handled_(0), | 157 requests_handled_(0), |
160 requests_sent_(0), | 158 requests_sent_(0), |
161 clients_connected_(0), | 159 clients_connected_(0), |
162 clients_terminated_(0) { | 160 clients_terminated_(0) { |
163 chrome::RegisterPathProvider(); | |
164 } | 161 } |
165 | 162 |
166 CrashService::~CrashService() { | 163 CrashService::~CrashService() { |
167 base::AutoLock lock(sending_); | 164 base::AutoLock lock(sending_); |
168 delete dumper_; | 165 delete dumper_; |
169 delete sender_; | 166 delete sender_; |
170 } | 167 } |
171 | 168 |
172 | 169 bool CrashService::Initialize(const base::FilePath& operating_dir, |
173 bool CrashService::Initialize(const std::wstring& command_line) { | 170 const base::FilePath& dumps_path) { |
174 using google_breakpad::CrashReportSender; | 171 using google_breakpad::CrashReportSender; |
175 using google_breakpad::CrashGenerationServer; | 172 using google_breakpad::CrashGenerationServer; |
176 | 173 |
177 std::wstring pipe_name = kTestPipeName; | 174 std::wstring pipe_name = kTestPipeName; |
178 int max_reports = -1; | 175 int max_reports = -1; |
179 | 176 |
180 // The checkpoint file allows CrashReportSender to enforce the the maximum | 177 // The checkpoint file allows CrashReportSender to enforce the the maximum |
181 // reports per day quota. Does not seem to serve any other purpose. | 178 // reports per day quota. Does not seem to serve any other purpose. |
182 base::FilePath checkpoint_path = report_path_.Append(kCheckPointFile); | 179 base::FilePath checkpoint_path = operating_dir.Append(kCheckPointFile); |
183 | 180 |
184 // The dumps path is typically : '<user profile>\Local settings\ | 181 CommandLine& cmd_line = *CommandLine::ForCurrentProcess(); |
185 // Application data\Goggle\Chrome\Crash Reports' and the report path is | |
186 // Application data\Google\Chrome\Reported Crashes.txt | |
187 base::FilePath user_data_dir; | |
188 if (!PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)) { | |
189 LOG(ERROR) << "could not get DIR_USER_DATA"; | |
190 return false; | |
191 } | |
192 report_path_ = user_data_dir.Append(chrome::kCrashReportLog); | |
193 | 182 |
194 CommandLine cmd_line = CommandLine::FromString(command_line); | 183 base::FilePath dumps_path_to_use = dumps_path; |
195 | 184 |
196 base::FilePath dumps_path; | |
197 if (cmd_line.HasSwitch(kDumpsDir)) { | 185 if (cmd_line.HasSwitch(kDumpsDir)) { |
198 dumps_path = base::FilePath(cmd_line.GetSwitchValueNative(kDumpsDir)); | 186 dumps_path_to_use = |
199 } else { | 187 base::FilePath(cmd_line.GetSwitchValueNative(kDumpsDir)); |
200 if (!PathService::Get(chrome::DIR_CRASH_DUMPS, &dumps_path)) { | |
201 LOG(ERROR) << "could not get DIR_CRASH_DUMPS"; | |
202 return false; | |
203 } | |
204 } | 188 } |
205 | 189 |
206 // We can override the send reports quota with a command line switch. | 190 // We can override the send reports quota with a command line switch. |
207 if (cmd_line.HasSwitch(kMaxReports)) | 191 if (cmd_line.HasSwitch(kMaxReports)) |
208 max_reports = _wtoi(cmd_line.GetSwitchValueNative(kMaxReports).c_str()); | 192 max_reports = _wtoi(cmd_line.GetSwitchValueNative(kMaxReports).c_str()); |
209 | 193 |
210 // Allow the global pipe name to be overridden for better testability. | 194 // Allow the global pipe name to be overridden for better testability. |
211 if (cmd_line.HasSwitch(kPipeName)) | 195 if (cmd_line.HasSwitch(kPipeName)) |
212 pipe_name = cmd_line.GetSwitchValueNative(kPipeName); | 196 pipe_name = cmd_line.GetSwitchValueNative(kPipeName); |
213 | 197 |
(...skipping 22 matching lines...) Expand all Loading... |
236 | 220 |
237 security_attributes_actual = &security_attributes; | 221 security_attributes_actual = &security_attributes; |
238 } | 222 } |
239 | 223 |
240 // Create the OOP crash generator object. | 224 // Create the OOP crash generator object. |
241 dumper_ = new CrashGenerationServer(pipe_name, security_attributes_actual, | 225 dumper_ = new CrashGenerationServer(pipe_name, security_attributes_actual, |
242 &CrashService::OnClientConnected, this, | 226 &CrashService::OnClientConnected, this, |
243 &CrashService::OnClientDumpRequest, this, | 227 &CrashService::OnClientDumpRequest, this, |
244 &CrashService::OnClientExited, this, | 228 &CrashService::OnClientExited, this, |
245 NULL, NULL, | 229 NULL, NULL, |
246 true, &dumps_path.value()); | 230 true, &dumps_path_to_use.value()); |
247 | 231 |
248 if (!dumper_) { | 232 if (!dumper_) { |
249 LOG(ERROR) << "could not create dumper"; | 233 LOG(ERROR) << "could not create dumper"; |
250 if (security_attributes.lpSecurityDescriptor) | 234 if (security_attributes.lpSecurityDescriptor) |
251 LocalFree(security_attributes.lpSecurityDescriptor); | 235 LocalFree(security_attributes.lpSecurityDescriptor); |
252 return false; | 236 return false; |
253 } | 237 } |
254 | 238 |
255 if (!CreateTopWindow(::GetModuleHandleW(NULL), | 239 if (!CreateTopWindow(::GetModuleHandleW(NULL), |
256 !cmd_line.HasSwitch(kNoWindow))) { | 240 !cmd_line.HasSwitch(kNoWindow))) { |
257 LOG(ERROR) << "could not create window"; | 241 LOG(ERROR) << "could not create window"; |
258 if (security_attributes.lpSecurityDescriptor) | 242 if (security_attributes.lpSecurityDescriptor) |
259 LocalFree(security_attributes.lpSecurityDescriptor); | 243 LocalFree(security_attributes.lpSecurityDescriptor); |
260 return false; | 244 return false; |
261 } | 245 } |
262 | 246 |
263 reporter_tag_ = L"crash svc"; | 247 reporter_tag_ = L"crash svc"; |
264 if (cmd_line.HasSwitch(kReporterTag)) | 248 if (cmd_line.HasSwitch(kReporterTag)) |
265 reporter_tag_ = cmd_line.GetSwitchValueNative(kReporterTag); | 249 reporter_tag_ = cmd_line.GetSwitchValueNative(kReporterTag); |
266 | 250 |
267 // Log basic information. | 251 // Log basic information. |
268 VLOG(1) << "pipe name is " << pipe_name | 252 VLOG(1) << "pipe name is " << pipe_name |
269 << "\ndumps at " << dumps_path.value() | 253 << "\ndumps at " << dumps_path_to_use.value(); |
270 << "\nreports at " << report_path_.value(); | |
271 | 254 |
272 if (sender_) { | 255 if (sender_) { |
273 VLOG(1) << "checkpoint is " << checkpoint_path.value() | 256 VLOG(1) << "checkpoint is " << checkpoint_path.value() |
274 << "\nserver is " << kCrashReportURL | 257 << "\nserver is " << kCrashReportURL |
275 << "\nmaximum " << sender_->max_reports_per_day() << " reports/day" | 258 << "\nmaximum " << sender_->max_reports_per_day() << " reports/day" |
276 << "\nreporter is " << reporter_tag_; | 259 << "\nreporter is " << reporter_tag_; |
277 } | 260 } |
278 // Start servicing clients. | 261 // Start servicing clients. |
279 if (!dumper_->Start()) { | 262 if (!dumper_->Start()) { |
280 LOG(ERROR) << "could not start dumper"; | 263 LOG(ERROR) << "could not start dumper"; |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
494 SDDL_REVISION, | 477 SDDL_REVISION, |
495 &sec_desc, NULL)) { | 478 &sec_desc, NULL)) { |
496 if (::GetSecurityDescriptorSacl(sec_desc, &sacl_present, &sacl, | 479 if (::GetSecurityDescriptorSacl(sec_desc, &sacl_present, &sacl, |
497 &sacl_defaulted)) { | 480 &sacl_defaulted)) { |
498 return sec_desc; | 481 return sec_desc; |
499 } | 482 } |
500 } | 483 } |
501 | 484 |
502 return NULL; | 485 return NULL; |
503 } | 486 } |
| 487 |
| 488 } // namespace breakpad |
OLD | NEW |