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

Side by Side Diff: minidump/minidump_thread_writer_test.cc

Issue 1364803004: win: Save contents of TEBs allowing !teb and !gle to work in windbg (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@dump-without-crashing
Patch Set: . Created 5 years, 2 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
« no previous file with comments | « minidump/minidump_thread_writer.cc ('k') | snapshot/test/test_process_snapshot.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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_thread_writer.h" 15 #include "minidump/minidump_thread_writer.h"
16 16
17 #include <windows.h> 17 #include <windows.h>
18 #include <dbghelp.h> 18 #include <dbghelp.h>
19 #include <sys/types.h> 19 #include <sys/types.h>
20 20
21 #include <string>
22
21 #include "base/compiler_specific.h" 23 #include "base/compiler_specific.h"
22 #include "base/format_macros.h" 24 #include "base/format_macros.h"
23 #include "base/strings/stringprintf.h" 25 #include "base/strings/stringprintf.h"
24 #include "gtest/gtest.h" 26 #include "gtest/gtest.h"
25 #include "minidump/minidump_context_writer.h" 27 #include "minidump/minidump_context_writer.h"
26 #include "minidump/minidump_memory_writer.h" 28 #include "minidump/minidump_memory_writer.h"
27 #include "minidump/minidump_file_writer.h" 29 #include "minidump/minidump_file_writer.h"
28 #include "minidump/minidump_thread_id_map.h" 30 #include "minidump/minidump_thread_id_map.h"
29 #include "minidump/test/minidump_context_test_util.h" 31 #include "minidump/test/minidump_context_test_util.h"
30 #include "minidump/test/minidump_memory_writer_test_util.h" 32 #include "minidump/test/minidump_memory_writer_test_util.h"
(...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after
520 } 522 }
521 }; 523 };
522 524
523 template <typename Traits> 525 template <typename Traits>
524 void RunInitializeFromSnapshotTest(bool thread_id_collision) { 526 void RunInitializeFromSnapshotTest(bool thread_id_collision) {
525 using MinidumpContextType = typename Traits::MinidumpContextType; 527 using MinidumpContextType = typename Traits::MinidumpContextType;
526 MINIDUMP_THREAD expect_threads[3] = {}; 528 MINIDUMP_THREAD expect_threads[3] = {};
527 uint64_t thread_ids[arraysize(expect_threads)] = {}; 529 uint64_t thread_ids[arraysize(expect_threads)] = {};
528 uint8_t memory_values[arraysize(expect_threads)] = {}; 530 uint8_t memory_values[arraysize(expect_threads)] = {};
529 uint32_t context_seeds[arraysize(expect_threads)] = {}; 531 uint32_t context_seeds[arraysize(expect_threads)] = {};
532 MINIDUMP_MEMORY_DESCRIPTOR tebs[arraysize(expect_threads)] = {};
533
534 const size_t kTebSize = 1024;
530 535
531 expect_threads[0].ThreadId = 1; 536 expect_threads[0].ThreadId = 1;
532 expect_threads[0].SuspendCount = 2; 537 expect_threads[0].SuspendCount = 2;
533 expect_threads[0].Priority = 3; 538 expect_threads[0].Priority = 3;
534 expect_threads[0].Teb = 0x0123456789abcdef; 539 expect_threads[0].Teb = 0x0123456789abcdef;
535 expect_threads[0].Stack.StartOfMemoryRange = 0x1000; 540 expect_threads[0].Stack.StartOfMemoryRange = 0x1000;
536 expect_threads[0].Stack.Memory.DataSize = 0x100; 541 expect_threads[0].Stack.Memory.DataSize = 0x100;
537 expect_threads[0].ThreadContext.DataSize = sizeof(MinidumpContextType); 542 expect_threads[0].ThreadContext.DataSize = sizeof(MinidumpContextType);
538 memory_values[0] = 'A'; 543 memory_values[0] = 'A';
539 context_seeds[0] = 0x80000000; 544 context_seeds[0] = 0x80000000;
545 tebs[0].StartOfMemoryRange = expect_threads[0].Teb;
546 tebs[0].Memory.DataSize = kTebSize;
540 547
541 // The thread at index 1 has no stack. 548 // The thread at index 1 has no stack.
542 expect_threads[1].ThreadId = 11; 549 expect_threads[1].ThreadId = 11;
543 expect_threads[1].SuspendCount = 12; 550 expect_threads[1].SuspendCount = 12;
544 expect_threads[1].Priority = 13; 551 expect_threads[1].Priority = 13;
545 expect_threads[1].Teb = 0xfedcba9876543210; 552 expect_threads[1].Teb = 0xfedcba9876543210;
546 expect_threads[1].ThreadContext.DataSize = sizeof(MinidumpContextType); 553 expect_threads[1].ThreadContext.DataSize = sizeof(MinidumpContextType);
547 context_seeds[1] = 0x40000001; 554 context_seeds[1] = 0x40000001;
555 tebs[1].StartOfMemoryRange = expect_threads[1].Teb;
556 tebs[1].Memory.DataSize = kTebSize;
548 557
549 expect_threads[2].ThreadId = 21; 558 expect_threads[2].ThreadId = 21;
550 expect_threads[2].SuspendCount = 22; 559 expect_threads[2].SuspendCount = 22;
551 expect_threads[2].Priority = 23; 560 expect_threads[2].Priority = 23;
552 expect_threads[2].Teb = 0x1111111111111111; 561 expect_threads[2].Teb = 0x1111111111111111;
553 expect_threads[2].Stack.StartOfMemoryRange = 0x3000; 562 expect_threads[2].Stack.StartOfMemoryRange = 0x3000;
554 expect_threads[2].Stack.Memory.DataSize = 0x300; 563 expect_threads[2].Stack.Memory.DataSize = 0x300;
555 expect_threads[2].ThreadContext.DataSize = sizeof(MinidumpContextType); 564 expect_threads[2].ThreadContext.DataSize = sizeof(MinidumpContextType);
556 memory_values[2] = 'd'; 565 memory_values[2] = 'd';
557 context_seeds[2] = 0x20000002; 566 context_seeds[2] = 0x20000002;
567 tebs[2].StartOfMemoryRange = expect_threads[2].Teb;
568 tebs[2].Memory.DataSize = kTebSize;
558 569
559 if (thread_id_collision) { 570 if (thread_id_collision) {
560 thread_ids[0] = 0x0123456700000001; 571 thread_ids[0] = 0x0123456700000001;
561 thread_ids[1] = 0x89abcdef00000001; 572 thread_ids[1] = 0x89abcdef00000001;
562 thread_ids[2] = 4; 573 thread_ids[2] = 4;
563 expect_threads[0].ThreadId = 0; 574 expect_threads[0].ThreadId = 0;
564 expect_threads[1].ThreadId = 1; 575 expect_threads[1].ThreadId = 1;
565 expect_threads[2].ThreadId = 2; 576 expect_threads[2].ThreadId = 2;
566 } else { 577 } else {
567 thread_ids[0] = 1; 578 thread_ids[0] = 1;
(...skipping 20 matching lines...) Expand all
588 memory_snapshot->SetAddress( 599 memory_snapshot->SetAddress(
589 expect_threads[index].Stack.StartOfMemoryRange); 600 expect_threads[index].Stack.StartOfMemoryRange);
590 memory_snapshot->SetSize(expect_threads[index].Stack.Memory.DataSize); 601 memory_snapshot->SetSize(expect_threads[index].Stack.Memory.DataSize);
591 memory_snapshot->SetValue(memory_values[index]); 602 memory_snapshot->SetValue(memory_values[index]);
592 thread_snapshot->SetStack(memory_snapshot.Pass()); 603 thread_snapshot->SetStack(memory_snapshot.Pass());
593 } 604 }
594 605
595 Traits::InitializeCPUContext(thread_snapshot->MutableContext(), 606 Traits::InitializeCPUContext(thread_snapshot->MutableContext(),
596 context_seeds[index]); 607 context_seeds[index]);
597 608
609 auto teb_snapshot = make_scoped_ptr(new TestMemorySnapshot());
610 teb_snapshot->SetAddress(expect_threads[index].Teb);
611 teb_snapshot->SetSize(kTebSize);
612 teb_snapshot->SetValue(static_cast<char>('t' + index));
613 thread_snapshot->AddExtraMemory(teb_snapshot.Pass());
614
598 thread_snapshots.push_back(thread_snapshot); 615 thread_snapshots.push_back(thread_snapshot);
599 } 616 }
600 617
601 auto thread_list_writer = make_scoped_ptr(new MinidumpThreadListWriter()); 618 auto thread_list_writer = make_scoped_ptr(new MinidumpThreadListWriter());
602 auto memory_list_writer = make_scoped_ptr(new MinidumpMemoryListWriter()); 619 auto memory_list_writer = make_scoped_ptr(new MinidumpMemoryListWriter());
603 thread_list_writer->SetMemoryListWriter(memory_list_writer.get()); 620 thread_list_writer->SetMemoryListWriter(memory_list_writer.get());
604 MinidumpThreadIDMap thread_id_map; 621 MinidumpThreadIDMap thread_id_map;
605 thread_list_writer->InitializeFromSnapshot(thread_snapshots, &thread_id_map); 622 thread_list_writer->InitializeFromSnapshot(thread_snapshots, &thread_id_map);
606 623
607 MinidumpFileWriter minidump_file_writer; 624 MinidumpFileWriter minidump_file_writer;
608 minidump_file_writer.AddStream(thread_list_writer.Pass()); 625 minidump_file_writer.AddStream(thread_list_writer.Pass());
609 minidump_file_writer.AddStream(memory_list_writer.Pass()); 626 minidump_file_writer.AddStream(memory_list_writer.Pass());
610 627
611 StringFile string_file; 628 StringFile string_file;
612 ASSERT_TRUE(minidump_file_writer.WriteEverything(&string_file)); 629 ASSERT_TRUE(minidump_file_writer.WriteEverything(&string_file));
613 630
614 const MINIDUMP_THREAD_LIST* thread_list = nullptr; 631 const MINIDUMP_THREAD_LIST* thread_list = nullptr;
615 const MINIDUMP_MEMORY_LIST* memory_list = nullptr; 632 const MINIDUMP_MEMORY_LIST* memory_list = nullptr;
616 ASSERT_NO_FATAL_FAILURE( 633 ASSERT_NO_FATAL_FAILURE(
617 GetThreadListStream(string_file.string(), &thread_list, &memory_list)); 634 GetThreadListStream(string_file.string(), &thread_list, &memory_list));
618 635
619 ASSERT_EQ(3u, thread_list->NumberOfThreads); 636 ASSERT_EQ(3u, thread_list->NumberOfThreads);
620 ASSERT_EQ(2u, memory_list->NumberOfMemoryRanges); 637 ASSERT_EQ(5u, memory_list->NumberOfMemoryRanges);
621 638
622 size_t memory_index = 0; 639 size_t memory_index = 0;
623 for (size_t index = 0; index < thread_list->NumberOfThreads; ++index) { 640 for (size_t index = 0; index < thread_list->NumberOfThreads; ++index) {
624 SCOPED_TRACE(base::StringPrintf("index %" PRIuS, index)); 641 SCOPED_TRACE(base::StringPrintf("index %" PRIuS, index));
625 642
626 const MINIDUMP_MEMORY_DESCRIPTOR* observed_stack = nullptr; 643 const MINIDUMP_MEMORY_DESCRIPTOR* observed_stack = nullptr;
627 const MINIDUMP_MEMORY_DESCRIPTOR** observed_stack_p = 644 const MINIDUMP_MEMORY_DESCRIPTOR** observed_stack_p =
628 expect_threads[index].Stack.Memory.DataSize ? &observed_stack : nullptr; 645 expect_threads[index].Stack.Memory.DataSize ? &observed_stack : nullptr;
629 const MinidumpContextType* observed_context = nullptr; 646 const MinidumpContextType* observed_context = nullptr;
630 ASSERT_NO_FATAL_FAILURE( 647 ASSERT_NO_FATAL_FAILURE(
631 ExpectThread(&expect_threads[index], 648 ExpectThread(&expect_threads[index],
632 &thread_list->Threads[index], 649 &thread_list->Threads[index],
633 string_file.string(), 650 string_file.string(),
634 observed_stack_p, 651 observed_stack_p,
635 reinterpret_cast<const void**>(&observed_context))); 652 reinterpret_cast<const void**>(&observed_context)));
636 653
637 ASSERT_NO_FATAL_FAILURE(Traits::ExpectMinidumpContext( 654 ASSERT_NO_FATAL_FAILURE(Traits::ExpectMinidumpContext(
638 context_seeds[index], observed_context, true)); 655 context_seeds[index], observed_context, true));
639 656
640 if (observed_stack_p) { 657 if (observed_stack_p) {
641 ASSERT_NO_FATAL_FAILURE(ExpectMinidumpMemoryDescriptorAndContents( 658 ASSERT_NO_FATAL_FAILURE(ExpectMinidumpMemoryDescriptorAndContents(
642 &expect_threads[index].Stack, 659 &expect_threads[index].Stack,
643 observed_stack, 660 observed_stack,
644 string_file.string(), 661 string_file.string(),
645 memory_values[index], 662 memory_values[index],
646 index == thread_list->NumberOfThreads - 1)); 663 false));
647 664
648 ASSERT_NO_FATAL_FAILURE(ExpectMinidumpMemoryDescriptor( 665 ASSERT_NO_FATAL_FAILURE(ExpectMinidumpMemoryDescriptor(
649 observed_stack, &memory_list->MemoryRanges[memory_index])); 666 observed_stack, &memory_list->MemoryRanges[memory_index]));
650 667
651 ++memory_index; 668 ++memory_index;
652 } 669 }
653 } 670 }
671
672 for (size_t index = 0; index < thread_list->NumberOfThreads; ++index) {
673 const MINIDUMP_MEMORY_DESCRIPTOR* memory =
674 &memory_list->MemoryRanges[memory_index];
675 ASSERT_NO_FATAL_FAILURE(
676 ExpectMinidumpMemoryDescriptor(&tebs[index], memory));
677 std::string expected_data(kTebSize, static_cast<char>('t' + index));
678 std::string observed_data(&string_file.string()[memory->Memory.Rva],
679 memory->Memory.DataSize);
680 EXPECT_EQ(expected_data, observed_data);
681 ++memory_index;
682 }
654 } 683 }
655 684
656 TEST(MinidumpThreadWriter, InitializeFromSnapshot_x86) { 685 TEST(MinidumpThreadWriter, InitializeFromSnapshot_x86) {
657 RunInitializeFromSnapshotTest<InitializeFromSnapshotX86Traits>(false); 686 RunInitializeFromSnapshotTest<InitializeFromSnapshotX86Traits>(false);
658 } 687 }
659 688
660 TEST(MinidumpThreadWriter, InitializeFromSnapshot_AMD64) { 689 TEST(MinidumpThreadWriter, InitializeFromSnapshot_AMD64) {
661 RunInitializeFromSnapshotTest<InitializeFromSnapshotAMD64Traits>(false); 690 RunInitializeFromSnapshotTest<InitializeFromSnapshotAMD64Traits>(false);
662 } 691 }
663 692
(...skipping 17 matching lines...) Expand all
681 710
682 TEST(MinidumpThreadWriterDeathTest, InitializeFromSnapshot_NoContext) { 711 TEST(MinidumpThreadWriterDeathTest, InitializeFromSnapshot_NoContext) {
683 ASSERT_DEATH_CHECK( 712 ASSERT_DEATH_CHECK(
684 RunInitializeFromSnapshotTest<InitializeFromSnapshotNoContextTraits>( 713 RunInitializeFromSnapshotTest<InitializeFromSnapshotNoContextTraits>(
685 false), "context_"); 714 false), "context_");
686 } 715 }
687 716
688 } // namespace 717 } // namespace
689 } // namespace test 718 } // namespace test
690 } // namespace crashpad 719 } // namespace crashpad
OLDNEW
« no previous file with comments | « minidump/minidump_thread_writer.cc ('k') | snapshot/test/test_process_snapshot.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698