| 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 |