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 |