Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/browser_watcher/postmortem_minidump_writer.h" | 5 #include "components/browser_watcher/postmortem_minidump_writer.h" |
| 6 | 6 |
| 7 #include <windows.h> // NOLINT | 7 #include <windows.h> // NOLINT |
| 8 #include <dbghelp.h> | 8 #include <dbghelp.h> |
| 9 | 9 |
| 10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
| 11 #include "base/files/file_util.h" | 11 #include "base/files/file_util.h" |
| 12 #include "base/files/scoped_file.h" | 12 #include "base/files/scoped_file.h" |
| 13 #include "base/files/scoped_temp_dir.h" | 13 #include "base/files/scoped_temp_dir.h" |
| 14 #include "base/win/scoped_handle.h" | 14 #include "base/win/scoped_handle.h" |
| 15 #include "components/browser_watcher/stability_data_names.h" | |
| 15 #include "components/browser_watcher/stability_report.pb.h" | 16 #include "components/browser_watcher/stability_report.pb.h" |
| 16 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
| 17 #include "third_party/crashpad/crashpad/snapshot/minidump/process_snapshot_minid ump.h" | 18 #include "third_party/crashpad/crashpad/snapshot/minidump/process_snapshot_minid ump.h" |
| 18 #include "third_party/crashpad/crashpad/util/file/file_reader.h" | 19 #include "third_party/crashpad/crashpad/util/file/file_reader.h" |
| 19 #include "third_party/crashpad/crashpad/util/misc/uuid.h" | 20 #include "third_party/crashpad/crashpad/util/misc/uuid.h" |
| 20 | 21 |
| 21 namespace browser_watcher { | 22 namespace browser_watcher { |
| 22 | 23 |
| 23 using crashpad::UUID; | 24 using crashpad::UUID; |
| 24 | 25 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 36 expected_client_id_.InitializeWithNew(); | 37 expected_client_id_.InitializeWithNew(); |
| 37 expected_report_id_.InitializeWithNew(); | 38 expected_report_id_.InitializeWithNew(); |
| 38 | 39 |
| 39 // Create a stability report. | 40 // Create a stability report. |
| 40 // TODO(manzagop): flesh out the report once proto is more detailed. | 41 // TODO(manzagop): flesh out the report once proto is more detailed. |
| 41 ProcessState* process_state = expected_report_.add_process_states(); | 42 ProcessState* process_state = expected_report_.add_process_states(); |
| 42 CodeModule* module = process_state->add_modules(); | 43 CodeModule* module = process_state->add_modules(); |
| 43 module->set_base_address(1024); | 44 module->set_base_address(1024); |
| 44 module->set_code_file("some_code_file.dll"); | 45 module->set_code_file("some_code_file.dll"); |
| 45 | 46 |
| 46 // Write the minidump. | 47 // Set up directory and path. |
| 47 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); | 48 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); |
| 48 minidump_path_ = temp_dir_.GetPath().AppendASCII("minidump.dmp"); | 49 minidump_path_ = temp_dir_.GetPath().AppendASCII("minidump.dmp"); |
| 49 } | 50 } |
| 50 | 51 |
| 51 bool WriteDump() { | 52 bool WriteDump(bool add_product_details) { |
| 53 // Make a copy of the expected report as product details are stripped from | |
| 54 // the proto written to the minidump stream. | |
| 55 StabilityReport report(expected_report_); | |
| 56 | |
| 57 if (add_product_details) { | |
| 58 google::protobuf::Map<std::string, TypedValue>* global_data = | |
|
bcwhite
2017/02/13 13:16:59
You can make this a reference type and dereference
manzagop (departed)
2017/02/13 17:07:45
Done.
| |
| 59 report.mutable_global_data(); | |
| 60 (*global_data)[kStabilityChannel].set_string_value(kChannel); | |
| 61 (*global_data)[kStabilityPlatform].set_string_value(kPlatform); | |
| 62 (*global_data)[kStabilityProduct].set_string_value(kProductName); | |
| 63 (*global_data)[kStabilityVersion].set_string_value(kVersion); | |
| 64 } | |
| 65 | |
| 52 base::win::ScopedHandle file_handle(::CreateFile( | 66 base::win::ScopedHandle file_handle(::CreateFile( |
| 53 minidump_path_.value().c_str(), GENERIC_READ | GENERIC_WRITE, | 67 minidump_path_.value().c_str(), GENERIC_READ | GENERIC_WRITE, |
| 54 FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, CREATE_NEW, | 68 FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, CREATE_NEW, |
| 55 FILE_ATTRIBUTE_NORMAL, nullptr)); | 69 FILE_ATTRIBUTE_NORMAL, nullptr)); |
| 56 if (!file_handle.IsValid()) | 70 if (!file_handle.IsValid()) |
| 57 return false; | 71 return false; |
| 58 | 72 |
| 59 MinidumpInfo minidump_info; | 73 return WritePostmortemDump(file_handle.Get(), expected_client_id_, |
| 60 minidump_info.client_id = expected_client_id_; | 74 expected_report_id_, &report); |
| 61 minidump_info.report_id = expected_report_id_; | |
| 62 minidump_info.product_name = kProductName; | |
| 63 minidump_info.version_number = kVersion; | |
| 64 minidump_info.channel_name = kChannel; | |
| 65 minidump_info.platform = kPlatform; | |
| 66 | |
| 67 return WritePostmortemDump(file_handle.Get(), expected_report_, | |
| 68 minidump_info); | |
| 69 } | 75 } |
| 70 | 76 |
| 71 const base::FilePath& minidump_path() { return minidump_path_; } | 77 const base::FilePath& minidump_path() { return minidump_path_; } |
| 72 const UUID& expected_client_id() { return expected_client_id_; } | 78 const UUID& expected_client_id() { return expected_client_id_; } |
| 73 const UUID& expected_report_id() { return expected_report_id_; } | 79 const UUID& expected_report_id() { return expected_report_id_; } |
| 74 const StabilityReport& expected_report() { return expected_report_; } | 80 const StabilityReport& expected_report() { return expected_report_; } |
| 75 | 81 |
| 76 private: | 82 private: |
| 77 base::ScopedTempDir temp_dir_; | 83 base::ScopedTempDir temp_dir_; |
| 78 base::FilePath minidump_path_; | 84 base::FilePath minidump_path_; |
| 79 UUID expected_client_id_; | 85 UUID expected_client_id_; |
| 80 UUID expected_report_id_; | 86 UUID expected_report_id_; |
| 81 StabilityReport expected_report_; | 87 StabilityReport expected_report_; |
| 82 }; | 88 }; |
| 83 | 89 |
| 90 TEST_F(WritePostmortemDumpTest, MissingProductDetailsFailureTest) { | |
| 91 ASSERT_FALSE(WriteDump(false)); | |
| 92 } | |
| 93 | |
| 84 TEST_F(WritePostmortemDumpTest, ValidateStabilityReportTest) { | 94 TEST_F(WritePostmortemDumpTest, ValidateStabilityReportTest) { |
| 85 ASSERT_TRUE(WriteDump()); | 95 ASSERT_TRUE(WriteDump(true)); |
| 86 | 96 |
| 87 // Read back the minidump to extract the proto. | 97 // Read back the minidump to extract the proto. |
| 88 // TODO(manzagop): rely on crashpad for reading the proto once crashpad | 98 // TODO(manzagop): rely on crashpad for reading the proto once crashpad |
| 89 // supports it (https://crashpad.chromium.org/bug/10). | 99 // supports it (https://crashpad.chromium.org/bug/10). |
| 90 base::ScopedFILE minidump_file; | 100 base::ScopedFILE minidump_file; |
| 91 minidump_file.reset(base::OpenFile(minidump_path(), "rb")); | 101 minidump_file.reset(base::OpenFile(minidump_path(), "rb")); |
| 92 ASSERT_TRUE(minidump_file.get()); | 102 ASSERT_TRUE(minidump_file.get()); |
| 93 | 103 |
| 94 MINIDUMP_HEADER header = {}; | 104 MINIDUMP_HEADER header = {}; |
| 95 ASSERT_EQ(1U, fread(&header, sizeof(header), 1, minidump_file.get())); | 105 ASSERT_EQ(1U, fread(&header, sizeof(header), 1, minidump_file.get())); |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 113 // Validate the recovered report. | 123 // Validate the recovered report. |
| 114 std::string expected_serialized_report; | 124 std::string expected_serialized_report; |
| 115 expected_report().SerializeToString(&expected_serialized_report); | 125 expected_report().SerializeToString(&expected_serialized_report); |
| 116 ASSERT_EQ(expected_serialized_report, recovered_serialized_report); | 126 ASSERT_EQ(expected_serialized_report, recovered_serialized_report); |
| 117 | 127 |
| 118 StabilityReport recovered_report; | 128 StabilityReport recovered_report; |
| 119 ASSERT_TRUE(recovered_report.ParseFromString(recovered_serialized_report)); | 129 ASSERT_TRUE(recovered_report.ParseFromString(recovered_serialized_report)); |
| 120 } | 130 } |
| 121 | 131 |
| 122 TEST_F(WritePostmortemDumpTest, CrashpadCanReadTest) { | 132 TEST_F(WritePostmortemDumpTest, CrashpadCanReadTest) { |
| 123 ASSERT_TRUE(WriteDump()); | 133 ASSERT_TRUE(WriteDump(true)); |
| 124 | 134 |
| 125 // Validate crashpad can read the produced minidump. | 135 // Validate crashpad can read the produced minidump. |
| 126 crashpad::FileReader minidump_file_reader; | 136 crashpad::FileReader minidump_file_reader; |
| 127 ASSERT_TRUE(minidump_file_reader.Open(minidump_path())); | 137 ASSERT_TRUE(minidump_file_reader.Open(minidump_path())); |
| 128 | 138 |
| 129 crashpad::ProcessSnapshotMinidump minidump_process_snapshot; | 139 crashpad::ProcessSnapshotMinidump minidump_process_snapshot; |
| 130 ASSERT_TRUE(minidump_process_snapshot.Initialize(&minidump_file_reader)); | 140 ASSERT_TRUE(minidump_process_snapshot.Initialize(&minidump_file_reader)); |
| 131 | 141 |
| 132 // Validate the crashpadinfo. | 142 // Validate the crashpadinfo. |
| 133 UUID client_id; | 143 UUID client_id; |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 151 it = parameters.find("channel"); | 161 it = parameters.find("channel"); |
| 152 ASSERT_NE(parameters.end(), it); | 162 ASSERT_NE(parameters.end(), it); |
| 153 ASSERT_EQ(kChannel, it->second); | 163 ASSERT_EQ(kChannel, it->second); |
| 154 | 164 |
| 155 it = parameters.find("plat"); | 165 it = parameters.find("plat"); |
| 156 ASSERT_NE(parameters.end(), it); | 166 ASSERT_NE(parameters.end(), it); |
| 157 ASSERT_EQ(kPlatform, it->second); | 167 ASSERT_EQ(kPlatform, it->second); |
| 158 } | 168 } |
| 159 | 169 |
| 160 } // namespace browser_watcher | 170 } // namespace browser_watcher |
| OLD | NEW |