OLD | NEW |
1 // Copyright (c) 2010, Google Inc. | 1 // Copyright (c) 2010, Google Inc. |
2 // All rights reserved. | 2 // All rights reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are |
6 // met: | 6 // met: |
7 // | 7 // |
8 // * Redistributions of source code must retain the above copyright | 8 // * Redistributions of source code must retain the above copyright |
9 // notice, this list of conditions and the following disclaimer. | 9 // notice, this list of conditions and the following disclaimer. |
10 // * Redistributions in binary form must reproduce the above | 10 // * Redistributions in binary form must reproduce the above |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
56 using google_breakpad::MinidumpModule; | 56 using google_breakpad::MinidumpModule; |
57 using google_breakpad::MinidumpModuleList; | 57 using google_breakpad::MinidumpModuleList; |
58 using google_breakpad::MinidumpSystemInfo; | 58 using google_breakpad::MinidumpSystemInfo; |
59 using google_breakpad::MinidumpThread; | 59 using google_breakpad::MinidumpThread; |
60 using google_breakpad::MinidumpThreadList; | 60 using google_breakpad::MinidumpThreadList; |
61 using google_breakpad::SynthMinidump::Context; | 61 using google_breakpad::SynthMinidump::Context; |
62 using google_breakpad::SynthMinidump::Dump; | 62 using google_breakpad::SynthMinidump::Dump; |
63 using google_breakpad::SynthMinidump::Exception; | 63 using google_breakpad::SynthMinidump::Exception; |
64 using google_breakpad::SynthMinidump::Memory; | 64 using google_breakpad::SynthMinidump::Memory; |
65 using google_breakpad::SynthMinidump::Module; | 65 using google_breakpad::SynthMinidump::Module; |
| 66 using google_breakpad::SynthMinidump::Section; |
66 using google_breakpad::SynthMinidump::Stream; | 67 using google_breakpad::SynthMinidump::Stream; |
67 using google_breakpad::SynthMinidump::String; | 68 using google_breakpad::SynthMinidump::String; |
68 using google_breakpad::SynthMinidump::SystemInfo; | 69 using google_breakpad::SynthMinidump::SystemInfo; |
69 using google_breakpad::SynthMinidump::Thread; | 70 using google_breakpad::SynthMinidump::Thread; |
70 using google_breakpad::test_assembler::kBigEndian; | 71 using google_breakpad::test_assembler::kBigEndian; |
71 using google_breakpad::test_assembler::kLittleEndian; | 72 using google_breakpad::test_assembler::kLittleEndian; |
72 using std::ifstream; | 73 using std::ifstream; |
73 using std::istringstream; | 74 using std::istringstream; |
74 using std::vector; | 75 using std::vector; |
75 using ::testing::Return; | 76 using ::testing::Return; |
76 | 77 |
77 class MinidumpTest : public ::testing::Test { | 78 class MinidumpTest : public ::testing::Test { |
78 public: | 79 public: |
79 void SetUp() { | 80 void SetUp() { |
80 minidump_file_ = string(getenv("srcdir") ? getenv("srcdir") : ".") + | 81 minidump_file_ = string(getenv("srcdir") ? getenv("srcdir") : ".") + |
81 "/src/processor/testdata/minidump2.dmp"; | 82 "/src/processor/testdata/minidump2.dmp"; |
82 } | 83 } |
83 string minidump_file_; | 84 string minidump_file_; |
84 }; | 85 }; |
85 | 86 |
86 TEST_F(MinidumpTest, TestMinidumpFromFile) { | 87 TEST_F(MinidumpTest, TestMinidumpFromFile) { |
87 Minidump minidump(minidump_file_); | 88 Minidump minidump(minidump_file_); |
88 ASSERT_EQ(minidump.path(), minidump_file_); | 89 ASSERT_EQ(minidump.path(), minidump_file_); |
89 ASSERT_TRUE(minidump.Read()); | 90 ASSERT_TRUE(minidump.Read()); |
90 const MDRawHeader* header = minidump.header(); | 91 const MDRawHeader* header = minidump.header(); |
91 ASSERT_NE(header, (MDRawHeader*)NULL); | 92 ASSERT_NE(header, (MDRawHeader*)NULL); |
92 ASSERT_EQ(header->signature, uint32_t(MD_HEADER_SIGNATURE)); | 93 ASSERT_EQ(header->signature, uint32_t(MD_HEADER_SIGNATURE)); |
93 //TODO: add more checks here | 94 |
| 95 MinidumpModuleList *md_module_list = minidump.GetModuleList(); |
| 96 ASSERT_TRUE(md_module_list != NULL); |
| 97 const MinidumpModule *md_module = md_module_list->GetModuleAtIndex(0); |
| 98 ASSERT_TRUE(md_module != NULL); |
| 99 ASSERT_EQ("c:\\test_app.exe", md_module->code_file()); |
| 100 ASSERT_EQ("c:\\test_app.pdb", md_module->debug_file()); |
| 101 ASSERT_EQ("45D35F6C2d000", md_module->code_identifier()); |
| 102 ASSERT_EQ("5A9832E5287241C1838ED98914E9B7FF1", md_module->debug_identifier()); |
94 } | 103 } |
95 | 104 |
96 TEST_F(MinidumpTest, TestMinidumpFromStream) { | 105 TEST_F(MinidumpTest, TestMinidumpFromStream) { |
97 // read minidump contents into memory, construct a stringstream around them | 106 // read minidump contents into memory, construct a stringstream around them |
98 ifstream file_stream(minidump_file_.c_str(), std::ios::in); | 107 ifstream file_stream(minidump_file_.c_str(), std::ios::in); |
99 ASSERT_TRUE(file_stream.good()); | 108 ASSERT_TRUE(file_stream.good()); |
100 vector<char> bytes; | 109 vector<char> bytes; |
101 file_stream.seekg(0, std::ios_base::end); | 110 file_stream.seekg(0, std::ios_base::end); |
102 ASSERT_TRUE(file_stream.good()); | 111 ASSERT_TRUE(file_stream.good()); |
103 bytes.resize(file_stream.tellg()); | 112 bytes.resize(file_stream.tellg()); |
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
378 uint32_t thread_id; | 387 uint32_t thread_id; |
379 ASSERT_TRUE(md_thread->GetThreadID(&thread_id)); | 388 ASSERT_TRUE(md_thread->GetThreadID(&thread_id)); |
380 ASSERT_EQ(0xa898f11bU, thread_id); | 389 ASSERT_EQ(0xa898f11bU, thread_id); |
381 MinidumpMemoryRegion* md_stack = md_thread->GetMemory(); | 390 MinidumpMemoryRegion* md_stack = md_thread->GetMemory(); |
382 ASSERT_NE(reinterpret_cast<MinidumpMemoryRegion*>(NULL), md_stack); | 391 ASSERT_NE(reinterpret_cast<MinidumpMemoryRegion*>(NULL), md_stack); |
383 | 392 |
384 MinidumpContext* md_context = md_thread->GetContext(); | 393 MinidumpContext* md_context = md_thread->GetContext(); |
385 ASSERT_EQ(reinterpret_cast<MinidumpContext*>(NULL), md_context); | 394 ASSERT_EQ(reinterpret_cast<MinidumpContext*>(NULL), md_context); |
386 } | 395 } |
387 | 396 |
| 397 static const MDVSFixedFileInfo fixed_file_info = { |
| 398 0xb2fba33a, // signature |
| 399 0x33d7a728, // struct_version |
| 400 0x31afcb20, // file_version_hi |
| 401 0xe51cdab1, // file_version_lo |
| 402 0xd1ea6907, // product_version_hi |
| 403 0x03032857, // product_version_lo |
| 404 0x11bf71d7, // file_flags_mask |
| 405 0x5fb8cdbf, // file_flags |
| 406 0xe45d0d5d, // file_os |
| 407 0x107d9562, // file_type |
| 408 0x5a8844d4, // file_subtype |
| 409 0xa8d30b20, // file_date_hi |
| 410 0x651c3e4e // file_date_lo |
| 411 }; |
| 412 |
388 TEST(Dump, OneModule) { | 413 TEST(Dump, OneModule) { |
389 static const MDVSFixedFileInfo fixed_file_info = { | |
390 0xb2fba33a, // signature | |
391 0x33d7a728, // struct_version | |
392 0x31afcb20, // file_version_hi | |
393 0xe51cdab1, // file_version_lo | |
394 0xd1ea6907, // product_version_hi | |
395 0x03032857, // product_version_lo | |
396 0x11bf71d7, // file_flags_mask | |
397 0x5fb8cdbf, // file_flags | |
398 0xe45d0d5d, // file_os | |
399 0x107d9562, // file_type | |
400 0x5a8844d4, // file_subtype | |
401 0xa8d30b20, // file_date_hi | |
402 0x651c3e4e // file_date_lo | |
403 }; | |
404 | |
405 Dump dump(0, kBigEndian); | 414 Dump dump(0, kBigEndian); |
406 String module_name(dump, "single module"); | 415 String module_name(dump, "single module"); |
| 416 Section cv_info(dump); |
| 417 cv_info |
| 418 .D32(MD_CVINFOPDB70_SIGNATURE) // signature |
| 419 // signature, a MDGUID |
| 420 .D32(0xabcd1234) |
| 421 .D16(0xf00d) |
| 422 .D16(0xbeef) |
| 423 .Append("\x01\x02\x03\x04\x05\x06\x07\x08") |
| 424 .D32(1) // age |
| 425 .AppendCString("c:\\foo\\file.pdb"); // pdb_file_name |
| 426 |
| 427 String csd_version(dump, "Windows 9000"); |
| 428 SystemInfo system_info(dump, SystemInfo::windows_x86, csd_version); |
| 429 |
407 Module module(dump, 0xa90206ca83eb2852ULL, 0xada542bd, | 430 Module module(dump, 0xa90206ca83eb2852ULL, 0xada542bd, |
408 module_name, | 431 module_name, |
409 0xb1054d2a, | 432 0xb1054d2a, |
410 0x34571371, | 433 0x34571371, |
411 fixed_file_info, // from synth_minidump_unittest_data.h | 434 fixed_file_info, // from synth_minidump_unittest_data.h |
412 NULL, NULL); | 435 &cv_info, nullptr); |
413 | 436 |
414 dump.Add(&module); | 437 dump.Add(&module); |
415 dump.Add(&module_name); | 438 dump.Add(&module_name); |
| 439 dump.Add(&cv_info); |
| 440 dump.Add(&system_info); |
| 441 dump.Add(&csd_version); |
416 dump.Finish(); | 442 dump.Finish(); |
417 | 443 |
418 string contents; | 444 string contents; |
419 ASSERT_TRUE(dump.GetContents(&contents)); | 445 ASSERT_TRUE(dump.GetContents(&contents)); |
420 istringstream minidump_stream(contents); | 446 istringstream minidump_stream(contents); |
421 Minidump minidump(minidump_stream); | 447 Minidump minidump(minidump_stream); |
422 ASSERT_TRUE(minidump.Read()); | 448 ASSERT_TRUE(minidump.Read()); |
423 ASSERT_EQ(1U, minidump.GetDirectoryEntryCount()); | 449 ASSERT_EQ(2U, minidump.GetDirectoryEntryCount()); |
424 | 450 |
425 const MDRawDirectory *dir = minidump.GetDirectoryEntryAtIndex(0); | 451 const MDRawDirectory *dir = minidump.GetDirectoryEntryAtIndex(1); |
426 ASSERT_TRUE(dir != NULL); | 452 ASSERT_TRUE(dir != NULL); |
427 EXPECT_EQ((uint32_t) MD_MODULE_LIST_STREAM, dir->stream_type); | 453 EXPECT_EQ((uint32_t) MD_MODULE_LIST_STREAM, dir->stream_type); |
428 | 454 |
429 MinidumpModuleList *md_module_list = minidump.GetModuleList(); | 455 MinidumpModuleList *md_module_list = minidump.GetModuleList(); |
430 ASSERT_TRUE(md_module_list != NULL); | 456 ASSERT_TRUE(md_module_list != NULL); |
431 ASSERT_EQ(1U, md_module_list->module_count()); | 457 ASSERT_EQ(1U, md_module_list->module_count()); |
432 | 458 |
433 const MinidumpModule *md_module = md_module_list->GetModuleAtIndex(0); | 459 const MinidumpModule *md_module = md_module_list->GetModuleAtIndex(0); |
434 ASSERT_TRUE(md_module != NULL); | 460 ASSERT_TRUE(md_module != NULL); |
435 ASSERT_EQ(0xa90206ca83eb2852ULL, md_module->base_address()); | 461 ASSERT_EQ(0xa90206ca83eb2852ULL, md_module->base_address()); |
436 ASSERT_EQ(0xada542bd, md_module->size()); | 462 ASSERT_EQ(0xada542bd, md_module->size()); |
437 ASSERT_EQ("single module", md_module->code_file()); | 463 ASSERT_EQ("single module", md_module->code_file()); |
| 464 ASSERT_EQ("c:\\foo\\file.pdb", md_module->debug_file()); |
| 465 // time_date_stamp and size_of_image concatenated |
| 466 ASSERT_EQ("B1054D2Aada542bd", md_module->code_identifier()); |
| 467 ASSERT_EQ("ABCD1234F00DBEEF01020304050607081", md_module->debug_identifier()); |
438 | 468 |
439 const MDRawModule *md_raw_module = md_module->module(); | 469 const MDRawModule *md_raw_module = md_module->module(); |
440 ASSERT_TRUE(md_raw_module != NULL); | 470 ASSERT_TRUE(md_raw_module != NULL); |
441 ASSERT_EQ(0xb1054d2aU, md_raw_module->time_date_stamp); | 471 ASSERT_EQ(0xb1054d2aU, md_raw_module->time_date_stamp); |
442 ASSERT_EQ(0x34571371U, md_raw_module->checksum); | 472 ASSERT_EQ(0x34571371U, md_raw_module->checksum); |
443 ASSERT_TRUE(memcmp(&md_raw_module->version_info, &fixed_file_info, | 473 ASSERT_TRUE(memcmp(&md_raw_module->version_info, &fixed_file_info, |
444 sizeof(fixed_file_info)) == 0); | 474 sizeof(fixed_file_info)) == 0); |
445 } | 475 } |
446 | 476 |
| 477 // Test that a module with a MDCVInfoELF CV record is handled properly. |
| 478 TEST(Dump, OneModuleCVELF) { |
| 479 Dump dump(0, kLittleEndian); |
| 480 String module_name(dump, "elf module"); |
| 481 Section cv_info(dump); |
| 482 cv_info |
| 483 .D32(MD_CVINFOELF_SIGNATURE) // signature |
| 484 // build_id |
| 485 .Append("\x5f\xa9\xcd\xb4\x10\x53\xdf\x1b\x86\xfa\xb7\x33\xb4\xdf" |
| 486 "\x37\x38\xce\xa3\x4a\x87"); |
| 487 |
| 488 const MDRawSystemInfo linux_x86 = { |
| 489 MD_CPU_ARCHITECTURE_X86, // processor_architecture |
| 490 6, // processor_level |
| 491 0xd08, // processor_revision |
| 492 1, // number_of_processors |
| 493 0, // product_type |
| 494 0, // major_version |
| 495 0, // minor_version |
| 496 0, // build_number |
| 497 MD_OS_LINUX, // platform_id |
| 498 0xdeadbeef, // csd_version_rva |
| 499 0x100, // suite_mask |
| 500 0, // reserved2 |
| 501 { // cpu |
| 502 { // x86_cpu_info |
| 503 { 0x756e6547, 0x49656e69, 0x6c65746e }, // vendor_id |
| 504 0x6d8, // version_information |
| 505 0xafe9fbff, // feature_information |
| 506 0xffffffff // amd_extended_cpu_features |
| 507 } |
| 508 } |
| 509 }; |
| 510 String csd_version(dump, "Literally Linux"); |
| 511 SystemInfo system_info(dump, linux_x86, csd_version); |
| 512 |
| 513 Module module(dump, 0xa90206ca83eb2852ULL, 0xada542bd, |
| 514 module_name, |
| 515 0xb1054d2a, |
| 516 0x34571371, |
| 517 fixed_file_info, // from synth_minidump_unittest_data.h |
| 518 &cv_info, nullptr); |
| 519 |
| 520 dump.Add(&module); |
| 521 dump.Add(&module_name); |
| 522 dump.Add(&cv_info); |
| 523 dump.Add(&system_info); |
| 524 dump.Add(&csd_version); |
| 525 dump.Finish(); |
| 526 |
| 527 string contents; |
| 528 ASSERT_TRUE(dump.GetContents(&contents)); |
| 529 istringstream minidump_stream(contents); |
| 530 Minidump minidump(minidump_stream); |
| 531 ASSERT_TRUE(minidump.Read()); |
| 532 |
| 533 MinidumpModuleList *md_module_list = minidump.GetModuleList(); |
| 534 ASSERT_TRUE(md_module_list != NULL); |
| 535 ASSERT_EQ(1U, md_module_list->module_count()); |
| 536 |
| 537 const MinidumpModule *md_module = md_module_list->GetModuleAtIndex(0); |
| 538 ASSERT_TRUE(md_module != NULL); |
| 539 ASSERT_EQ(0xa90206ca83eb2852ULL, md_module->base_address()); |
| 540 ASSERT_EQ(0xada542bd, md_module->size()); |
| 541 ASSERT_EQ("elf module", md_module->code_file()); |
| 542 // debug_file == code_file |
| 543 ASSERT_EQ("elf module", md_module->debug_file()); |
| 544 // just the build_id, directly |
| 545 ASSERT_EQ("5fa9cdb41053df1b86fab733b4df3738cea34a87", |
| 546 md_module->code_identifier()); |
| 547 // build_id truncted to GUID length and treated as such, with zero |
| 548 // age appended |
| 549 ASSERT_EQ("B4CDA95F53101BDF86FAB733B4DF37380", md_module->debug_identifier()); |
| 550 |
| 551 const MDRawModule *md_raw_module = md_module->module(); |
| 552 ASSERT_TRUE(md_raw_module != NULL); |
| 553 ASSERT_EQ(0xb1054d2aU, md_raw_module->time_date_stamp); |
| 554 ASSERT_EQ(0x34571371U, md_raw_module->checksum); |
| 555 ASSERT_TRUE(memcmp(&md_raw_module->version_info, &fixed_file_info, |
| 556 sizeof(fixed_file_info)) == 0); |
| 557 } |
| 558 |
| 559 // Test that a build_id that's shorter than a GUID is handled properly. |
| 560 TEST(Dump, CVELFShort) { |
| 561 Dump dump(0, kLittleEndian); |
| 562 String module_name(dump, "elf module"); |
| 563 Section cv_info(dump); |
| 564 cv_info |
| 565 .D32(MD_CVINFOELF_SIGNATURE) // signature |
| 566 // build_id, shorter than a GUID |
| 567 .Append("\x5f\xa9\xcd\xb4"); |
| 568 |
| 569 const MDRawSystemInfo linux_x86 = { |
| 570 MD_CPU_ARCHITECTURE_X86, // processor_architecture |
| 571 6, // processor_level |
| 572 0xd08, // processor_revision |
| 573 1, // number_of_processors |
| 574 0, // product_type |
| 575 0, // major_version |
| 576 0, // minor_version |
| 577 0, // build_number |
| 578 MD_OS_LINUX, // platform_id |
| 579 0xdeadbeef, // csd_version_rva |
| 580 0x100, // suite_mask |
| 581 0, // reserved2 |
| 582 { // cpu |
| 583 { // x86_cpu_info |
| 584 { 0x756e6547, 0x49656e69, 0x6c65746e }, // vendor_id |
| 585 0x6d8, // version_information |
| 586 0xafe9fbff, // feature_information |
| 587 0xffffffff // amd_extended_cpu_features |
| 588 } |
| 589 } |
| 590 }; |
| 591 String csd_version(dump, "Literally Linux"); |
| 592 SystemInfo system_info(dump, linux_x86, csd_version); |
| 593 |
| 594 Module module(dump, 0xa90206ca83eb2852ULL, 0xada542bd, |
| 595 module_name, |
| 596 0xb1054d2a, |
| 597 0x34571371, |
| 598 fixed_file_info, // from synth_minidump_unittest_data.h |
| 599 &cv_info, nullptr); |
| 600 |
| 601 dump.Add(&module); |
| 602 dump.Add(&module_name); |
| 603 dump.Add(&cv_info); |
| 604 dump.Add(&system_info); |
| 605 dump.Add(&csd_version); |
| 606 dump.Finish(); |
| 607 |
| 608 string contents; |
| 609 ASSERT_TRUE(dump.GetContents(&contents)); |
| 610 istringstream minidump_stream(contents); |
| 611 Minidump minidump(minidump_stream); |
| 612 ASSERT_TRUE(minidump.Read()); |
| 613 ASSERT_EQ(2U, minidump.GetDirectoryEntryCount()); |
| 614 |
| 615 MinidumpModuleList *md_module_list = minidump.GetModuleList(); |
| 616 ASSERT_TRUE(md_module_list != NULL); |
| 617 ASSERT_EQ(1U, md_module_list->module_count()); |
| 618 |
| 619 const MinidumpModule *md_module = md_module_list->GetModuleAtIndex(0); |
| 620 ASSERT_TRUE(md_module != NULL); |
| 621 // just the build_id, directly |
| 622 ASSERT_EQ("5fa9cdb4", md_module->code_identifier()); |
| 623 // build_id expanded to GUID length and treated as such, with zero |
| 624 // age appended |
| 625 ASSERT_EQ("B4CDA95F0000000000000000000000000", md_module->debug_identifier()); |
| 626 } |
| 627 |
447 TEST(Dump, OneSystemInfo) { | 628 TEST(Dump, OneSystemInfo) { |
448 Dump dump(0, kLittleEndian); | 629 Dump dump(0, kLittleEndian); |
449 String csd_version(dump, "Petulant Pierogi"); | 630 String csd_version(dump, "Petulant Pierogi"); |
450 SystemInfo system_info(dump, SystemInfo::windows_x86, csd_version); | 631 SystemInfo system_info(dump, SystemInfo::windows_x86, csd_version); |
451 | 632 |
452 dump.Add(&system_info); | 633 dump.Add(&system_info); |
453 dump.Add(&csd_version); | 634 dump.Add(&csd_version); |
454 dump.Finish(); | 635 dump.Finish(); |
455 | 636 |
456 string contents; | 637 string contents; |
(...skipping 800 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1257 EXPECT_EQ(0x1e2db2ceU, raw_context.iregs[25]); | 1438 EXPECT_EQ(0x1e2db2ceU, raw_context.iregs[25]); |
1258 EXPECT_EQ(0xaaa4659cU, raw_context.iregs[26]); | 1439 EXPECT_EQ(0xaaa4659cU, raw_context.iregs[26]); |
1259 EXPECT_EQ(0xd0c0f0e0U, raw_context.iregs[27]); | 1440 EXPECT_EQ(0xd0c0f0e0U, raw_context.iregs[27]); |
1260 EXPECT_EQ(0xc7d6a9b8U, raw_context.iregs[28]); | 1441 EXPECT_EQ(0xc7d6a9b8U, raw_context.iregs[28]); |
1261 EXPECT_EQ(0x56781234U, raw_context.iregs[29]); | 1442 EXPECT_EQ(0x56781234U, raw_context.iregs[29]); |
1262 EXPECT_EQ(0x1234abcdU, raw_context.iregs[30]); | 1443 EXPECT_EQ(0x1234abcdU, raw_context.iregs[30]); |
1263 EXPECT_EQ(0x30401020U, raw_context.iregs[31]); | 1444 EXPECT_EQ(0x30401020U, raw_context.iregs[31]); |
1264 } | 1445 } |
1265 | 1446 |
1266 } // namespace | 1447 } // namespace |
OLD | NEW |