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_module_writer.h" | 15 #include "minidump/minidump_module_writer.h" |
16 | 16 |
17 #include <dbghelp.h> | 17 #include <dbghelp.h> |
18 #include <stdint.h> | 18 #include <stdint.h> |
19 #include <string.h> | 19 #include <string.h> |
20 | 20 |
21 #include "base/strings/utf_string_conversions.h" | 21 #include "base/strings/utf_string_conversions.h" |
22 #include "gtest/gtest.h" | 22 #include "gtest/gtest.h" |
23 #include "minidump/minidump_extensions.h" | 23 #include "minidump/minidump_extensions.h" |
24 #include "minidump/minidump_file_writer.h" | 24 #include "minidump/minidump_file_writer.h" |
25 #include "minidump/test/minidump_file_writer_test_util.h" | 25 #include "minidump/test/minidump_file_writer_test_util.h" |
26 #include "minidump/test/minidump_string_writer_test_util.h" | 26 #include "minidump/test/minidump_string_writer_test_util.h" |
| 27 #include "minidump/test/minidump_writable_test_util.h" |
27 #include "util/file/string_file_writer.h" | 28 #include "util/file/string_file_writer.h" |
28 #include "util/misc/uuid.h" | 29 #include "util/misc/uuid.h" |
29 | 30 |
30 namespace crashpad { | 31 namespace crashpad { |
31 namespace test { | 32 namespace test { |
32 namespace { | 33 namespace { |
33 | 34 |
34 void GetModuleListStream(const std::string& file_contents, | 35 void GetModuleListStream(const std::string& file_contents, |
35 const MINIDUMP_MODULE_LIST** module_list) { | 36 const MINIDUMP_MODULE_LIST** module_list) { |
36 const size_t kDirectoryOffset = sizeof(MINIDUMP_HEADER); | 37 const size_t kDirectoryOffset = sizeof(MINIDUMP_HEADER); |
37 const size_t kModuleListStreamOffset = | 38 const size_t kModuleListStreamOffset = |
38 kDirectoryOffset + sizeof(MINIDUMP_DIRECTORY); | 39 kDirectoryOffset + sizeof(MINIDUMP_DIRECTORY); |
39 const size_t kModulesOffset = | 40 const size_t kModulesOffset = |
40 kModuleListStreamOffset + sizeof(MINIDUMP_MODULE_LIST); | 41 kModuleListStreamOffset + sizeof(MINIDUMP_MODULE_LIST); |
41 | 42 |
42 ASSERT_GE(file_contents.size(), kModulesOffset); | 43 ASSERT_GE(file_contents.size(), kModulesOffset); |
43 | 44 |
44 const MINIDUMP_DIRECTORY* directory; | 45 const MINIDUMP_DIRECTORY* directory; |
45 const MINIDUMP_HEADER* header = | 46 const MINIDUMP_HEADER* header = |
46 MinidumpHeaderAtStart(file_contents, &directory); | 47 MinidumpHeaderAtStart(file_contents, &directory); |
47 ASSERT_NO_FATAL_FAILURE(VerifyMinidumpHeader(header, 1, 0)); | 48 ASSERT_NO_FATAL_FAILURE(VerifyMinidumpHeader(header, 1, 0)); |
48 ASSERT_TRUE(directory); | 49 ASSERT_TRUE(directory); |
49 | 50 |
50 ASSERT_EQ(kMinidumpStreamTypeModuleList, directory[0].StreamType); | 51 ASSERT_EQ(kMinidumpStreamTypeModuleList, directory[0].StreamType); |
51 ASSERT_GE(directory[0].Location.DataSize, sizeof(MINIDUMP_MODULE_LIST)); | 52 EXPECT_EQ(kModuleListStreamOffset, directory[0].Location.Rva); |
52 ASSERT_EQ(kModuleListStreamOffset, directory[0].Location.Rva); | |
53 | 53 |
54 *module_list = reinterpret_cast<const MINIDUMP_MODULE_LIST*>( | 54 *module_list = MinidumpWritableAtLocationDescriptor<MINIDUMP_MODULE_LIST>( |
55 &file_contents[kModuleListStreamOffset]); | 55 file_contents, directory[0].Location); |
56 | 56 ASSERT_TRUE(module_list); |
57 ASSERT_EQ(sizeof(MINIDUMP_MODULE_LIST) + | |
58 (*module_list)->NumberOfModules * sizeof(MINIDUMP_MODULE), | |
59 directory[0].Location.DataSize); | |
60 } | 57 } |
61 | 58 |
62 TEST(MinidumpModuleWriter, EmptyModuleList) { | 59 TEST(MinidumpModuleWriter, EmptyModuleList) { |
63 MinidumpFileWriter minidump_file_writer; | 60 MinidumpFileWriter minidump_file_writer; |
64 MinidumpModuleListWriter module_list_writer; | 61 MinidumpModuleListWriter module_list_writer; |
65 | 62 |
66 minidump_file_writer.AddStream(&module_list_writer); | 63 minidump_file_writer.AddStream(&module_list_writer); |
67 | 64 |
68 StringFileWriter file_writer; | 65 StringFileWriter file_writer; |
69 ASSERT_TRUE(minidump_file_writer.WriteEverything(&file_writer)); | 66 ASSERT_TRUE(minidump_file_writer.WriteEverything(&file_writer)); |
(...skipping 15 matching lines...) Expand all Loading... |
85 // record must be a PDB 7.0 link, otherwise, it must be a PDB 2.0 link. If | 82 // record must be a PDB 7.0 link, otherwise, it must be a PDB 2.0 link. If |
86 // |expected_pdb_name| is nullptr, |codeview_record| must not point to anything. | 83 // |expected_pdb_name| is nullptr, |codeview_record| must not point to anything. |
87 void ExpectCodeViewRecord(const MINIDUMP_LOCATION_DESCRIPTOR* codeview_record, | 84 void ExpectCodeViewRecord(const MINIDUMP_LOCATION_DESCRIPTOR* codeview_record, |
88 const std::string& file_contents, | 85 const std::string& file_contents, |
89 const char* expected_pdb_name, | 86 const char* expected_pdb_name, |
90 const UUID* expected_pdb_uuid, | 87 const UUID* expected_pdb_uuid, |
91 time_t expected_pdb_timestamp, | 88 time_t expected_pdb_timestamp, |
92 uint32_t expected_pdb_age) { | 89 uint32_t expected_pdb_age) { |
93 if (expected_pdb_name) { | 90 if (expected_pdb_name) { |
94 EXPECT_NE(0u, codeview_record->Rva); | 91 EXPECT_NE(0u, codeview_record->Rva); |
95 ASSERT_LE(codeview_record->Rva + codeview_record->DataSize, | |
96 file_contents.size()); | |
97 | 92 |
98 std::string observed_pdb_name; | 93 std::string observed_pdb_name; |
99 if (expected_pdb_uuid) { | 94 if (expected_pdb_uuid) { |
100 // The CodeView record should be a PDB 7.0 link. | 95 // The CodeView record should be a PDB 7.0 link. |
101 EXPECT_GE(codeview_record->DataSize, | |
102 sizeof(MinidumpModuleCodeViewRecordPDB70)); | |
103 const MinidumpModuleCodeViewRecordPDB70* codeview_pdb70_record = | 96 const MinidumpModuleCodeViewRecordPDB70* codeview_pdb70_record = |
104 reinterpret_cast<const MinidumpModuleCodeViewRecordPDB70*>( | 97 MinidumpWritableAtLocationDescriptor< |
105 &file_contents[codeview_record->Rva]); | 98 MinidumpModuleCodeViewRecordPDB70>(file_contents, |
106 EXPECT_EQ(MinidumpModuleCodeViewRecordPDB70::kSignature, | 99 *codeview_record); |
107 codeview_pdb70_record->signature); | 100 ASSERT_TRUE(codeview_pdb70_record); |
108 EXPECT_EQ(0, | 101 EXPECT_EQ(0, |
109 memcmp(expected_pdb_uuid, | 102 memcmp(expected_pdb_uuid, |
110 &codeview_pdb70_record->uuid, | 103 &codeview_pdb70_record->uuid, |
111 sizeof(codeview_pdb70_record->uuid))); | 104 sizeof(codeview_pdb70_record->uuid))); |
112 EXPECT_EQ(expected_pdb_age, codeview_pdb70_record->age); | 105 EXPECT_EQ(expected_pdb_age, codeview_pdb70_record->age); |
113 | 106 |
114 observed_pdb_name.assign( | 107 observed_pdb_name.assign( |
115 reinterpret_cast<const char*>(&codeview_pdb70_record->pdb_name[0]), | 108 reinterpret_cast<const char*>(&codeview_pdb70_record->pdb_name[0]), |
116 codeview_record->DataSize - | 109 codeview_record->DataSize - |
117 offsetof(MinidumpModuleCodeViewRecordPDB70, pdb_name)); | 110 offsetof(MinidumpModuleCodeViewRecordPDB70, pdb_name)); |
118 } else { | 111 } else { |
119 // The CodeView record should be a PDB 2.0 link. | 112 // The CodeView record should be a PDB 2.0 link. |
120 EXPECT_GE(codeview_record->DataSize, | |
121 sizeof(MinidumpModuleCodeViewRecordPDB20)); | |
122 const MinidumpModuleCodeViewRecordPDB20* codeview_pdb20_record = | 113 const MinidumpModuleCodeViewRecordPDB20* codeview_pdb20_record = |
123 reinterpret_cast<const MinidumpModuleCodeViewRecordPDB20*>( | 114 MinidumpWritableAtLocationDescriptor< |
124 &file_contents[codeview_record->Rva]); | 115 MinidumpModuleCodeViewRecordPDB20>(file_contents, |
125 EXPECT_EQ(MinidumpModuleCodeViewRecordPDB20::kSignature, | 116 *codeview_record); |
126 codeview_pdb20_record->signature); | 117 ASSERT_TRUE(codeview_pdb20_record); |
127 EXPECT_EQ(static_cast<uint32_t>(expected_pdb_timestamp), | 118 EXPECT_EQ(static_cast<uint32_t>(expected_pdb_timestamp), |
128 codeview_pdb20_record->timestamp); | 119 codeview_pdb20_record->timestamp); |
129 EXPECT_EQ(expected_pdb_age, codeview_pdb20_record->age); | 120 EXPECT_EQ(expected_pdb_age, codeview_pdb20_record->age); |
130 | 121 |
131 observed_pdb_name.assign( | 122 observed_pdb_name.assign( |
132 reinterpret_cast<const char*>(&codeview_pdb20_record->pdb_name[0]), | 123 reinterpret_cast<const char*>(&codeview_pdb20_record->pdb_name[0]), |
133 codeview_record->DataSize - | 124 codeview_record->DataSize - |
134 offsetof(MinidumpModuleCodeViewRecordPDB20, pdb_name)); | 125 offsetof(MinidumpModuleCodeViewRecordPDB20, pdb_name)); |
135 } | 126 } |
136 | 127 |
(...skipping 13 matching lines...) Expand all Loading... |
150 // miscellanous debugging record in |file_contents|, and its fields are compared | 141 // miscellanous debugging record in |file_contents|, and its fields are compared |
151 // against the the |expected_debug_*| values. If |expected_debug_name| is | 142 // against the the |expected_debug_*| values. If |expected_debug_name| is |
152 // nullptr, |misc_record| must not point to anything. | 143 // nullptr, |misc_record| must not point to anything. |
153 void ExpectMiscellaneousDebugRecord( | 144 void ExpectMiscellaneousDebugRecord( |
154 const MINIDUMP_LOCATION_DESCRIPTOR* misc_record, | 145 const MINIDUMP_LOCATION_DESCRIPTOR* misc_record, |
155 const std::string& file_contents, | 146 const std::string& file_contents, |
156 const char* expected_debug_name, | 147 const char* expected_debug_name, |
157 uint32_t expected_debug_type, | 148 uint32_t expected_debug_type, |
158 bool expected_debug_utf16) { | 149 bool expected_debug_utf16) { |
159 if (expected_debug_name) { | 150 if (expected_debug_name) { |
160 EXPECT_GE(misc_record->DataSize, sizeof(IMAGE_DEBUG_MISC)); | |
161 EXPECT_NE(0u, misc_record->Rva); | 151 EXPECT_NE(0u, misc_record->Rva); |
162 ASSERT_LE(misc_record->Rva + misc_record->DataSize, file_contents.size()); | |
163 const IMAGE_DEBUG_MISC* misc_debug_record = | 152 const IMAGE_DEBUG_MISC* misc_debug_record = |
164 reinterpret_cast<const IMAGE_DEBUG_MISC*>( | 153 MinidumpWritableAtLocationDescriptor<IMAGE_DEBUG_MISC>(file_contents, |
165 &file_contents[misc_record->Rva]); | 154 *misc_record); |
| 155 ASSERT_TRUE(misc_debug_record); |
166 EXPECT_EQ(expected_debug_type, misc_debug_record->DataType); | 156 EXPECT_EQ(expected_debug_type, misc_debug_record->DataType); |
167 EXPECT_EQ(misc_record->DataSize, misc_debug_record->Length); | |
168 EXPECT_EQ(expected_debug_utf16, misc_debug_record->Unicode); | 157 EXPECT_EQ(expected_debug_utf16, misc_debug_record->Unicode); |
169 EXPECT_EQ(0u, misc_debug_record->Reserved[0]); | 158 EXPECT_EQ(0u, misc_debug_record->Reserved[0]); |
170 EXPECT_EQ(0u, misc_debug_record->Reserved[1]); | 159 EXPECT_EQ(0u, misc_debug_record->Reserved[1]); |
171 EXPECT_EQ(0u, misc_debug_record->Reserved[2]); | 160 EXPECT_EQ(0u, misc_debug_record->Reserved[2]); |
172 | 161 |
173 // Check for the NUL terminator. | 162 // Check for the NUL terminator. |
174 size_t bytes_available = | 163 size_t bytes_available = |
175 misc_debug_record->Length - offsetof(IMAGE_DEBUG_MISC, Data); | 164 misc_debug_record->Length - offsetof(IMAGE_DEBUG_MISC, Data); |
176 EXPECT_EQ('\0', misc_debug_record->Data[bytes_available - 1]); | 165 EXPECT_EQ('\0', misc_debug_record->Data[bytes_available - 1]); |
177 std::string observed_data( | 166 std::string observed_data( |
(...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
617 module_list_writer.AddModule(&module_writer); | 606 module_list_writer.AddModule(&module_writer); |
618 minidump_file_writer.AddStream(&module_list_writer); | 607 minidump_file_writer.AddStream(&module_list_writer); |
619 | 608 |
620 StringFileWriter file_writer; | 609 StringFileWriter file_writer; |
621 ASSERT_DEATH(minidump_file_writer.WriteEverything(&file_writer), "name_"); | 610 ASSERT_DEATH(minidump_file_writer.WriteEverything(&file_writer), "name_"); |
622 } | 611 } |
623 | 612 |
624 } // namespace | 613 } // namespace |
625 } // namespace test | 614 } // namespace test |
626 } // namespace crashpad | 615 } // namespace crashpad |
OLD | NEW |