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 "chrome/tools/crash_service/crash_service.h" |
6 | 6 |
7 #include <windows.h> | 7 #include <windows.h> |
8 | 8 |
9 #include <fstream> | 9 #include <fstream> |
10 #include <map> | 10 #include <map> |
11 #include <sddl.h> | 11 #include <sddl.h> |
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" | 16 #include "base/path_service.h" |
| 17 #include "base/string_number_conversions.h" |
17 #include "base/win/windows_version.h" | 18 #include "base/win/windows_version.h" |
18 #include "breakpad/src/client/windows/crash_generation/client_info.h" | 19 #include "breakpad/src/client/windows/crash_generation/client_info.h" |
19 #include "breakpad/src/client/windows/crash_generation/crash_generation_server.h
" | 20 #include "breakpad/src/client/windows/crash_generation/crash_generation_server.h
" |
20 #include "breakpad/src/client/windows/sender/crash_report_sender.h" | 21 #include "breakpad/src/client/windows/sender/crash_report_sender.h" |
21 #include "chrome/common/chrome_constants.h" | 22 #include "chrome/common/chrome_constants.h" |
22 #include "chrome/common/chrome_paths.h" | 23 #include "chrome/common/chrome_paths.h" |
23 | 24 |
24 namespace { | 25 namespace { |
25 | 26 |
26 const wchar_t kTestPipeName[] = L"\\\\.\\pipe\\ChromeCrashServices"; | 27 const wchar_t kTestPipeName[] = L"\\\\.\\pipe\\ChromeCrashServices"; |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
139 | 140 |
140 DumpJobInfo(DWORD process_id, CrashService* service, | 141 DumpJobInfo(DWORD process_id, CrashService* service, |
141 const CrashMap& crash_map, const std::wstring& path) | 142 const CrashMap& crash_map, const std::wstring& path) |
142 : pid(process_id), self(service), map(crash_map), dump_path(path) { | 143 : pid(process_id), self(service), map(crash_map), dump_path(path) { |
143 } | 144 } |
144 }; | 145 }; |
145 | 146 |
146 } // namespace | 147 } // namespace |
147 | 148 |
148 // Command line switches: | 149 // Command line switches: |
149 const char CrashService::kMaxReports[] = "max-reports"; | 150 const char CrashService::kMaxReports[] = "max-reports"; |
150 const char CrashService::kNoWindow[] = "no-window"; | 151 const char CrashService::kNoWindow[] = "no-window"; |
151 const char CrashService::kReporterTag[] = "reporter"; | 152 const char CrashService::kReporterTag[] = "reporter"; |
152 const char CrashService::kDumpsDir[] = "dumps-dir"; | 153 const char CrashService::kDumpsDir[] = "dumps-dir"; |
153 const char CrashService::kPipeName[] = "pipe-name"; | 154 const char CrashService::kPipeName[] = "pipe-name"; |
| 155 const char CrashService::kArchiveDumpsByPid[] = "archive-dumps-by-pid"; |
| 156 |
| 157 bool CrashService::archive_dumps_by_pid_ = false; |
154 | 158 |
155 CrashService::CrashService(const std::wstring& report_dir) | 159 CrashService::CrashService(const std::wstring& report_dir) |
156 : report_path_(report_dir), | 160 : report_path_(report_dir), |
157 sender_(NULL), | 161 sender_(NULL), |
158 dumper_(NULL), | 162 dumper_(NULL), |
159 requests_handled_(0), | 163 requests_handled_(0), |
160 requests_sent_(0), | 164 requests_sent_(0), |
161 clients_connected_(0), | 165 clients_connected_(0), |
162 clients_terminated_(0) { | 166 clients_terminated_(0) { |
163 chrome::RegisterPathProvider(); | 167 chrome::RegisterPathProvider(); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
196 FilePath dumps_path; | 200 FilePath dumps_path; |
197 if (cmd_line.HasSwitch(kDumpsDir)) { | 201 if (cmd_line.HasSwitch(kDumpsDir)) { |
198 dumps_path = FilePath(cmd_line.GetSwitchValueNative(kDumpsDir)); | 202 dumps_path = FilePath(cmd_line.GetSwitchValueNative(kDumpsDir)); |
199 } else { | 203 } else { |
200 if (!PathService::Get(chrome::DIR_CRASH_DUMPS, &dumps_path)) { | 204 if (!PathService::Get(chrome::DIR_CRASH_DUMPS, &dumps_path)) { |
201 LOG(ERROR) << "could not get DIR_CRASH_DUMPS"; | 205 LOG(ERROR) << "could not get DIR_CRASH_DUMPS"; |
202 return false; | 206 return false; |
203 } | 207 } |
204 } | 208 } |
205 | 209 |
| 210 if (cmd_line.HasSwitch(kArchiveDumpsByPid)) |
| 211 archive_dumps_by_pid_ = true; |
| 212 |
206 // We can override the send reports quota with a command line switch. | 213 // We can override the send reports quota with a command line switch. |
207 if (cmd_line.HasSwitch(kMaxReports)) | 214 if (cmd_line.HasSwitch(kMaxReports)) |
208 max_reports = _wtoi(cmd_line.GetSwitchValueNative(kMaxReports).c_str()); | 215 max_reports = _wtoi(cmd_line.GetSwitchValueNative(kMaxReports).c_str()); |
209 | 216 |
210 // Allow the global pipe name to be overridden for better testability. | 217 // Allow the global pipe name to be overridden for better testability. |
211 if (cmd_line.HasSwitch(kPipeName)) | 218 if (cmd_line.HasSwitch(kPipeName)) |
212 pipe_name = cmd_line.GetSwitchValueNative(kPipeName); | 219 pipe_name = cmd_line.GetSwitchValueNative(kPipeName); |
213 | 220 |
214 #ifdef _WIN64 | 221 #ifdef _WIN64 |
215 pipe_name += L"-x64"; | 222 pipe_name += L"-x64"; |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
364 return; | 371 return; |
365 } | 372 } |
366 | 373 |
367 CrashMap map; | 374 CrashMap map; |
368 CustomInfoToMap(client_info, self->reporter_tag_, &map); | 375 CustomInfoToMap(client_info, self->reporter_tag_, &map); |
369 | 376 |
370 if (!WriteCustomInfoToFile(*file_path, map)) { | 377 if (!WriteCustomInfoToFile(*file_path, map)) { |
371 LOG(ERROR) << "could not write custom info file"; | 378 LOG(ERROR) << "could not write custom info file"; |
372 } | 379 } |
373 | 380 |
| 381 // Move dump file to the directory under client pid. |
| 382 FilePath dump_path = FilePath(*file_path); |
| 383 if (archive_dumps_by_pid_) { |
| 384 FilePath dump_path_with_pid(dump_path.DirName()); |
| 385 dump_path_with_pid = dump_path_with_pid.Append(base::Int64ToString16(pid)); |
| 386 file_util::CreateDirectoryW(dump_path_with_pid); |
| 387 dump_path_with_pid = dump_path_with_pid.Append(dump_path.BaseName()); |
| 388 file_util::Move(dump_path, dump_path_with_pid); |
| 389 } |
| 390 |
374 if (!self->sender_) | 391 if (!self->sender_) |
375 return; | 392 return; |
376 | 393 |
377 // Send the crash dump using a worker thread. This operation has retry | 394 // Send the crash dump using a worker thread. This operation has retry |
378 // logic in case there is no internet connection at the time. | 395 // logic in case there is no internet connection at the time. |
379 DumpJobInfo* dump_job = new DumpJobInfo(pid, self, map, *file_path); | 396 DumpJobInfo* dump_job = new DumpJobInfo(pid, self, map, |
| 397 dump_path.value()); |
380 if (!::QueueUserWorkItem(&CrashService::AsyncSendDump, | 398 if (!::QueueUserWorkItem(&CrashService::AsyncSendDump, |
381 dump_job, WT_EXECUTELONGFUNCTION)) { | 399 dump_job, WT_EXECUTELONGFUNCTION)) { |
382 LOG(ERROR) << "could not queue job"; | 400 LOG(ERROR) << "could not queue job"; |
383 } | 401 } |
384 } | 402 } |
385 | 403 |
386 // We are going to try sending the report several times. If we can't send, | 404 // We are going to try sending the report several times. If we can't send, |
387 // we sleep from one minute to several hours depending on the retry round. | 405 // we sleep from one minute to several hours depending on the retry round. |
388 unsigned long CrashService::AsyncSendDump(void* context) { | 406 unsigned long CrashService::AsyncSendDump(void* context) { |
389 if (!context) | 407 if (!context) |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
485 SDDL_REVISION, | 503 SDDL_REVISION, |
486 &sec_desc, NULL)) { | 504 &sec_desc, NULL)) { |
487 if (::GetSecurityDescriptorSacl(sec_desc, &sacl_present, &sacl, | 505 if (::GetSecurityDescriptorSacl(sec_desc, &sacl_present, &sacl, |
488 &sacl_defaulted)) { | 506 &sacl_defaulted)) { |
489 return sec_desc; | 507 return sec_desc; |
490 } | 508 } |
491 } | 509 } |
492 | 510 |
493 return NULL; | 511 return NULL; |
494 } | 512 } |
OLD | NEW |