Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(83)

Side by Side Diff: minidump/minidump_module_writer_test.cc

Issue 460933004: Add MinidumpModuleWriter, MinidumpModuleListWriter, related classes, and their test (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 The Crashpad Authors. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (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
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "minidump/minidump_module_writer.h"
16
17 #include <dbghelp.h>
18 #include <stdint.h>
19 #include <string.h>
20
21 #include "base/strings/utf_string_conversions.h"
22 #include "gtest/gtest.h"
23 #include "minidump/minidump_extensions.h"
24 #include "minidump/minidump_file_writer.h"
25 #include "minidump/minidump_test_util.h"
26 #include "util/file/string_file_writer.h"
27 #include "util/misc/uuid.h"
28
29 namespace {
30
31 using namespace crashpad;
32 using namespace crashpad::test;
33
34 void GetModuleListStream(const std::string& file_contents,
35 const MINIDUMP_MODULE_LIST** module_list) {
36 const size_t kDirectoryOffset = sizeof(MINIDUMP_HEADER);
37 const size_t kModuleListStreamOffset =
38 kDirectoryOffset + sizeof(MINIDUMP_DIRECTORY);
39 const size_t kModulesOffset =
40 kModuleListStreamOffset + sizeof(MINIDUMP_MODULE_LIST);
41
42 ASSERT_GE(file_contents.size(), kModulesOffset);
43
44 const MINIDUMP_HEADER* header =
45 reinterpret_cast<const MINIDUMP_HEADER*>(&file_contents[0]);
46
47 VerifyMinidumpHeader(header, 1, 0);
Robert Sesek 2014/08/12 22:56:05 IWYU
48 if (testing::Test::HasFatalFailure()) {
49 return;
50 }
51
52 const MINIDUMP_DIRECTORY* directory =
53 reinterpret_cast<const MINIDUMP_DIRECTORY*>(
54 &file_contents[kDirectoryOffset]);
55
56 ASSERT_EQ(kMinidumpStreamTypeModuleList, directory->StreamType);
57 ASSERT_GE(directory->Location.DataSize, sizeof(MINIDUMP_MODULE_LIST));
58 ASSERT_EQ(kModuleListStreamOffset, directory->Location.Rva);
59
60 *module_list = reinterpret_cast<const MINIDUMP_MODULE_LIST*>(
61 &file_contents[kModuleListStreamOffset]);
62
63 ASSERT_EQ(sizeof(MINIDUMP_MODULE_LIST) +
64 (*module_list)->NumberOfModules * sizeof(MINIDUMP_MODULE),
65 directory->Location.DataSize);
66 }
67
68 TEST(MinidumpModuleWriter, EmptyModuleList) {
69 MinidumpFileWriter minidump_file_writer;
70 MinidumpModuleListWriter module_list_writer;
71
72 minidump_file_writer.AddStream(&module_list_writer);
73
74 StringFileWriter file_writer;
75 ASSERT_TRUE(minidump_file_writer.WriteEverything(&file_writer));
76
77 ASSERT_EQ(sizeof(MINIDUMP_HEADER) + sizeof(MINIDUMP_DIRECTORY) +
78 sizeof(MINIDUMP_MODULE_LIST),
79 file_writer.string().size());
80
81 const MINIDUMP_MODULE_LIST* module_list;
82 GetModuleListStream(file_writer.string(), &module_list);
83 if (Test::HasFatalFailure()) {
84 return;
85 }
86
87 EXPECT_EQ(0u, module_list->NumberOfModules);
88 }
89
90 // ExpectModule() verifies that |expected| matches |observed|. Fields that are
91 // supposed to contain constant magic numbers are verified against the expected
92 // constants instead of |expected|. Reserved fields are verified to be 0. RVA
93 // and MINIDUMP_LOCATION_DESCRIPTOR fields are not verified against |expected|.
94 // Instead, |ModuleNameRva| is used to locate the module name, which is compared
95 // against |expected_module_name|. If |expected_pdb_name| is non-NULL,
96 // |CvRecord| is used to locate a CodeView record, whose fields are compared
97 // against the |expected_pdb_*| values. If |expected_pdb_uuid| is supplied, the
98 // CodeView record must be a PDB 7.0 link, otherwise, it must be a PDB 2.0 link.
99 // If |expected_pdb_name| is NULL, |CvRecord| must be absent. Similarly,
100 // |expected_debug_name| is used to control verification of |MiscRecord| against
101 // the |expected_debug_*| values.
102 void ExpectModule(const MINIDUMP_MODULE* expected,
103 const MINIDUMP_MODULE* observed,
104 const std::string& file_contents,
105 const char* expected_module_name,
Robert Sesek 2014/08/12 22:56:05 Why const char* for the expected names instead of
Mark Mentovai 2014/08/12 23:23:26 rsesek wrote:
106 const char* expected_pdb_name,
107 const UUID* expected_pdb_uuid,
108 time_t expected_pdb_timestamp,
109 uint32_t expected_pdb_age,
110 const char* expected_debug_name,
111 uint32_t expected_debug_type,
112 bool expected_debug_utf16) {
113 EXPECT_EQ(expected->BaseOfImage, observed->BaseOfImage);
114 EXPECT_EQ(expected->SizeOfImage, observed->SizeOfImage);
115 EXPECT_EQ(expected->CheckSum, observed->CheckSum);
116 EXPECT_EQ(expected->TimeDateStamp, observed->TimeDateStamp);
117 EXPECT_EQ(static_cast<uint32_t>(VS_FFI_SIGNATURE),
118 observed->VersionInfo.dwSignature);
119 EXPECT_EQ(static_cast<uint32_t>(VS_FFI_STRUCVERSION),
120 observed->VersionInfo.dwStrucVersion);
121 EXPECT_EQ(expected->VersionInfo.dwFileVersionMS,
122 observed->VersionInfo.dwFileVersionMS);
123 EXPECT_EQ(expected->VersionInfo.dwFileVersionLS,
124 observed->VersionInfo.dwFileVersionLS);
125 EXPECT_EQ(expected->VersionInfo.dwProductVersionMS,
126 observed->VersionInfo.dwProductVersionMS);
127 EXPECT_EQ(expected->VersionInfo.dwProductVersionLS,
128 observed->VersionInfo.dwProductVersionLS);
129 EXPECT_EQ(expected->VersionInfo.dwFileFlagsMask,
130 observed->VersionInfo.dwFileFlagsMask);
131 EXPECT_EQ(expected->VersionInfo.dwFileFlags,
132 observed->VersionInfo.dwFileFlags);
133 EXPECT_EQ(expected->VersionInfo.dwFileOS, observed->VersionInfo.dwFileOS);
134 EXPECT_EQ(expected->VersionInfo.dwFileType, observed->VersionInfo.dwFileType);
135 EXPECT_EQ(expected->VersionInfo.dwFileSubtype,
136 observed->VersionInfo.dwFileSubtype);
137 EXPECT_EQ(expected->VersionInfo.dwFileDateMS,
138 observed->VersionInfo.dwFileDateMS);
139 EXPECT_EQ(expected->VersionInfo.dwFileDateLS,
140 observed->VersionInfo.dwFileDateLS);
141 EXPECT_EQ(0u, observed->Reserved0);
142 EXPECT_EQ(0u, observed->Reserved1);
143
144 EXPECT_NE(0u, observed->ModuleNameRva);
145 ASSERT_LE(observed->ModuleNameRva,
146 file_contents.size() - sizeof(MINIDUMP_STRING));
147 const MINIDUMP_STRING* module_name = reinterpret_cast<const MINIDUMP_STRING*>(
148 &file_contents[observed->ModuleNameRva]);
149 ASSERT_LE(observed->ModuleNameRva + sizeof(MINIDUMP_STRING) +
150 (module_name->Length + 1),
151 file_contents.size());
152 ASSERT_EQ(0u, module_name->Length % 2);
153 string16 observed_module_name_utf16(
154 reinterpret_cast<const char16*>(
155 &file_contents[observed->ModuleNameRva + sizeof(MINIDUMP_STRING)]),
156 module_name->Length / 2);
157 string16 expected_module_name_utf16 = base::UTF8ToUTF16(expected_module_name);
158 EXPECT_EQ(expected_module_name_utf16, observed_module_name_utf16);
159
160 if (expected_pdb_name) {
Robert Sesek 2014/08/12 22:56:05 If this weren't in a test, this is where I'd tell
Mark Mentovai 2014/08/12 23:23:26 rsesek wrote:
161 EXPECT_NE(0u, observed->CvRecord.Rva);
162 ASSERT_LE(observed->CvRecord.Rva + observed->CvRecord.DataSize,
163 file_contents.size());
164
165 std::string observed_pdb_name;
166 if (expected_pdb_uuid) {
167 // The CodeView record should be a PDB 7.0 link.
168 EXPECT_GE(observed->CvRecord.DataSize,
169 sizeof(MinidumpModuleCodeViewRecordPDB70));
170 const MinidumpModuleCodeViewRecordPDB70* codeview_pdb70_record =
171 reinterpret_cast<const MinidumpModuleCodeViewRecordPDB70*>(
172 &file_contents[observed->CvRecord.Rva]);
173 EXPECT_EQ(MinidumpModuleCodeViewRecordPDB70::kSignature,
174 codeview_pdb70_record->signature);
175 EXPECT_EQ(0,
176 memcmp(expected_pdb_uuid,
177 &codeview_pdb70_record->uuid,
178 sizeof(codeview_pdb70_record->uuid)));
179 EXPECT_EQ(expected_pdb_age, codeview_pdb70_record->age);
180
181 observed_pdb_name.assign(
182 reinterpret_cast<const char*>(&codeview_pdb70_record->pdb_name[0]),
183 observed->CvRecord.DataSize -
184 offsetof(MinidumpModuleCodeViewRecordPDB70, pdb_name));
185 } else {
186 // The CodeView record should be a PDB 2.0 link.
187 EXPECT_GE(observed->CvRecord.DataSize,
188 sizeof(MinidumpModuleCodeViewRecordPDB20));
189 const MinidumpModuleCodeViewRecordPDB20* codeview_pdb20_record =
190 reinterpret_cast<const MinidumpModuleCodeViewRecordPDB20*>(
191 &file_contents[observed->CvRecord.Rva]);
192 EXPECT_EQ(MinidumpModuleCodeViewRecordPDB20::kSignature,
193 codeview_pdb20_record->signature);
194 EXPECT_EQ(expected_pdb_timestamp, codeview_pdb20_record->timestamp);
195 EXPECT_EQ(expected_pdb_age, codeview_pdb20_record->age);
196
197 observed_pdb_name.assign(
198 reinterpret_cast<const char*>(&codeview_pdb20_record->pdb_name[0]),
199 observed->CvRecord.DataSize -
200 offsetof(MinidumpModuleCodeViewRecordPDB20, pdb_name));
201 }
202
203 // Check for, and then remove, the NUL terminator.
204 EXPECT_EQ('\0', observed_pdb_name[observed_pdb_name.size() - 1]);
205 observed_pdb_name.resize(observed_pdb_name.size() - 1);
206
207 EXPECT_EQ(expected_pdb_name, observed_pdb_name);
208 } else {
209 // There should be no CodeView record.
210 EXPECT_EQ(0u, observed->CvRecord.DataSize);
211 EXPECT_EQ(0u, observed->CvRecord.Rva);
212 }
213
214 if (expected_debug_name) {
215 EXPECT_GE(observed->MiscRecord.DataSize, sizeof(IMAGE_DEBUG_MISC));
216 EXPECT_NE(0u, observed->MiscRecord.Rva);
217 ASSERT_LE(observed->MiscRecord.Rva + observed->MiscRecord.DataSize,
218 file_contents.size());
219 const IMAGE_DEBUG_MISC* misc_debug_record =
220 reinterpret_cast<const IMAGE_DEBUG_MISC*>(
221 &file_contents[observed->MiscRecord.Rva]);
222 EXPECT_EQ(expected_debug_type, misc_debug_record->DataType);
223 EXPECT_EQ(observed->MiscRecord.DataSize, misc_debug_record->Length);
224 EXPECT_EQ(expected_debug_utf16, misc_debug_record->Unicode);
225 EXPECT_EQ(0u, misc_debug_record->Reserved[0]);
226 EXPECT_EQ(0u, misc_debug_record->Reserved[1]);
227 EXPECT_EQ(0u, misc_debug_record->Reserved[2]);
228
229 // Check for the NUL terminator.
230 size_t bytes_available =
231 misc_debug_record->Length - offsetof(IMAGE_DEBUG_MISC, Data);
232 EXPECT_EQ('\0', misc_debug_record->Data[bytes_available - 1]);
233 std::string observed_data(
234 reinterpret_cast<const char*>(misc_debug_record->Data));
235
236 size_t bytes_used;
237 if (misc_debug_record->Unicode) {
238 string16 observed_data_utf16(
239 reinterpret_cast<const char16*>(misc_debug_record->Data));
240 bytes_used = (observed_data_utf16.size() + 1) * sizeof(char16);
241 observed_data = base::UTF16ToUTF8(observed_data_utf16);
242 } else {
243 observed_data = reinterpret_cast<const char*>(misc_debug_record->Data);
244 bytes_used = (observed_data.size() + 1) * sizeof(char);
245 }
246 EXPECT_LE(bytes_used, bytes_available);
247
248 // Make sure that any padding bytes after the first NUL are also NUL.
249 for (size_t index = bytes_used; index < bytes_available; ++index) {
250 EXPECT_EQ('\0', misc_debug_record->Data[index]);
251 }
252
253 EXPECT_EQ(expected_debug_name, observed_data);
254 } else {
255 // There should be no miscellaneous debugging record.
256 EXPECT_EQ(0u, observed->MiscRecord.DataSize);
257 EXPECT_EQ(0u, observed->MiscRecord.Rva);
258 }
259 }
260
261 TEST(MinidumpModuleWriter, EmptyModule) {
262 MinidumpFileWriter minidump_file_writer;
263 MinidumpModuleListWriter module_list_writer;
264
265 const char kModuleName[] = "test_executable";
266
267 MinidumpModuleWriter module_writer;
268 module_writer.SetName(kModuleName);
269
270 module_list_writer.AddModule(&module_writer);
271 minidump_file_writer.AddStream(&module_list_writer);
272
273 StringFileWriter file_writer;
274 ASSERT_TRUE(minidump_file_writer.WriteEverything(&file_writer));
275
276 ASSERT_GT(file_writer.string().size(),
277 sizeof(MINIDUMP_HEADER) + sizeof(MINIDUMP_DIRECTORY) +
278 sizeof(MINIDUMP_MODULE_LIST) + 1 * sizeof(MINIDUMP_MODULE));
279
280 const MINIDUMP_MODULE_LIST* module_list;
281 GetModuleListStream(file_writer.string(), &module_list);
282 if (Test::HasFatalFailure()) {
283 return;
284 }
285
286 EXPECT_EQ(1u, module_list->NumberOfModules);
287
288 MINIDUMP_MODULE expected = {};
289 ExpectModule(&expected,
290 &module_list->Modules[0],
291 file_writer.string(),
292 kModuleName,
293 NULL,
294 NULL,
295 0,
296 0,
297 NULL,
298 0,
299 false);
300 if (Test::HasFatalFailure()) {
301 return;
302 }
303 }
304
305 TEST(MinidumpModuleWriter, OneModule) {
306 MinidumpFileWriter minidump_file_writer;
307 MinidumpModuleListWriter module_list_writer;
308
309 const char kModuleName[] = "statically_linked";
310 const uint64_t kModuleBase = 0x000000010da69000ull;
311 const uint32_t kModuleSize = 0x1000;
312 const uint32_t kChecksum = 0x76543210;
313 const time_t kTimestamp = 0x386d4380;
314 const uint32_t kFileVersionMS = 0x00010002;
315 const uint32_t kFileVersionLS = 0x00030004;
316 const uint32_t kProductVersionMS = 0x00050006;
317 const uint32_t kProductVersionLS = 0x00070008;
318 const uint32_t kFileFlagsMask = VS_FF_DEBUG | VS_FF_PRERELEASE |
319 VS_FF_PATCHED | VS_FF_PRIVATEBUILD |
320 VS_FF_INFOINFERRED | VS_FF_SPECIALBUILD;
321 const uint32_t kFileFlags = VS_FF_PRIVATEBUILD | VS_FF_SPECIALBUILD;
322 const uint32_t kFileOS = VOS_DOS;
323 const uint32_t kFileType = VFT_DRV;
324 const uint32_t kFileSubtype = VFT2_DRV_KEYBOARD;
325 const char kPDBName[] = "statical.pdb";
326 const uint8_t kPDBUUIDBytes[16] =
327 {0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
328 0x08, 0x19, 0x2a, 0x3b, 0x4c, 0x5d, 0x6e, 0x7f};
329 UUID pdb_uuid;
330 pdb_uuid.InitializeFromBytes(kPDBUUIDBytes);
331 const uint32_t kPDBAge = 1;
332 const uint32_t kDebugType = IMAGE_DEBUG_MISC_EXENAME;
333 const char kDebugName[] = "statical.dbg";
334 const bool kDebugUTF16 = false;
335
336 MinidumpModuleWriter module_writer;
337 module_writer.SetName(kModuleName);
338 module_writer.SetImageBaseAddress(kModuleBase);
339 module_writer.SetImageSize(kModuleSize);
340 module_writer.SetChecksum(kChecksum);
341 module_writer.SetTimestamp(kTimestamp);
342 module_writer.SetFileVersion(kFileVersionMS >> 16,
343 kFileVersionMS & 0xffff,
344 kFileVersionLS >> 16,
345 kFileVersionLS & 0xffff);
346 module_writer.SetProductVersion(kProductVersionMS >> 16,
347 kProductVersionMS & 0xffff,
348 kProductVersionLS >> 16,
349 kProductVersionLS & 0xffff);
350 module_writer.SetFileFlagsAndMask(kFileFlags, kFileFlagsMask);
351 module_writer.SetFileOS(kFileOS);
352 module_writer.SetFileTypeAndSubtype(kFileType, kFileSubtype);
353
354 MinidumpModuleCodeViewRecordPDB70Writer codeview_pdb70_writer;
355 codeview_pdb70_writer.SetPDBName(kPDBName);
356 codeview_pdb70_writer.SetUUIDAndAge(pdb_uuid, kPDBAge);
357 module_writer.SetCodeViewRecord(&codeview_pdb70_writer);
358
359 MinidumpModuleMiscDebugRecordWriter misc_debug_writer;
360 misc_debug_writer.SetDataType(kDebugType);
361 misc_debug_writer.SetData(kDebugName, kDebugUTF16);
362 module_writer.SetMiscDebugRecord(&misc_debug_writer);
363
364 module_list_writer.AddModule(&module_writer);
365 minidump_file_writer.AddStream(&module_list_writer);
366
367 StringFileWriter file_writer;
368 ASSERT_TRUE(minidump_file_writer.WriteEverything(&file_writer));
369
370 ASSERT_GT(file_writer.string().size(),
371 sizeof(MINIDUMP_HEADER) + sizeof(MINIDUMP_DIRECTORY) +
372 sizeof(MINIDUMP_MODULE_LIST) + 1 * sizeof(MINIDUMP_MODULE));
373
374 const MINIDUMP_MODULE_LIST* module_list;
375 GetModuleListStream(file_writer.string(), &module_list);
376 if (Test::HasFatalFailure()) {
377 return;
378 }
379
380 EXPECT_EQ(1u, module_list->NumberOfModules);
381
382 MINIDUMP_MODULE expected = {};
383 expected.BaseOfImage = kModuleBase;
384 expected.SizeOfImage = kModuleSize;
385 expected.CheckSum = kChecksum;
386 expected.TimeDateStamp = kTimestamp;
387 expected.VersionInfo.dwFileVersionMS = kFileVersionMS;
388 expected.VersionInfo.dwFileVersionLS = kFileVersionLS;
389 expected.VersionInfo.dwProductVersionMS = kProductVersionMS;
390 expected.VersionInfo.dwProductVersionLS = kProductVersionLS;
391 expected.VersionInfo.dwFileFlagsMask = kFileFlagsMask;
392 expected.VersionInfo.dwFileFlags = kFileFlags;
393 expected.VersionInfo.dwFileOS = kFileOS;
394 expected.VersionInfo.dwFileType = kFileType;
395 expected.VersionInfo.dwFileSubtype = kFileSubtype;
396
397 ExpectModule(&expected,
398 &module_list->Modules[0],
399 file_writer.string(),
400 kModuleName,
401 kPDBName,
402 &pdb_uuid,
403 0,
404 kPDBAge,
405 kDebugName,
406 kDebugType,
407 kDebugUTF16);
408 if (Test::HasFatalFailure()) {
409 return;
410 }
411 }
412
413 TEST(MinidumpModuleWriter, OneModule_CodeViewUsesPDB20_MiscUsesUTF16) {
414 // MinidumpModuleWriter.OneModule tested with a PDB 7.0 link as the CodeView
415 // record and an IMAGE_DEBUG_MISC record in UTF-8. This test exercises the
416 // alternatives, a PDB 2.0 link as the CodeView record and an IMAGE_DEBUG_MISC
417 // record with UTF-16 data.
418 MinidumpFileWriter minidump_file_writer;
419 MinidumpModuleListWriter module_list_writer;
420
421 const char kModuleName[] = "dinosaur";
422 const char kPDBName[] = "d1n05.pdb";
423 const time_t kPDBTimestamp = 0x386d4380;
424 const uint32_t kPDBAge = 1;
425 const uint32_t kDebugType = IMAGE_DEBUG_MISC_EXENAME;
426 const char kDebugName[] = "d1n05.dbg";
427 const bool kDebugUTF16 = true;
428
429 MinidumpModuleWriter module_writer;
430 module_writer.SetName(kModuleName);
431
432 MinidumpModuleCodeViewRecordPDB20Writer codeview_pdb20_writer;
433 codeview_pdb20_writer.SetPDBName(kPDBName);
434 codeview_pdb20_writer.SetTimestampAndAge(kPDBTimestamp, kPDBAge);
435 module_writer.SetCodeViewRecord(&codeview_pdb20_writer);
436
437 MinidumpModuleMiscDebugRecordWriter misc_debug_writer;
438 misc_debug_writer.SetDataType(kDebugType);
439 misc_debug_writer.SetData(kDebugName, kDebugUTF16);
440 module_writer.SetMiscDebugRecord(&misc_debug_writer);
441
442 module_list_writer.AddModule(&module_writer);
443 minidump_file_writer.AddStream(&module_list_writer);
444
445 StringFileWriter file_writer;
446 ASSERT_TRUE(minidump_file_writer.WriteEverything(&file_writer));
447
448 ASSERT_GT(file_writer.string().size(),
449 sizeof(MINIDUMP_HEADER) + sizeof(MINIDUMP_DIRECTORY) +
450 sizeof(MINIDUMP_MODULE_LIST) + 1 * sizeof(MINIDUMP_MODULE));
451
452 const MINIDUMP_MODULE_LIST* module_list;
453 GetModuleListStream(file_writer.string(), &module_list);
454 if (Test::HasFatalFailure()) {
455 return;
456 }
457
458 EXPECT_EQ(1u, module_list->NumberOfModules);
459
460 MINIDUMP_MODULE expected = {};
461
462 ExpectModule(&expected,
463 &module_list->Modules[0],
464 file_writer.string(),
465 kModuleName,
466 kPDBName,
467 NULL,
468 kPDBTimestamp,
469 kPDBAge,
470 kDebugName,
471 kDebugType,
472 kDebugUTF16);
473 if (Test::HasFatalFailure()) {
474 return;
475 }
476 }
477
478 TEST(MinidumpModuleWriter, ThreeModules) {
479 MinidumpFileWriter minidump_file_writer;
480 MinidumpModuleListWriter module_list_writer;
481
482 const char kModuleName1[] = "main";
483 const uint64_t kModuleBase1 = 0x0000000100101000ull;
484 const uint32_t kModuleSize1 = 0xf000;
485 const char kPDBName1[] = "main";
486 const uint8_t kPDBUUIDBytes1[16] =
487 {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11,
488 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99};
489 UUID pdb_uuid_1;
490 pdb_uuid_1.InitializeFromBytes(kPDBUUIDBytes1);
491 const uint32_t kPDBAge1 = 0;
492
493 const char kModuleName2[] = "ld.so";
494 const uint64_t kModuleBase2 = 0x0000000200202000ull;
495 const uint32_t kModuleSize2 = 0x1e000;
496
497 const char kModuleName3[] = "libc.so";
498 const uint64_t kModuleBase3 = 0x0000000300303000ull;
499 const uint32_t kModuleSize3 = 0x2d000;
500 const char kPDBName3[] = "libc.so";
501 const uint8_t kPDBUUIDBytes3[16] =
502 {0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0, 0x90, 0x80,
503 0x70, 0x60, 0x50, 0x40, 0x30, 0x20, 0x10, 0x00};
504 UUID pdb_uuid_3;
505 pdb_uuid_3.InitializeFromBytes(kPDBUUIDBytes3);
506 const uint32_t kPDBAge3 = 0;
507
508 MinidumpModuleWriter module_writer_1;
509 module_writer_1.SetName(kModuleName1);
510 module_writer_1.SetImageBaseAddress(kModuleBase1);
511 module_writer_1.SetImageSize(kModuleSize1);
512
513 MinidumpModuleCodeViewRecordPDB70Writer codeview_pdb70_writer_1;
514 codeview_pdb70_writer_1.SetPDBName(kPDBName1);
515 codeview_pdb70_writer_1.SetUUIDAndAge(pdb_uuid_1, kPDBAge1);
516 module_writer_1.SetCodeViewRecord(&codeview_pdb70_writer_1);
517
518 module_list_writer.AddModule(&module_writer_1);
519
520 MinidumpModuleWriter module_writer_2;
521 module_writer_2.SetName(kModuleName2);
522 module_writer_2.SetImageBaseAddress(kModuleBase2);
523 module_writer_2.SetImageSize(kModuleSize2);
524
525 module_list_writer.AddModule(&module_writer_2);
526
527 MinidumpModuleWriter module_writer_3;
528 module_writer_3.SetName(kModuleName3);
529 module_writer_3.SetImageBaseAddress(kModuleBase3);
530 module_writer_3.SetImageSize(kModuleSize3);
531
532 MinidumpModuleCodeViewRecordPDB70Writer codeview_pdb70_writer_3;
533 codeview_pdb70_writer_3.SetPDBName(kPDBName3);
534 codeview_pdb70_writer_3.SetUUIDAndAge(pdb_uuid_3, kPDBAge3);
535 module_writer_3.SetCodeViewRecord(&codeview_pdb70_writer_3);
536
537 module_list_writer.AddModule(&module_writer_3);
538
539 minidump_file_writer.AddStream(&module_list_writer);
540
541 StringFileWriter file_writer;
542 ASSERT_TRUE(minidump_file_writer.WriteEverything(&file_writer));
543
544 ASSERT_GT(file_writer.string().size(),
545 sizeof(MINIDUMP_HEADER) + sizeof(MINIDUMP_DIRECTORY) +
546 sizeof(MINIDUMP_MODULE_LIST) + 1 * sizeof(MINIDUMP_MODULE));
547
548 const MINIDUMP_MODULE_LIST* module_list;
549 GetModuleListStream(file_writer.string(), &module_list);
550 if (Test::HasFatalFailure()) {
551 return;
552 }
553
554 EXPECT_EQ(3u, module_list->NumberOfModules);
555
556 MINIDUMP_MODULE expected = {};
557
558 {
559 SCOPED_TRACE("module 0");
560
561 expected.BaseOfImage = kModuleBase1;
562 expected.SizeOfImage = kModuleSize1;
563
564 ExpectModule(&expected,
565 &module_list->Modules[0],
566 file_writer.string(),
567 kModuleName1,
568 kPDBName1,
569 &pdb_uuid_1,
570 0,
571 kPDBAge1,
572 NULL,
573 0,
574 false);
575 if (Test::HasFatalFailure()) {
576 return;
577 }
578 }
579
580 {
581 SCOPED_TRACE("module 1");
582
583 expected.BaseOfImage = kModuleBase2;
584 expected.SizeOfImage = kModuleSize2;
585
586 ExpectModule(&expected,
587 &module_list->Modules[1],
588 file_writer.string(),
589 kModuleName2,
590 NULL,
591 NULL,
592 0,
593 0,
594 NULL,
595 0,
596 false);
597 if (Test::HasFatalFailure()) {
598 return;
599 }
600 }
601
602 {
603 SCOPED_TRACE("module 2");
604
605 expected.BaseOfImage = kModuleBase3;
606 expected.SizeOfImage = kModuleSize3;
607
608 ExpectModule(&expected,
609 &module_list->Modules[2],
610 file_writer.string(),
611 kModuleName3,
612 kPDBName3,
613 &pdb_uuid_3,
614 0,
615 kPDBAge3,
616 NULL,
617 0,
618 false);
619 if (Test::HasFatalFailure()) {
620 return;
621 }
622 }
623 }
624
Robert Sesek 2014/08/12 22:56:05 I assume you can mix and match modules with differ
Mark Mentovai 2014/08/12 23:23:26 rsesek wrote:
625 TEST(MinidumpSystemInfoWriterDeathTest, NoModuleName) {
626 MinidumpFileWriter minidump_file_writer;
627 MinidumpModuleListWriter module_list_writer;
628 MinidumpModuleWriter module_writer;
629 module_list_writer.AddModule(&module_writer);
630 minidump_file_writer.AddStream(&module_list_writer);
631
632 StringFileWriter file_writer;
633 ASSERT_DEATH(minidump_file_writer.WriteEverything(&file_writer), "name_");
634 }
635
636 } // namespace
OLDNEW
« minidump/minidump_module_writer.h ('K') | « minidump/minidump_module_writer.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698