OLD | NEW |
1 // Copyright 2014 The Crashpad Authors. All rights reserved. | 1 // Copyright 2014 The Crashpad Authors. All rights reserved. |
2 // | 2 // |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
4 // you may not use this file except in compliance with the License. | 4 // you may not use this file except in compliance with the License. |
5 // You may obtain a copy of the License at | 5 // You may obtain a copy of the License at |
6 // | 6 // |
7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
8 // | 8 // |
9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 // See the License for the specific language governing permissions and | 12 // See the License for the specific language governing permissions and |
13 // limitations under the License. | 13 // limitations under the License. |
14 | 14 |
15 #include "minidump/minidump_crashpad_info_writer.h" | 15 #include "minidump/minidump_crashpad_info_writer.h" |
16 | 16 |
17 #include <dbghelp.h> | 17 #include <dbghelp.h> |
18 | 18 |
19 #include "gtest/gtest.h" | 19 #include "gtest/gtest.h" |
20 #include "minidump/minidump_extensions.h" | 20 #include "minidump/minidump_extensions.h" |
21 #include "minidump/minidump_file_writer.h" | 21 #include "minidump/minidump_file_writer.h" |
22 #include "minidump/minidump_module_crashpad_info_writer.h" | 22 #include "minidump/minidump_module_crashpad_info_writer.h" |
23 #include "minidump/test/minidump_file_writer_test_util.h" | 23 #include "minidump/test/minidump_file_writer_test_util.h" |
| 24 #include "minidump/test/minidump_string_writer_test_util.h" |
24 #include "minidump/test/minidump_writable_test_util.h" | 25 #include "minidump/test/minidump_writable_test_util.h" |
| 26 #include "snapshot/test/test_module_snapshot.h" |
| 27 #include "snapshot/test/test_process_snapshot.h" |
25 #include "util/file/string_file_writer.h" | 28 #include "util/file/string_file_writer.h" |
26 | 29 |
27 namespace crashpad { | 30 namespace crashpad { |
28 namespace test { | 31 namespace test { |
29 namespace { | 32 namespace { |
30 | 33 |
31 void GetCrashpadInfoStream(const std::string& file_contents, | 34 void GetCrashpadInfoStream(const std::string& file_contents, |
32 const MinidumpCrashpadInfo** crashpad_info, | 35 const MinidumpCrashpadInfo** crashpad_info, |
33 const MinidumpModuleCrashpadInfoList** module_list) { | 36 const MinidumpModuleCrashpadInfoList** module_list) { |
34 const MINIDUMP_DIRECTORY* directory; | 37 const MINIDUMP_DIRECTORY* directory; |
35 const MINIDUMP_HEADER* header = | 38 const MINIDUMP_HEADER* header = |
36 MinidumpHeaderAtStart(file_contents, &directory); | 39 MinidumpHeaderAtStart(file_contents, &directory); |
37 ASSERT_NO_FATAL_FAILURE(VerifyMinidumpHeader(header, 1, 0)); | 40 ASSERT_NO_FATAL_FAILURE(VerifyMinidumpHeader(header, 1, 0)); |
38 ASSERT_TRUE(directory); | 41 ASSERT_TRUE(directory); |
39 | 42 |
40 ASSERT_EQ(kMinidumpStreamTypeCrashpadInfo, directory[0].StreamType); | 43 ASSERT_EQ(kMinidumpStreamTypeCrashpadInfo, directory[0].StreamType); |
41 | 44 |
42 *crashpad_info = MinidumpWritableAtLocationDescriptor<MinidumpCrashpadInfo>( | 45 *crashpad_info = MinidumpWritableAtLocationDescriptor<MinidumpCrashpadInfo>( |
43 file_contents, directory[0].Location); | 46 file_contents, directory[0].Location); |
44 ASSERT_TRUE(*crashpad_info); | 47 ASSERT_TRUE(*crashpad_info); |
45 | 48 |
46 *module_list = | 49 *module_list = |
47 MinidumpWritableAtLocationDescriptor<MinidumpModuleCrashpadInfoList>( | 50 MinidumpWritableAtLocationDescriptor<MinidumpModuleCrashpadInfoList>( |
48 file_contents, (*crashpad_info)->module_list); | 51 file_contents, (*crashpad_info)->module_list); |
49 } | 52 } |
50 | 53 |
51 TEST(MinidumpCrashpadInfoWriter, Empty) { | 54 TEST(MinidumpCrashpadInfoWriter, Empty) { |
52 MinidumpFileWriter minidump_file_writer; | 55 MinidumpFileWriter minidump_file_writer; |
53 auto crashpad_info_writer = make_scoped_ptr(new MinidumpCrashpadInfoWriter()); | 56 auto crashpad_info_writer = make_scoped_ptr(new MinidumpCrashpadInfoWriter()); |
| 57 EXPECT_FALSE(crashpad_info_writer->IsUseful()); |
54 | 58 |
55 minidump_file_writer.AddStream(crashpad_info_writer.Pass()); | 59 minidump_file_writer.AddStream(crashpad_info_writer.Pass()); |
56 | 60 |
57 StringFileWriter file_writer; | 61 StringFileWriter file_writer; |
58 ASSERT_TRUE(minidump_file_writer.WriteEverything(&file_writer)); | 62 ASSERT_TRUE(minidump_file_writer.WriteEverything(&file_writer)); |
59 | 63 |
60 const MinidumpCrashpadInfo* crashpad_info; | 64 const MinidumpCrashpadInfo* crashpad_info; |
61 const MinidumpModuleCrashpadInfoList* module_list; | 65 const MinidumpModuleCrashpadInfoList* module_list; |
62 | 66 |
63 ASSERT_NO_FATAL_FAILURE(GetCrashpadInfoStream( | 67 ASSERT_NO_FATAL_FAILURE(GetCrashpadInfoStream( |
64 file_writer.string(), &crashpad_info, &module_list)); | 68 file_writer.string(), &crashpad_info, &module_list)); |
65 | 69 |
66 EXPECT_EQ(MinidumpCrashpadInfo::kVersion, crashpad_info->version); | 70 EXPECT_EQ(MinidumpCrashpadInfo::kVersion, crashpad_info->version); |
67 EXPECT_FALSE(module_list); | 71 EXPECT_FALSE(module_list); |
68 } | 72 } |
69 | 73 |
70 TEST(MinidumpCrashpadInfoWriter, CrashpadModuleList) { | 74 TEST(MinidumpCrashpadInfoWriter, CrashpadModuleList) { |
71 const uint32_t kMinidumpModuleListIndex = 3; | 75 const uint32_t kMinidumpModuleListIndex = 3; |
72 | 76 |
73 MinidumpFileWriter minidump_file_writer; | 77 MinidumpFileWriter minidump_file_writer; |
74 auto crashpad_info_writer = make_scoped_ptr(new MinidumpCrashpadInfoWriter()); | 78 auto crashpad_info_writer = make_scoped_ptr(new MinidumpCrashpadInfoWriter()); |
75 | 79 |
76 auto module_list_writer = | 80 auto module_list_writer = |
77 make_scoped_ptr(new MinidumpModuleCrashpadInfoListWriter()); | 81 make_scoped_ptr(new MinidumpModuleCrashpadInfoListWriter()); |
78 auto module_writer = make_scoped_ptr(new MinidumpModuleCrashpadInfoWriter()); | 82 auto module_writer = make_scoped_ptr(new MinidumpModuleCrashpadInfoWriter()); |
79 module_writer->SetMinidumpModuleListIndex(kMinidumpModuleListIndex); | 83 module_writer->SetMinidumpModuleListIndex(kMinidumpModuleListIndex); |
80 module_list_writer->AddModule(module_writer.Pass()); | 84 module_list_writer->AddModule(module_writer.Pass()); |
81 crashpad_info_writer->SetModuleList(module_list_writer.Pass()); | 85 crashpad_info_writer->SetModuleList(module_list_writer.Pass()); |
82 | 86 |
| 87 EXPECT_TRUE(crashpad_info_writer->IsUseful()); |
| 88 |
83 minidump_file_writer.AddStream(crashpad_info_writer.Pass()); | 89 minidump_file_writer.AddStream(crashpad_info_writer.Pass()); |
84 | 90 |
85 StringFileWriter file_writer; | 91 StringFileWriter file_writer; |
86 ASSERT_TRUE(minidump_file_writer.WriteEverything(&file_writer)); | 92 ASSERT_TRUE(minidump_file_writer.WriteEverything(&file_writer)); |
87 | 93 |
88 const MinidumpCrashpadInfo* crashpad_info; | 94 const MinidumpCrashpadInfo* crashpad_info; |
89 const MinidumpModuleCrashpadInfoList* module_list; | 95 const MinidumpModuleCrashpadInfoList* module_list; |
90 | 96 |
91 ASSERT_NO_FATAL_FAILURE(GetCrashpadInfoStream( | 97 ASSERT_NO_FATAL_FAILURE(GetCrashpadInfoStream( |
92 file_writer.string(), &crashpad_info, &module_list)); | 98 file_writer.string(), &crashpad_info, &module_list)); |
93 | 99 |
94 EXPECT_EQ(MinidumpCrashpadInfo::kVersion, crashpad_info->version); | 100 EXPECT_EQ(MinidumpCrashpadInfo::kVersion, crashpad_info->version); |
95 ASSERT_TRUE(module_list); | 101 ASSERT_TRUE(module_list); |
96 ASSERT_EQ(1u, module_list->count); | 102 ASSERT_EQ(1u, module_list->count); |
97 | 103 |
98 const MinidumpModuleCrashpadInfo* module = | 104 const MinidumpModuleCrashpadInfo* module = |
99 MinidumpWritableAtLocationDescriptor<MinidumpModuleCrashpadInfo>( | 105 MinidumpWritableAtLocationDescriptor<MinidumpModuleCrashpadInfo>( |
100 file_writer.string(), module_list->children[0]); | 106 file_writer.string(), module_list->children[0]); |
101 ASSERT_TRUE(module); | 107 ASSERT_TRUE(module); |
102 | 108 |
103 EXPECT_EQ(MinidumpModuleCrashpadInfo::kVersion, module->version); | 109 EXPECT_EQ(MinidumpModuleCrashpadInfo::kVersion, module->version); |
104 EXPECT_EQ(kMinidumpModuleListIndex, module->minidump_module_list_index); | 110 EXPECT_EQ(kMinidumpModuleListIndex, module->minidump_module_list_index); |
| 111 EXPECT_EQ(0u, module->list_annotations.DataSize); |
| 112 EXPECT_EQ(0u, module->list_annotations.Rva); |
105 EXPECT_EQ(0u, module->simple_annotations.DataSize); | 113 EXPECT_EQ(0u, module->simple_annotations.DataSize); |
106 EXPECT_EQ(0u, module->simple_annotations.Rva); | 114 EXPECT_EQ(0u, module->simple_annotations.Rva); |
107 } | 115 } |
108 | 116 |
| 117 TEST(MinidumpCrashpadInfoWriter, InitializeFromSnapshot) { |
| 118 const char kEntry[] = "This is a simple annotation in a list."; |
| 119 |
| 120 // Test with a useless module, one that doesn’t carry anything that would |
| 121 // require MinidumpCrashpadInfo or any child object. |
| 122 auto process_snapshot = make_scoped_ptr(new TestProcessSnapshot()); |
| 123 |
| 124 auto module_snapshot = make_scoped_ptr(new TestModuleSnapshot()); |
| 125 process_snapshot->AddModule(module_snapshot.Pass()); |
| 126 |
| 127 auto info_writer = make_scoped_ptr(new MinidumpCrashpadInfoWriter()); |
| 128 info_writer->InitializeFromSnapshot(process_snapshot.get()); |
| 129 EXPECT_FALSE(info_writer->IsUseful()); |
| 130 |
| 131 // Try again with a useful module. |
| 132 process_snapshot.reset(new TestProcessSnapshot()); |
| 133 |
| 134 module_snapshot.reset(new TestModuleSnapshot()); |
| 135 std::vector<std::string> annotations_list(1, std::string(kEntry)); |
| 136 module_snapshot->SetAnnotationsVector(annotations_list); |
| 137 process_snapshot->AddModule(module_snapshot.Pass()); |
| 138 |
| 139 info_writer.reset(new MinidumpCrashpadInfoWriter()); |
| 140 info_writer->InitializeFromSnapshot(process_snapshot.get()); |
| 141 EXPECT_TRUE(info_writer->IsUseful()); |
| 142 |
| 143 MinidumpFileWriter minidump_file_writer; |
| 144 minidump_file_writer.AddStream(info_writer.Pass()); |
| 145 |
| 146 StringFileWriter file_writer; |
| 147 ASSERT_TRUE(minidump_file_writer.WriteEverything(&file_writer)); |
| 148 |
| 149 const MinidumpCrashpadInfo* info; |
| 150 const MinidumpModuleCrashpadInfoList* module_list; |
| 151 ASSERT_NO_FATAL_FAILURE(GetCrashpadInfoStream( |
| 152 file_writer.string(), &info, &module_list)); |
| 153 |
| 154 EXPECT_EQ(MinidumpCrashpadInfo::kVersion, info->version); |
| 155 ASSERT_TRUE(module_list); |
| 156 ASSERT_EQ(1u, module_list->count); |
| 157 |
| 158 const MinidumpModuleCrashpadInfo* module = |
| 159 MinidumpWritableAtLocationDescriptor<MinidumpModuleCrashpadInfo>( |
| 160 file_writer.string(), module_list->children[0]); |
| 161 ASSERT_TRUE(module); |
| 162 |
| 163 EXPECT_EQ(MinidumpModuleCrashpadInfo::kVersion, module->version); |
| 164 EXPECT_EQ(0u, module->minidump_module_list_index); |
| 165 |
| 166 const MinidumpRVAList* list_annotations = |
| 167 MinidumpWritableAtLocationDescriptor<MinidumpRVAList>( |
| 168 file_writer.string(), module->list_annotations); |
| 169 ASSERT_TRUE(list_annotations); |
| 170 |
| 171 ASSERT_EQ(1u, list_annotations->count); |
| 172 EXPECT_EQ(kEntry, |
| 173 MinidumpUTF8StringAtRVAAsString( |
| 174 file_writer.string(), list_annotations->children[0])); |
| 175 |
| 176 const MinidumpSimpleStringDictionary* simple_annotations = |
| 177 MinidumpWritableAtLocationDescriptor<MinidumpSimpleStringDictionary>( |
| 178 file_writer.string(), module->simple_annotations); |
| 179 EXPECT_FALSE(simple_annotations); |
| 180 } |
| 181 |
109 } // namespace | 182 } // namespace |
110 } // namespace test | 183 } // namespace test |
111 } // namespace crashpad | 184 } // namespace crashpad |
OLD | NEW |