| OLD | NEW |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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 "components/crash/content/app/fallback_crash_handler_win.h" | 5 #include "components/crash/content/app/fallback_crash_handler_win.h" |
| 6 | 6 |
| 7 #include <dbghelp.h> | 7 #include <dbghelp.h> |
| 8 #include <psapi.h> |
| 8 | 9 |
| 9 #include <algorithm> | 10 #include <algorithm> |
| 10 #include <map> | 11 #include <map> |
| 11 #include <vector> | 12 #include <vector> |
| 12 | 13 |
| 13 #include "base/command_line.h" | 14 #include "base/command_line.h" |
| 14 #include "base/files/file.h" | 15 #include "base/files/file.h" |
| 15 #include "base/files/file_util.h" | 16 #include "base/files/file_util.h" |
| 16 #include "base/macros.h" | 17 #include "base/macros.h" |
| 17 #include "base/numerics/safe_conversions.h" | 18 #include "base/numerics/safe_conversions.h" |
| 18 #include "base/process/process_handle.h" | 19 #include "base/process/process_handle.h" |
| 19 #include "base/strings/string_number_conversions.h" | 20 #include "base/strings/string_number_conversions.h" |
| 20 #include "base/win/scoped_handle.h" | 21 #include "base/win/scoped_handle.h" |
| 21 #include "base/win/win_util.h" | 22 #include "base/win/win_util.h" |
| 22 #include "third_party/crashpad/crashpad/client/crash_report_database.h" | 23 #include "third_party/crashpad/crashpad/client/crash_report_database.h" |
| 23 #include "third_party/crashpad/crashpad/client/settings.h" | 24 #include "third_party/crashpad/crashpad/client/settings.h" |
| 24 #include "third_party/crashpad/crashpad/minidump/minidump_extensions.h" | 25 #include "third_party/crashpad/crashpad/minidump/minidump_extensions.h" |
| 25 | 26 |
| 26 namespace crash_reporter { | 27 namespace crash_reporter { |
| 27 | 28 |
| 28 namespace { | 29 namespace { |
| 29 | 30 |
| 30 using FilePosition = uint32_t; | 31 using FilePosition = uint32_t; |
| 31 const FilePosition kInvalidFilePos = static_cast<FilePosition>(-1); | 32 const FilePosition kInvalidFilePos = static_cast<FilePosition>(-1); |
| 32 | 33 |
| 33 using StringStringMap = std::map<std::string, std::string>; | 34 using StringStringMap = std::map<std::string, std::string>; |
| 34 | 35 |
| 36 void AcquireMemoryMetrics(const base::Process& process, |
| 37 StringStringMap* crash_keys) { |
| 38 // Grab the process private memory. |
| 39 // This is best effort, though really shouldn't ever fail. |
| 40 PROCESS_MEMORY_COUNTERS_EX process_memory = {sizeof(process_memory)}; |
| 41 if (GetProcessMemoryInfo( |
| 42 process.Handle(), |
| 43 reinterpret_cast<PROCESS_MEMORY_COUNTERS*>(&process_memory), |
| 44 sizeof(process_memory))) { |
| 45 // This is in units of bytes, re-scale to pages for consistency with |
| 46 // system metrics. |
| 47 const uint64_t kPageSize = 4096; |
| 48 crash_keys->insert(std::make_pair( |
| 49 "ProcessPrivateUsage", |
| 50 base::Uint64ToString(process_memory.PrivateUsage / kPageSize))); |
| 51 |
| 52 crash_keys->insert(std::make_pair( |
| 53 "ProcessPeakWorkingSetSize", |
| 54 base::Uint64ToString(process_memory.PeakWorkingSetSize / kPageSize))); |
| 55 } |
| 56 |
| 57 // Grab system commit memory. Also best effort. |
| 58 PERFORMANCE_INFORMATION perf_info = {sizeof(perf_info)}; |
| 59 if (GetPerformanceInfo(&perf_info, sizeof(perf_info))) { |
| 60 // Record the remaining committable memory and the limit. This is in units |
| 61 // of system pages. |
| 62 crash_keys->insert(std::make_pair( |
| 63 "SystemCommitRemaining", |
| 64 base::UintToString(perf_info.CommitLimit - perf_info.CommitTotal))); |
| 65 crash_keys->insert(std::make_pair( |
| 66 "SystemCommitLimit", base::UintToString(perf_info.CommitLimit))); |
| 67 } |
| 68 } |
| 69 |
| 35 // This class is a helper to edit minidump files written by MiniDumpWriteDump. | 70 // This class is a helper to edit minidump files written by MiniDumpWriteDump. |
| 36 // It assumes the minidump file it operates on has a directory entry pointing to | 71 // It assumes the minidump file it operates on has a directory entry pointing to |
| 37 // a CrashpadInfo entry, which it updates to point to the SimpleDictionary data | 72 // a CrashpadInfo entry, which it updates to point to the SimpleDictionary data |
| 38 // it appends to the file contents. | 73 // it appends to the file contents. |
| 39 class MinidumpUpdater { | 74 class MinidumpUpdater { |
| 40 public: | 75 public: |
| 41 MinidumpUpdater(); | 76 MinidumpUpdater(); |
| 42 | 77 |
| 43 // Reads the existing directory from |file|. | 78 // Reads the existing directory from |file|. |
| 44 bool Initialize(base::File* file); | 79 bool Initialize(base::File* file); |
| (...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 405 const char* platform = "Win64"; | 440 const char* platform = "Win64"; |
| 406 #else | 441 #else |
| 407 const char* platform = "Win32"; | 442 const char* platform = "Win32"; |
| 408 #endif | 443 #endif |
| 409 std::map<std::string, std::string> crash_keys = {{"prod", product}, | 444 std::map<std::string, std::string> crash_keys = {{"prod", product}, |
| 410 {"ver", version}, | 445 {"ver", version}, |
| 411 {"channel", channel}, | 446 {"channel", channel}, |
| 412 {"plat", platform}, | 447 {"plat", platform}, |
| 413 {"ptype", process_type}}; | 448 {"ptype", process_type}}; |
| 414 | 449 |
| 450 // Add memory metrics relating to system-wide and target process memory usage. |
| 451 AcquireMemoryMetrics(process_, &crash_keys); |
| 452 |
| 415 crashpad::UUID client_id; | 453 crashpad::UUID client_id; |
| 416 crashpad::Settings* settings = database->GetSettings(); | 454 crashpad::Settings* settings = database->GetSettings(); |
| 417 if (settings) { | 455 if (settings) { |
| 418 // If GetSettings() or GetClientID() fails client_id will be left at its | 456 // If GetSettings() or GetClientID() fails client_id will be left at its |
| 419 // default value, all zeroes, which is appropriate. | 457 // default value, all zeroes, which is appropriate. |
| 420 settings->GetClientID(&client_id); | 458 settings->GetClientID(&client_id); |
| 421 } | 459 } |
| 422 | 460 |
| 423 base::FilePath dump_file_path; | 461 base::FilePath dump_file_path; |
| 424 if (!base::CreateTemporaryFile(&dump_file_path)) | 462 if (!base::CreateTemporaryFile(&dump_file_path)) |
| 425 return false; | 463 return false; |
| 426 | 464 |
| 427 // Open the file with delete on close, to try and ensure it's cleaned up on | 465 // Open the file with delete on close, to try and ensure it's cleaned up on |
| 428 // any kind of failure. | 466 // any kind of failure. |
| 429 base::File dump_file(dump_file_path, base::File::FLAG_OPEN | | 467 base::File dump_file(dump_file_path, base::File::FLAG_OPEN | |
| 430 base::File::FLAG_READ | | 468 base::File::FLAG_READ | |
| 431 base::File::FLAG_WRITE | | 469 base::File::FLAG_WRITE | |
| 432 base::File::FLAG_DELETE_ON_CLOSE); | 470 base::File::FLAG_DELETE_ON_CLOSE); |
| 433 if (!dump_file.IsValid()) | 471 if (!dump_file.IsValid()) |
| 434 return false; | 472 return false; |
| 435 | 473 |
| 436 uint32_t minidump_type = MiniDumpWithUnloadedModules | | 474 uint32_t minidump_type = MiniDumpWithUnloadedModules | |
| 437 MiniDumpWithProcessThreadData | | 475 MiniDumpWithProcessThreadData | |
| 438 MiniDumpWithThreadInfo; | 476 MiniDumpWithThreadInfo; |
| 439 | 477 |
| 440 // Capture more detail for canary and dev channels. The prefix search caters | 478 // Capture more detail for canary and dev channels. The prefix search caters |
| 441 // for the soon to be outdated "-m" suffixed multi-install channels. | 479 // for the soon to be outdated "-m" suffixed multi-install channels. |
| 442 if (channel.find("canary") == 0 || channel.find("dev") == 0) | 480 if (channel.find("canary") == 0 || channel.find("dev") == 0) |
| 443 minidump_type |= MiniDumpWithIndirectlyReferencedMemory; | 481 minidump_type |= MiniDumpWithIndirectlyReferencedMemory; |
| 444 | 482 |
| 445 // Write the minidump to the temp file, and then copy the data to the | 483 // Write the minidump to the temp file, and then copy the data to the |
| 446 // Crashpad-provided handle, as the latter is only open for write. | 484 // Crashpad-provided handle, as the latter is only open for write. |
| 447 if (!MiniDumpWriteDumpWithCrashpadInfo(process_, minidump_type, &exc_info, | 485 if (!MiniDumpWriteDumpWithCrashpadInfo(process_, minidump_type, &exc_info, |
| 448 crash_keys, client_id, report->uuid, | 486 crash_keys, client_id, report->uuid, |
| 449 &dump_file) || | 487 &dump_file) || |
| 450 !AppendFileContents(&dump_file, report->handle)) { | 488 !AppendFileContents(&dump_file, report->handle)) { |
| 451 return false; | 489 return false; |
| 452 } | 490 } |
| 453 | 491 |
| 454 on_error.Disarm(); | 492 on_error.Disarm(); |
| 455 | 493 |
| 456 crashpad::UUID report_id = {}; | 494 crashpad::UUID report_id = {}; |
| 457 status = database->FinishedWritingCrashReport(report, &report_id); | 495 status = database->FinishedWritingCrashReport(report, &report_id); |
| 458 if (status != crashpad::CrashReportDatabase::kNoError) | 496 if (status != crashpad::CrashReportDatabase::kNoError) |
| 459 return false; | 497 return false; |
| 460 | 498 |
| 461 return true; | 499 return true; |
| 462 } | 500 } |
| 463 | 501 |
| 464 } // namespace crash_reporter | 502 } // namespace crash_reporter |
| OLD | NEW |