1*9712c20fSFrederick Mayle // Copyright 2010 Google LLC
2*9712c20fSFrederick Mayle //
3*9712c20fSFrederick Mayle // Redistribution and use in source and binary forms, with or without
4*9712c20fSFrederick Mayle // modification, are permitted provided that the following conditions are
5*9712c20fSFrederick Mayle // met:
6*9712c20fSFrederick Mayle //
7*9712c20fSFrederick Mayle // * Redistributions of source code must retain the above copyright
8*9712c20fSFrederick Mayle // notice, this list of conditions and the following disclaimer.
9*9712c20fSFrederick Mayle // * Redistributions in binary form must reproduce the above
10*9712c20fSFrederick Mayle // copyright notice, this list of conditions and the following disclaimer
11*9712c20fSFrederick Mayle // in the documentation and/or other materials provided with the
12*9712c20fSFrederick Mayle // distribution.
13*9712c20fSFrederick Mayle // * Neither the name of Google LLC nor the names of its
14*9712c20fSFrederick Mayle // contributors may be used to endorse or promote products derived from
15*9712c20fSFrederick Mayle // this software without specific prior written permission.
16*9712c20fSFrederick Mayle //
17*9712c20fSFrederick Mayle // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18*9712c20fSFrederick Mayle // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19*9712c20fSFrederick Mayle // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20*9712c20fSFrederick Mayle // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21*9712c20fSFrederick Mayle // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22*9712c20fSFrederick Mayle // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23*9712c20fSFrederick Mayle // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24*9712c20fSFrederick Mayle // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25*9712c20fSFrederick Mayle // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26*9712c20fSFrederick Mayle // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27*9712c20fSFrederick Mayle // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*9712c20fSFrederick Mayle
29*9712c20fSFrederick Mayle // Unit test for Minidump. Uses a pre-generated minidump and
30*9712c20fSFrederick Mayle // verifies that certain streams are correct.
31*9712c20fSFrederick Mayle
32*9712c20fSFrederick Mayle #ifdef HAVE_CONFIG_H
33*9712c20fSFrederick Mayle #include <config.h> // Must come first
34*9712c20fSFrederick Mayle #endif
35*9712c20fSFrederick Mayle
36*9712c20fSFrederick Mayle #include <iostream>
37*9712c20fSFrederick Mayle #include <fstream>
38*9712c20fSFrederick Mayle #include <sstream>
39*9712c20fSFrederick Mayle #include <stdlib.h>
40*9712c20fSFrederick Mayle #include <string>
41*9712c20fSFrederick Mayle #include <vector>
42*9712c20fSFrederick Mayle
43*9712c20fSFrederick Mayle #include "breakpad_googletest_includes.h"
44*9712c20fSFrederick Mayle #include "common/using_std_string.h"
45*9712c20fSFrederick Mayle #include "google_breakpad/common/minidump_format.h"
46*9712c20fSFrederick Mayle #include "google_breakpad/processor/minidump.h"
47*9712c20fSFrederick Mayle #include "processor/logging.h"
48*9712c20fSFrederick Mayle #include "processor/synth_minidump.h"
49*9712c20fSFrederick Mayle
50*9712c20fSFrederick Mayle namespace {
51*9712c20fSFrederick Mayle
52*9712c20fSFrederick Mayle using google_breakpad::Minidump;
53*9712c20fSFrederick Mayle using google_breakpad::MinidumpContext;
54*9712c20fSFrederick Mayle using google_breakpad::MinidumpCrashpadInfo;
55*9712c20fSFrederick Mayle using google_breakpad::MinidumpException;
56*9712c20fSFrederick Mayle using google_breakpad::MinidumpMemoryInfo;
57*9712c20fSFrederick Mayle using google_breakpad::MinidumpMemoryInfoList;
58*9712c20fSFrederick Mayle using google_breakpad::MinidumpMemoryList;
59*9712c20fSFrederick Mayle using google_breakpad::MinidumpMemoryRegion;
60*9712c20fSFrederick Mayle using google_breakpad::MinidumpModule;
61*9712c20fSFrederick Mayle using google_breakpad::MinidumpModuleList;
62*9712c20fSFrederick Mayle using google_breakpad::MinidumpSystemInfo;
63*9712c20fSFrederick Mayle using google_breakpad::MinidumpUnloadedModule;
64*9712c20fSFrederick Mayle using google_breakpad::MinidumpUnloadedModuleList;
65*9712c20fSFrederick Mayle using google_breakpad::MinidumpThread;
66*9712c20fSFrederick Mayle using google_breakpad::MinidumpThreadList;
67*9712c20fSFrederick Mayle using google_breakpad::SynthMinidump::Context;
68*9712c20fSFrederick Mayle using google_breakpad::SynthMinidump::Dump;
69*9712c20fSFrederick Mayle using google_breakpad::SynthMinidump::Exception;
70*9712c20fSFrederick Mayle using google_breakpad::SynthMinidump::Memory;
71*9712c20fSFrederick Mayle using google_breakpad::SynthMinidump::Module;
72*9712c20fSFrederick Mayle using google_breakpad::SynthMinidump::UnloadedModule;
73*9712c20fSFrederick Mayle using google_breakpad::SynthMinidump::Section;
74*9712c20fSFrederick Mayle using google_breakpad::SynthMinidump::Stream;
75*9712c20fSFrederick Mayle using google_breakpad::SynthMinidump::String;
76*9712c20fSFrederick Mayle using google_breakpad::SynthMinidump::SystemInfo;
77*9712c20fSFrederick Mayle using google_breakpad::SynthMinidump::Thread;
78*9712c20fSFrederick Mayle using google_breakpad::test_assembler::kBigEndian;
79*9712c20fSFrederick Mayle using google_breakpad::test_assembler::kLittleEndian;
80*9712c20fSFrederick Mayle using std::ifstream;
81*9712c20fSFrederick Mayle using std::istringstream;
82*9712c20fSFrederick Mayle using std::vector;
83*9712c20fSFrederick Mayle using ::testing::Return;
84*9712c20fSFrederick Mayle
85*9712c20fSFrederick Mayle class MinidumpTest : public ::testing::Test {
86*9712c20fSFrederick Mayle public:
SetUp()87*9712c20fSFrederick Mayle void SetUp() {
88*9712c20fSFrederick Mayle minidump_file_ = string(getenv("srcdir") ? getenv("srcdir") : ".") +
89*9712c20fSFrederick Mayle "/src/processor/testdata/minidump2.dmp";
90*9712c20fSFrederick Mayle }
91*9712c20fSFrederick Mayle string minidump_file_;
92*9712c20fSFrederick Mayle };
93*9712c20fSFrederick Mayle
TEST_F(MinidumpTest,TestMinidumpFromFile)94*9712c20fSFrederick Mayle TEST_F(MinidumpTest, TestMinidumpFromFile) {
95*9712c20fSFrederick Mayle Minidump minidump(minidump_file_);
96*9712c20fSFrederick Mayle ASSERT_EQ(minidump.path(), minidump_file_);
97*9712c20fSFrederick Mayle ASSERT_TRUE(minidump.Read());
98*9712c20fSFrederick Mayle const MDRawHeader* header = minidump.header();
99*9712c20fSFrederick Mayle ASSERT_NE(header, (MDRawHeader*)NULL);
100*9712c20fSFrederick Mayle ASSERT_EQ(header->signature, uint32_t(MD_HEADER_SIGNATURE));
101*9712c20fSFrederick Mayle
102*9712c20fSFrederick Mayle MinidumpModuleList* md_module_list = minidump.GetModuleList();
103*9712c20fSFrederick Mayle ASSERT_TRUE(md_module_list != NULL);
104*9712c20fSFrederick Mayle const MinidumpModule* md_module = md_module_list->GetModuleAtIndex(0);
105*9712c20fSFrederick Mayle ASSERT_TRUE(md_module != NULL);
106*9712c20fSFrederick Mayle ASSERT_EQ("c:\\test_app.exe", md_module->code_file());
107*9712c20fSFrederick Mayle ASSERT_EQ("c:\\test_app.pdb", md_module->debug_file());
108*9712c20fSFrederick Mayle ASSERT_EQ("45D35F6C2d000", md_module->code_identifier());
109*9712c20fSFrederick Mayle ASSERT_EQ("5A9832E5287241C1838ED98914E9B7FF1", md_module->debug_identifier());
110*9712c20fSFrederick Mayle }
111*9712c20fSFrederick Mayle
TEST_F(MinidumpTest,TestMinidumpFromStream)112*9712c20fSFrederick Mayle TEST_F(MinidumpTest, TestMinidumpFromStream) {
113*9712c20fSFrederick Mayle // read minidump contents into memory, construct a stringstream around them
114*9712c20fSFrederick Mayle ifstream file_stream(minidump_file_.c_str(), std::ios::in);
115*9712c20fSFrederick Mayle ASSERT_TRUE(file_stream.good());
116*9712c20fSFrederick Mayle vector<char> bytes;
117*9712c20fSFrederick Mayle file_stream.seekg(0, std::ios_base::end);
118*9712c20fSFrederick Mayle ASSERT_TRUE(file_stream.good());
119*9712c20fSFrederick Mayle bytes.resize(file_stream.tellg());
120*9712c20fSFrederick Mayle file_stream.seekg(0, std::ios_base::beg);
121*9712c20fSFrederick Mayle ASSERT_TRUE(file_stream.good());
122*9712c20fSFrederick Mayle file_stream.read(&bytes[0], bytes.size());
123*9712c20fSFrederick Mayle ASSERT_TRUE(file_stream.good());
124*9712c20fSFrederick Mayle string str(&bytes[0], bytes.size());
125*9712c20fSFrederick Mayle istringstream stream(str);
126*9712c20fSFrederick Mayle ASSERT_TRUE(stream.good());
127*9712c20fSFrederick Mayle
128*9712c20fSFrederick Mayle // now read minidump from stringstream
129*9712c20fSFrederick Mayle Minidump minidump(stream);
130*9712c20fSFrederick Mayle ASSERT_EQ(minidump.path(), "");
131*9712c20fSFrederick Mayle ASSERT_TRUE(minidump.Read());
132*9712c20fSFrederick Mayle const MDRawHeader* header = minidump.header();
133*9712c20fSFrederick Mayle ASSERT_NE(header, (MDRawHeader*)NULL);
134*9712c20fSFrederick Mayle ASSERT_EQ(header->signature, uint32_t(MD_HEADER_SIGNATURE));
135*9712c20fSFrederick Mayle //TODO: add more checks here
136*9712c20fSFrederick Mayle }
137*9712c20fSFrederick Mayle
TEST_F(MinidumpTest,TestMinidumpWithCrashpadAnnotations)138*9712c20fSFrederick Mayle TEST_F(MinidumpTest, TestMinidumpWithCrashpadAnnotations) {
139*9712c20fSFrederick Mayle string crashpad_minidump_file =
140*9712c20fSFrederick Mayle string(getenv("srcdir") ? getenv("srcdir") : ".") +
141*9712c20fSFrederick Mayle "/src/processor/testdata/minidump_crashpad_annotation.dmp";
142*9712c20fSFrederick Mayle
143*9712c20fSFrederick Mayle Minidump minidump(crashpad_minidump_file);
144*9712c20fSFrederick Mayle ASSERT_EQ(minidump.path(), crashpad_minidump_file);
145*9712c20fSFrederick Mayle ASSERT_TRUE(minidump.Read());
146*9712c20fSFrederick Mayle
147*9712c20fSFrederick Mayle MinidumpCrashpadInfo* crashpad_info = minidump.GetCrashpadInfo();
148*9712c20fSFrederick Mayle ASSERT_TRUE(crashpad_info != NULL);
149*9712c20fSFrederick Mayle
150*9712c20fSFrederick Mayle const std::vector<std::vector<MinidumpCrashpadInfo::AnnotationObject>>*
151*9712c20fSFrederick Mayle annotation_objects_list =
152*9712c20fSFrederick Mayle crashpad_info->GetModuleCrashpadInfoAnnotationObjects();
153*9712c20fSFrederick Mayle ASSERT_EQ(2U, annotation_objects_list->size());
154*9712c20fSFrederick Mayle
155*9712c20fSFrederick Mayle std::vector<MinidumpCrashpadInfo::AnnotationObject> annotation_objects =
156*9712c20fSFrederick Mayle annotation_objects_list->at(0);
157*9712c20fSFrederick Mayle ASSERT_EQ(5U, annotation_objects.size());
158*9712c20fSFrederick Mayle
159*9712c20fSFrederick Mayle std::vector<std::string> annotation_names;
160*9712c20fSFrederick Mayle for (size_t i = 0; i < annotation_objects.size(); i++) {
161*9712c20fSFrederick Mayle MinidumpCrashpadInfo::AnnotationObject annotation_object =
162*9712c20fSFrederick Mayle annotation_objects.at(i);
163*9712c20fSFrederick Mayle annotation_names.push_back(annotation_object.name);
164*9712c20fSFrederick Mayle ASSERT_TRUE(annotation_object.type > 0);
165*9712c20fSFrederick Mayle ASSERT_TRUE(annotation_object.value.size() > 0);
166*9712c20fSFrederick Mayle }
167*9712c20fSFrederick Mayle
168*9712c20fSFrederick Mayle std::vector<std::string> expected_strings{
169*9712c20fSFrederick Mayle "exceptionReason", "exceptionName", "firstexception_bt", "firstexception",
170*9712c20fSFrederick Mayle "CounterAnnotation"};
171*9712c20fSFrederick Mayle ASSERT_EQ(annotation_names, expected_strings);
172*9712c20fSFrederick Mayle }
173*9712c20fSFrederick Mayle
TEST(Dump,ReadBackEmpty)174*9712c20fSFrederick Mayle TEST(Dump, ReadBackEmpty) {
175*9712c20fSFrederick Mayle Dump dump(0);
176*9712c20fSFrederick Mayle dump.Finish();
177*9712c20fSFrederick Mayle string contents;
178*9712c20fSFrederick Mayle ASSERT_TRUE(dump.GetContents(&contents));
179*9712c20fSFrederick Mayle istringstream stream(contents);
180*9712c20fSFrederick Mayle Minidump minidump(stream);
181*9712c20fSFrederick Mayle ASSERT_TRUE(minidump.Read());
182*9712c20fSFrederick Mayle ASSERT_EQ(0U, minidump.GetDirectoryEntryCount());
183*9712c20fSFrederick Mayle }
184*9712c20fSFrederick Mayle
TEST(Dump,ReadBackEmptyBigEndian)185*9712c20fSFrederick Mayle TEST(Dump, ReadBackEmptyBigEndian) {
186*9712c20fSFrederick Mayle Dump big_minidump(0, kBigEndian);
187*9712c20fSFrederick Mayle big_minidump.Finish();
188*9712c20fSFrederick Mayle string contents;
189*9712c20fSFrederick Mayle ASSERT_TRUE(big_minidump.GetContents(&contents));
190*9712c20fSFrederick Mayle istringstream stream(contents);
191*9712c20fSFrederick Mayle Minidump minidump(stream);
192*9712c20fSFrederick Mayle ASSERT_TRUE(minidump.Read());
193*9712c20fSFrederick Mayle ASSERT_EQ(0U, minidump.GetDirectoryEntryCount());
194*9712c20fSFrederick Mayle }
195*9712c20fSFrederick Mayle
TEST(Dump,OneStream)196*9712c20fSFrederick Mayle TEST(Dump, OneStream) {
197*9712c20fSFrederick Mayle Dump dump(0, kBigEndian);
198*9712c20fSFrederick Mayle Stream stream(dump, 0xfbb7fa2bU);
199*9712c20fSFrederick Mayle stream.Append("stream contents");
200*9712c20fSFrederick Mayle dump.Add(&stream);
201*9712c20fSFrederick Mayle dump.Finish();
202*9712c20fSFrederick Mayle
203*9712c20fSFrederick Mayle string contents;
204*9712c20fSFrederick Mayle ASSERT_TRUE(dump.GetContents(&contents));
205*9712c20fSFrederick Mayle istringstream minidump_stream(contents);
206*9712c20fSFrederick Mayle Minidump minidump(minidump_stream);
207*9712c20fSFrederick Mayle ASSERT_TRUE(minidump.Read());
208*9712c20fSFrederick Mayle ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());
209*9712c20fSFrederick Mayle
210*9712c20fSFrederick Mayle const MDRawDirectory* dir = minidump.GetDirectoryEntryAtIndex(0);
211*9712c20fSFrederick Mayle ASSERT_TRUE(dir != NULL);
212*9712c20fSFrederick Mayle EXPECT_EQ(0xfbb7fa2bU, dir->stream_type);
213*9712c20fSFrederick Mayle
214*9712c20fSFrederick Mayle uint32_t stream_length;
215*9712c20fSFrederick Mayle ASSERT_TRUE(minidump.SeekToStreamType(0xfbb7fa2bU, &stream_length));
216*9712c20fSFrederick Mayle ASSERT_EQ(15U, stream_length);
217*9712c20fSFrederick Mayle char stream_contents[15];
218*9712c20fSFrederick Mayle ASSERT_TRUE(minidump.ReadBytes(stream_contents, sizeof(stream_contents)));
219*9712c20fSFrederick Mayle EXPECT_EQ(string("stream contents"),
220*9712c20fSFrederick Mayle string(stream_contents, sizeof(stream_contents)));
221*9712c20fSFrederick Mayle
222*9712c20fSFrederick Mayle EXPECT_FALSE(minidump.GetThreadList());
223*9712c20fSFrederick Mayle EXPECT_FALSE(minidump.GetModuleList());
224*9712c20fSFrederick Mayle EXPECT_FALSE(minidump.GetMemoryList());
225*9712c20fSFrederick Mayle EXPECT_FALSE(minidump.GetException());
226*9712c20fSFrederick Mayle EXPECT_FALSE(minidump.GetAssertion());
227*9712c20fSFrederick Mayle EXPECT_FALSE(minidump.GetSystemInfo());
228*9712c20fSFrederick Mayle EXPECT_FALSE(minidump.GetMiscInfo());
229*9712c20fSFrederick Mayle EXPECT_FALSE(minidump.GetBreakpadInfo());
230*9712c20fSFrederick Mayle }
231*9712c20fSFrederick Mayle
TEST(Dump,OneMemory)232*9712c20fSFrederick Mayle TEST(Dump, OneMemory) {
233*9712c20fSFrederick Mayle Dump dump(0, kBigEndian);
234*9712c20fSFrederick Mayle Memory memory(dump, 0x309d68010bd21b2cULL);
235*9712c20fSFrederick Mayle memory.Append("memory contents");
236*9712c20fSFrederick Mayle dump.Add(&memory);
237*9712c20fSFrederick Mayle dump.Finish();
238*9712c20fSFrederick Mayle
239*9712c20fSFrederick Mayle string contents;
240*9712c20fSFrederick Mayle ASSERT_TRUE(dump.GetContents(&contents));
241*9712c20fSFrederick Mayle istringstream minidump_stream(contents);
242*9712c20fSFrederick Mayle Minidump minidump(minidump_stream);
243*9712c20fSFrederick Mayle ASSERT_TRUE(minidump.Read());
244*9712c20fSFrederick Mayle ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());
245*9712c20fSFrederick Mayle
246*9712c20fSFrederick Mayle const MDRawDirectory* dir = minidump.GetDirectoryEntryAtIndex(0);
247*9712c20fSFrederick Mayle ASSERT_TRUE(dir != NULL);
248*9712c20fSFrederick Mayle EXPECT_EQ((uint32_t) MD_MEMORY_LIST_STREAM, dir->stream_type);
249*9712c20fSFrederick Mayle
250*9712c20fSFrederick Mayle MinidumpMemoryList* memory_list = minidump.GetMemoryList();
251*9712c20fSFrederick Mayle ASSERT_TRUE(memory_list != NULL);
252*9712c20fSFrederick Mayle ASSERT_EQ(1U, memory_list->region_count());
253*9712c20fSFrederick Mayle
254*9712c20fSFrederick Mayle MinidumpMemoryRegion* region1 = memory_list->GetMemoryRegionAtIndex(0);
255*9712c20fSFrederick Mayle ASSERT_EQ(0x309d68010bd21b2cULL, region1->GetBase());
256*9712c20fSFrederick Mayle ASSERT_EQ(15U, region1->GetSize());
257*9712c20fSFrederick Mayle const uint8_t* region1_bytes = region1->GetMemory();
258*9712c20fSFrederick Mayle ASSERT_TRUE(memcmp("memory contents", region1_bytes, 15) == 0);
259*9712c20fSFrederick Mayle }
260*9712c20fSFrederick Mayle
261*9712c20fSFrederick Mayle // One thread --- and its requisite entourage.
TEST(Dump,OneThread)262*9712c20fSFrederick Mayle TEST(Dump, OneThread) {
263*9712c20fSFrederick Mayle Dump dump(0, kLittleEndian);
264*9712c20fSFrederick Mayle Memory stack(dump, 0x2326a0fa);
265*9712c20fSFrederick Mayle stack.Append("stack for thread");
266*9712c20fSFrederick Mayle
267*9712c20fSFrederick Mayle MDRawContextX86 raw_context;
268*9712c20fSFrederick Mayle const uint32_t kExpectedEIP = 0x6913f540;
269*9712c20fSFrederick Mayle raw_context.context_flags = MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL;
270*9712c20fSFrederick Mayle raw_context.edi = 0x3ecba80d;
271*9712c20fSFrederick Mayle raw_context.esi = 0x382583b9;
272*9712c20fSFrederick Mayle raw_context.ebx = 0x7fccc03f;
273*9712c20fSFrederick Mayle raw_context.edx = 0xf62f8ec2;
274*9712c20fSFrederick Mayle raw_context.ecx = 0x46a6a6a8;
275*9712c20fSFrederick Mayle raw_context.eax = 0x6a5025e2;
276*9712c20fSFrederick Mayle raw_context.ebp = 0xd9fabb4a;
277*9712c20fSFrederick Mayle raw_context.eip = kExpectedEIP;
278*9712c20fSFrederick Mayle raw_context.cs = 0xbffe6eda;
279*9712c20fSFrederick Mayle raw_context.eflags = 0xb2ce1e2d;
280*9712c20fSFrederick Mayle raw_context.esp = 0x659caaa4;
281*9712c20fSFrederick Mayle raw_context.ss = 0x2e951ef7;
282*9712c20fSFrederick Mayle Context context(dump, raw_context);
283*9712c20fSFrederick Mayle
284*9712c20fSFrederick Mayle Thread thread(dump, 0xa898f11b, stack, context,
285*9712c20fSFrederick Mayle 0x9e39439f, 0x4abfc15f, 0xe499898a, 0x0d43e939dcfd0372ULL);
286*9712c20fSFrederick Mayle
287*9712c20fSFrederick Mayle dump.Add(&stack);
288*9712c20fSFrederick Mayle dump.Add(&context);
289*9712c20fSFrederick Mayle dump.Add(&thread);
290*9712c20fSFrederick Mayle dump.Finish();
291*9712c20fSFrederick Mayle
292*9712c20fSFrederick Mayle string contents;
293*9712c20fSFrederick Mayle ASSERT_TRUE(dump.GetContents(&contents));
294*9712c20fSFrederick Mayle
295*9712c20fSFrederick Mayle istringstream minidump_stream(contents);
296*9712c20fSFrederick Mayle Minidump minidump(minidump_stream);
297*9712c20fSFrederick Mayle ASSERT_TRUE(minidump.Read());
298*9712c20fSFrederick Mayle ASSERT_EQ(2U, minidump.GetDirectoryEntryCount());
299*9712c20fSFrederick Mayle
300*9712c20fSFrederick Mayle MinidumpMemoryList* md_memory_list = minidump.GetMemoryList();
301*9712c20fSFrederick Mayle ASSERT_TRUE(md_memory_list != NULL);
302*9712c20fSFrederick Mayle ASSERT_EQ(1U, md_memory_list->region_count());
303*9712c20fSFrederick Mayle
304*9712c20fSFrederick Mayle MinidumpMemoryRegion* md_region = md_memory_list->GetMemoryRegionAtIndex(0);
305*9712c20fSFrederick Mayle ASSERT_EQ(0x2326a0faU, md_region->GetBase());
306*9712c20fSFrederick Mayle ASSERT_EQ(16U, md_region->GetSize());
307*9712c20fSFrederick Mayle const uint8_t* region_bytes = md_region->GetMemory();
308*9712c20fSFrederick Mayle ASSERT_TRUE(memcmp("stack for thread", region_bytes, 16) == 0);
309*9712c20fSFrederick Mayle
310*9712c20fSFrederick Mayle MinidumpThreadList* thread_list = minidump.GetThreadList();
311*9712c20fSFrederick Mayle ASSERT_TRUE(thread_list != NULL);
312*9712c20fSFrederick Mayle ASSERT_EQ(1U, thread_list->thread_count());
313*9712c20fSFrederick Mayle
314*9712c20fSFrederick Mayle MinidumpThread* md_thread = thread_list->GetThreadAtIndex(0);
315*9712c20fSFrederick Mayle ASSERT_TRUE(md_thread != NULL);
316*9712c20fSFrederick Mayle uint32_t thread_id;
317*9712c20fSFrederick Mayle ASSERT_TRUE(md_thread->GetThreadID(&thread_id));
318*9712c20fSFrederick Mayle ASSERT_EQ(0xa898f11bU, thread_id);
319*9712c20fSFrederick Mayle MinidumpMemoryRegion* md_stack = md_thread->GetMemory();
320*9712c20fSFrederick Mayle ASSERT_TRUE(md_stack != NULL);
321*9712c20fSFrederick Mayle ASSERT_EQ(0x2326a0faU, md_stack->GetBase());
322*9712c20fSFrederick Mayle ASSERT_EQ(16U, md_stack->GetSize());
323*9712c20fSFrederick Mayle const uint8_t* md_stack_bytes = md_stack->GetMemory();
324*9712c20fSFrederick Mayle ASSERT_TRUE(memcmp("stack for thread", md_stack_bytes, 16) == 0);
325*9712c20fSFrederick Mayle
326*9712c20fSFrederick Mayle MinidumpContext* md_context = md_thread->GetContext();
327*9712c20fSFrederick Mayle ASSERT_TRUE(md_context != NULL);
328*9712c20fSFrederick Mayle ASSERT_EQ((uint32_t) MD_CONTEXT_X86, md_context->GetContextCPU());
329*9712c20fSFrederick Mayle
330*9712c20fSFrederick Mayle uint64_t eip;
331*9712c20fSFrederick Mayle ASSERT_TRUE(md_context->GetInstructionPointer(&eip));
332*9712c20fSFrederick Mayle EXPECT_EQ(kExpectedEIP, eip);
333*9712c20fSFrederick Mayle
334*9712c20fSFrederick Mayle const MDRawContextX86* md_raw_context = md_context->GetContextX86();
335*9712c20fSFrederick Mayle ASSERT_TRUE(md_raw_context != NULL);
336*9712c20fSFrederick Mayle ASSERT_EQ((uint32_t) (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL),
337*9712c20fSFrederick Mayle (md_raw_context->context_flags
338*9712c20fSFrederick Mayle & (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL)));
339*9712c20fSFrederick Mayle EXPECT_EQ(0x3ecba80dU, raw_context.edi);
340*9712c20fSFrederick Mayle EXPECT_EQ(0x382583b9U, raw_context.esi);
341*9712c20fSFrederick Mayle EXPECT_EQ(0x7fccc03fU, raw_context.ebx);
342*9712c20fSFrederick Mayle EXPECT_EQ(0xf62f8ec2U, raw_context.edx);
343*9712c20fSFrederick Mayle EXPECT_EQ(0x46a6a6a8U, raw_context.ecx);
344*9712c20fSFrederick Mayle EXPECT_EQ(0x6a5025e2U, raw_context.eax);
345*9712c20fSFrederick Mayle EXPECT_EQ(0xd9fabb4aU, raw_context.ebp);
346*9712c20fSFrederick Mayle EXPECT_EQ(kExpectedEIP, raw_context.eip);
347*9712c20fSFrederick Mayle EXPECT_EQ(0xbffe6edaU, raw_context.cs);
348*9712c20fSFrederick Mayle EXPECT_EQ(0xb2ce1e2dU, raw_context.eflags);
349*9712c20fSFrederick Mayle EXPECT_EQ(0x659caaa4U, raw_context.esp);
350*9712c20fSFrederick Mayle EXPECT_EQ(0x2e951ef7U, raw_context.ss);
351*9712c20fSFrederick Mayle }
352*9712c20fSFrederick Mayle
TEST(Dump,ThreadMissingMemory)353*9712c20fSFrederick Mayle TEST(Dump, ThreadMissingMemory) {
354*9712c20fSFrederick Mayle Dump dump(0, kLittleEndian);
355*9712c20fSFrederick Mayle Memory stack(dump, 0x2326a0fa);
356*9712c20fSFrederick Mayle // Stack has no contents.
357*9712c20fSFrederick Mayle
358*9712c20fSFrederick Mayle MDRawContextX86 raw_context;
359*9712c20fSFrederick Mayle memset(&raw_context, 0, sizeof(raw_context));
360*9712c20fSFrederick Mayle raw_context.context_flags = MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL;
361*9712c20fSFrederick Mayle Context context(dump, raw_context);
362*9712c20fSFrederick Mayle
363*9712c20fSFrederick Mayle Thread thread(dump, 0xa898f11b, stack, context,
364*9712c20fSFrederick Mayle 0x9e39439f, 0x4abfc15f, 0xe499898a, 0x0d43e939dcfd0372ULL);
365*9712c20fSFrederick Mayle
366*9712c20fSFrederick Mayle dump.Add(&stack);
367*9712c20fSFrederick Mayle dump.Add(&context);
368*9712c20fSFrederick Mayle dump.Add(&thread);
369*9712c20fSFrederick Mayle dump.Finish();
370*9712c20fSFrederick Mayle
371*9712c20fSFrederick Mayle string contents;
372*9712c20fSFrederick Mayle ASSERT_TRUE(dump.GetContents(&contents));
373*9712c20fSFrederick Mayle
374*9712c20fSFrederick Mayle istringstream minidump_stream(contents);
375*9712c20fSFrederick Mayle Minidump minidump(minidump_stream);
376*9712c20fSFrederick Mayle ASSERT_TRUE(minidump.Read());
377*9712c20fSFrederick Mayle ASSERT_EQ(2U, minidump.GetDirectoryEntryCount());
378*9712c20fSFrederick Mayle
379*9712c20fSFrederick Mayle // This should succeed even though the thread has no stack memory.
380*9712c20fSFrederick Mayle MinidumpThreadList* thread_list = minidump.GetThreadList();
381*9712c20fSFrederick Mayle ASSERT_TRUE(thread_list != NULL);
382*9712c20fSFrederick Mayle ASSERT_EQ(1U, thread_list->thread_count());
383*9712c20fSFrederick Mayle
384*9712c20fSFrederick Mayle MinidumpThread* md_thread = thread_list->GetThreadAtIndex(0);
385*9712c20fSFrederick Mayle ASSERT_TRUE(md_thread != NULL);
386*9712c20fSFrederick Mayle
387*9712c20fSFrederick Mayle uint32_t thread_id;
388*9712c20fSFrederick Mayle ASSERT_TRUE(md_thread->GetThreadID(&thread_id));
389*9712c20fSFrederick Mayle ASSERT_EQ(0xa898f11bU, thread_id);
390*9712c20fSFrederick Mayle
391*9712c20fSFrederick Mayle MinidumpContext* md_context = md_thread->GetContext();
392*9712c20fSFrederick Mayle ASSERT_NE(reinterpret_cast<MinidumpContext*>(NULL), md_context);
393*9712c20fSFrederick Mayle
394*9712c20fSFrederick Mayle MinidumpMemoryRegion* md_stack = md_thread->GetMemory();
395*9712c20fSFrederick Mayle ASSERT_EQ(reinterpret_cast<MinidumpMemoryRegion*>(NULL), md_stack);
396*9712c20fSFrederick Mayle }
397*9712c20fSFrederick Mayle
TEST(Dump,ThreadMissingContext)398*9712c20fSFrederick Mayle TEST(Dump, ThreadMissingContext) {
399*9712c20fSFrederick Mayle Dump dump(0, kLittleEndian);
400*9712c20fSFrederick Mayle Memory stack(dump, 0x2326a0fa);
401*9712c20fSFrederick Mayle stack.Append("stack for thread");
402*9712c20fSFrederick Mayle
403*9712c20fSFrederick Mayle // Context is empty.
404*9712c20fSFrederick Mayle Context context(dump);
405*9712c20fSFrederick Mayle
406*9712c20fSFrederick Mayle Thread thread(dump, 0xa898f11b, stack, context,
407*9712c20fSFrederick Mayle 0x9e39439f, 0x4abfc15f, 0xe499898a, 0x0d43e939dcfd0372ULL);
408*9712c20fSFrederick Mayle
409*9712c20fSFrederick Mayle dump.Add(&stack);
410*9712c20fSFrederick Mayle dump.Add(&context);
411*9712c20fSFrederick Mayle dump.Add(&thread);
412*9712c20fSFrederick Mayle dump.Finish();
413*9712c20fSFrederick Mayle
414*9712c20fSFrederick Mayle string contents;
415*9712c20fSFrederick Mayle ASSERT_TRUE(dump.GetContents(&contents));
416*9712c20fSFrederick Mayle
417*9712c20fSFrederick Mayle istringstream minidump_stream(contents);
418*9712c20fSFrederick Mayle Minidump minidump(minidump_stream);
419*9712c20fSFrederick Mayle ASSERT_TRUE(minidump.Read());
420*9712c20fSFrederick Mayle ASSERT_EQ(2U, minidump.GetDirectoryEntryCount());
421*9712c20fSFrederick Mayle
422*9712c20fSFrederick Mayle // This should succeed even though the thread has no stack memory.
423*9712c20fSFrederick Mayle MinidumpThreadList* thread_list = minidump.GetThreadList();
424*9712c20fSFrederick Mayle ASSERT_TRUE(thread_list != NULL);
425*9712c20fSFrederick Mayle ASSERT_EQ(1U, thread_list->thread_count());
426*9712c20fSFrederick Mayle
427*9712c20fSFrederick Mayle MinidumpThread* md_thread = thread_list->GetThreadAtIndex(0);
428*9712c20fSFrederick Mayle ASSERT_TRUE(md_thread != NULL);
429*9712c20fSFrederick Mayle
430*9712c20fSFrederick Mayle uint32_t thread_id;
431*9712c20fSFrederick Mayle ASSERT_TRUE(md_thread->GetThreadID(&thread_id));
432*9712c20fSFrederick Mayle ASSERT_EQ(0xa898f11bU, thread_id);
433*9712c20fSFrederick Mayle MinidumpMemoryRegion* md_stack = md_thread->GetMemory();
434*9712c20fSFrederick Mayle ASSERT_NE(reinterpret_cast<MinidumpMemoryRegion*>(NULL), md_stack);
435*9712c20fSFrederick Mayle
436*9712c20fSFrederick Mayle MinidumpContext* md_context = md_thread->GetContext();
437*9712c20fSFrederick Mayle ASSERT_EQ(reinterpret_cast<MinidumpContext*>(NULL), md_context);
438*9712c20fSFrederick Mayle }
439*9712c20fSFrederick Mayle
TEST(Dump,OneUnloadedModule)440*9712c20fSFrederick Mayle TEST(Dump, OneUnloadedModule) {
441*9712c20fSFrederick Mayle Dump dump(0, kBigEndian);
442*9712c20fSFrederick Mayle String module_name(dump, "unloaded module");
443*9712c20fSFrederick Mayle
444*9712c20fSFrederick Mayle String csd_version(dump, "Windows 9000");
445*9712c20fSFrederick Mayle SystemInfo system_info(dump, SystemInfo::windows_x86, csd_version);
446*9712c20fSFrederick Mayle
447*9712c20fSFrederick Mayle UnloadedModule unloaded_module(
448*9712c20fSFrederick Mayle dump,
449*9712c20fSFrederick Mayle 0xa90206ca83eb2852ULL,
450*9712c20fSFrederick Mayle 0xada542bd,
451*9712c20fSFrederick Mayle module_name,
452*9712c20fSFrederick Mayle 0x34571371,
453*9712c20fSFrederick Mayle 0xb1054d2a);
454*9712c20fSFrederick Mayle
455*9712c20fSFrederick Mayle dump.Add(&unloaded_module);
456*9712c20fSFrederick Mayle dump.Add(&module_name);
457*9712c20fSFrederick Mayle dump.Add(&system_info);
458*9712c20fSFrederick Mayle dump.Add(&csd_version);
459*9712c20fSFrederick Mayle dump.Finish();
460*9712c20fSFrederick Mayle
461*9712c20fSFrederick Mayle string contents;
462*9712c20fSFrederick Mayle ASSERT_TRUE(dump.GetContents(&contents));
463*9712c20fSFrederick Mayle istringstream minidump_stream(contents);
464*9712c20fSFrederick Mayle Minidump minidump(minidump_stream);
465*9712c20fSFrederick Mayle ASSERT_TRUE(minidump.Read());
466*9712c20fSFrederick Mayle ASSERT_EQ(2U, minidump.GetDirectoryEntryCount());
467*9712c20fSFrederick Mayle
468*9712c20fSFrederick Mayle const MDRawDirectory* dir = minidump.GetDirectoryEntryAtIndex(1);
469*9712c20fSFrederick Mayle ASSERT_TRUE(dir != NULL);
470*9712c20fSFrederick Mayle EXPECT_EQ((uint32_t) MD_UNLOADED_MODULE_LIST_STREAM, dir->stream_type);
471*9712c20fSFrederick Mayle
472*9712c20fSFrederick Mayle MinidumpUnloadedModuleList* md_unloaded_module_list =
473*9712c20fSFrederick Mayle minidump.GetUnloadedModuleList();
474*9712c20fSFrederick Mayle ASSERT_TRUE(md_unloaded_module_list != NULL);
475*9712c20fSFrederick Mayle ASSERT_EQ(1U, md_unloaded_module_list->module_count());
476*9712c20fSFrederick Mayle
477*9712c20fSFrederick Mayle const MinidumpUnloadedModule* md_unloaded_module =
478*9712c20fSFrederick Mayle md_unloaded_module_list->GetModuleAtIndex(0);
479*9712c20fSFrederick Mayle ASSERT_TRUE(md_unloaded_module != NULL);
480*9712c20fSFrederick Mayle ASSERT_EQ(0xa90206ca83eb2852ULL, md_unloaded_module->base_address());
481*9712c20fSFrederick Mayle ASSERT_EQ(0xada542bd, md_unloaded_module->size());
482*9712c20fSFrederick Mayle ASSERT_EQ("unloaded module", md_unloaded_module->code_file());
483*9712c20fSFrederick Mayle ASSERT_EQ("", md_unloaded_module->debug_file());
484*9712c20fSFrederick Mayle // time_date_stamp and size_of_image concatenated
485*9712c20fSFrederick Mayle ASSERT_EQ("B1054D2Aada542bd", md_unloaded_module->code_identifier());
486*9712c20fSFrederick Mayle ASSERT_EQ("", md_unloaded_module->debug_identifier());
487*9712c20fSFrederick Mayle
488*9712c20fSFrederick Mayle const MDRawUnloadedModule* md_raw_unloaded_module =
489*9712c20fSFrederick Mayle md_unloaded_module->module();
490*9712c20fSFrederick Mayle ASSERT_TRUE(md_raw_unloaded_module != NULL);
491*9712c20fSFrederick Mayle ASSERT_EQ(0xb1054d2aU, md_raw_unloaded_module->time_date_stamp);
492*9712c20fSFrederick Mayle ASSERT_EQ(0x34571371U, md_raw_unloaded_module->checksum);
493*9712c20fSFrederick Mayle }
494*9712c20fSFrederick Mayle
495*9712c20fSFrederick Mayle static const MDVSFixedFileInfo fixed_file_info = {
496*9712c20fSFrederick Mayle 0xb2fba33a, // signature
497*9712c20fSFrederick Mayle 0x33d7a728, // struct_version
498*9712c20fSFrederick Mayle 0x31afcb20, // file_version_hi
499*9712c20fSFrederick Mayle 0xe51cdab1, // file_version_lo
500*9712c20fSFrederick Mayle 0xd1ea6907, // product_version_hi
501*9712c20fSFrederick Mayle 0x03032857, // product_version_lo
502*9712c20fSFrederick Mayle 0x11bf71d7, // file_flags_mask
503*9712c20fSFrederick Mayle 0x5fb8cdbf, // file_flags
504*9712c20fSFrederick Mayle 0xe45d0d5d, // file_os
505*9712c20fSFrederick Mayle 0x107d9562, // file_type
506*9712c20fSFrederick Mayle 0x5a8844d4, // file_subtype
507*9712c20fSFrederick Mayle 0xa8d30b20, // file_date_hi
508*9712c20fSFrederick Mayle 0x651c3e4e // file_date_lo
509*9712c20fSFrederick Mayle };
510*9712c20fSFrederick Mayle
TEST(Dump,OneModule)511*9712c20fSFrederick Mayle TEST(Dump, OneModule) {
512*9712c20fSFrederick Mayle Dump dump(0, kBigEndian);
513*9712c20fSFrederick Mayle String module_name(dump, "single module");
514*9712c20fSFrederick Mayle Section cv_info(dump);
515*9712c20fSFrederick Mayle cv_info
516*9712c20fSFrederick Mayle .D32(MD_CVINFOPDB70_SIGNATURE) // signature
517*9712c20fSFrederick Mayle // signature, a MDGUID
518*9712c20fSFrederick Mayle .D32(0xabcd1234)
519*9712c20fSFrederick Mayle .D16(0xf00d)
520*9712c20fSFrederick Mayle .D16(0xbeef)
521*9712c20fSFrederick Mayle .Append("\x01\x02\x03\x04\x05\x06\x07\x08")
522*9712c20fSFrederick Mayle .D32(1) // age
523*9712c20fSFrederick Mayle .AppendCString("c:\\foo\\file.pdb"); // pdb_file_name
524*9712c20fSFrederick Mayle
525*9712c20fSFrederick Mayle String csd_version(dump, "Windows 9000");
526*9712c20fSFrederick Mayle SystemInfo system_info(dump, SystemInfo::windows_x86, csd_version);
527*9712c20fSFrederick Mayle
528*9712c20fSFrederick Mayle Module module(dump, 0xa90206ca83eb2852ULL, 0xada542bd,
529*9712c20fSFrederick Mayle module_name,
530*9712c20fSFrederick Mayle 0xb1054d2a,
531*9712c20fSFrederick Mayle 0x34571371,
532*9712c20fSFrederick Mayle fixed_file_info, // from synth_minidump_unittest_data.h
533*9712c20fSFrederick Mayle &cv_info, nullptr);
534*9712c20fSFrederick Mayle
535*9712c20fSFrederick Mayle dump.Add(&module);
536*9712c20fSFrederick Mayle dump.Add(&module_name);
537*9712c20fSFrederick Mayle dump.Add(&cv_info);
538*9712c20fSFrederick Mayle dump.Add(&system_info);
539*9712c20fSFrederick Mayle dump.Add(&csd_version);
540*9712c20fSFrederick Mayle dump.Finish();
541*9712c20fSFrederick Mayle
542*9712c20fSFrederick Mayle string contents;
543*9712c20fSFrederick Mayle ASSERT_TRUE(dump.GetContents(&contents));
544*9712c20fSFrederick Mayle istringstream minidump_stream(contents);
545*9712c20fSFrederick Mayle Minidump minidump(minidump_stream);
546*9712c20fSFrederick Mayle ASSERT_TRUE(minidump.Read());
547*9712c20fSFrederick Mayle ASSERT_EQ(2U, minidump.GetDirectoryEntryCount());
548*9712c20fSFrederick Mayle
549*9712c20fSFrederick Mayle const MDRawDirectory* dir = minidump.GetDirectoryEntryAtIndex(1);
550*9712c20fSFrederick Mayle ASSERT_TRUE(dir != NULL);
551*9712c20fSFrederick Mayle EXPECT_EQ((uint32_t) MD_MODULE_LIST_STREAM, dir->stream_type);
552*9712c20fSFrederick Mayle
553*9712c20fSFrederick Mayle MinidumpModuleList* md_module_list = minidump.GetModuleList();
554*9712c20fSFrederick Mayle ASSERT_TRUE(md_module_list != NULL);
555*9712c20fSFrederick Mayle ASSERT_EQ(1U, md_module_list->module_count());
556*9712c20fSFrederick Mayle
557*9712c20fSFrederick Mayle const MinidumpModule* md_module = md_module_list->GetModuleAtIndex(0);
558*9712c20fSFrederick Mayle ASSERT_TRUE(md_module != NULL);
559*9712c20fSFrederick Mayle ASSERT_EQ(0xa90206ca83eb2852ULL, md_module->base_address());
560*9712c20fSFrederick Mayle ASSERT_EQ(0xada542bd, md_module->size());
561*9712c20fSFrederick Mayle ASSERT_EQ("single module", md_module->code_file());
562*9712c20fSFrederick Mayle ASSERT_EQ("c:\\foo\\file.pdb", md_module->debug_file());
563*9712c20fSFrederick Mayle // time_date_stamp and size_of_image concatenated
564*9712c20fSFrederick Mayle ASSERT_EQ("B1054D2Aada542bd", md_module->code_identifier());
565*9712c20fSFrederick Mayle ASSERT_EQ("ABCD1234F00DBEEF01020304050607081", md_module->debug_identifier());
566*9712c20fSFrederick Mayle
567*9712c20fSFrederick Mayle const MDRawModule* md_raw_module = md_module->module();
568*9712c20fSFrederick Mayle ASSERT_TRUE(md_raw_module != NULL);
569*9712c20fSFrederick Mayle ASSERT_EQ(0xb1054d2aU, md_raw_module->time_date_stamp);
570*9712c20fSFrederick Mayle ASSERT_EQ(0x34571371U, md_raw_module->checksum);
571*9712c20fSFrederick Mayle ASSERT_TRUE(memcmp(&md_raw_module->version_info, &fixed_file_info,
572*9712c20fSFrederick Mayle sizeof(fixed_file_info)) == 0);
573*9712c20fSFrederick Mayle }
574*9712c20fSFrederick Mayle
575*9712c20fSFrederick Mayle // Test that a module with a MDCVInfoELF CV record is handled properly.
TEST(Dump,OneModuleCVELF)576*9712c20fSFrederick Mayle TEST(Dump, OneModuleCVELF) {
577*9712c20fSFrederick Mayle Dump dump(0, kLittleEndian);
578*9712c20fSFrederick Mayle String module_name(dump, "elf module");
579*9712c20fSFrederick Mayle Section cv_info(dump);
580*9712c20fSFrederick Mayle cv_info
581*9712c20fSFrederick Mayle .D32(MD_CVINFOELF_SIGNATURE) // signature
582*9712c20fSFrederick Mayle // build_id
583*9712c20fSFrederick Mayle .Append("\x5f\xa9\xcd\xb4\x10\x53\xdf\x1b\x86\xfa\xb7\x33\xb4\xdf"
584*9712c20fSFrederick Mayle "\x37\x38\xce\xa3\x4a\x87");
585*9712c20fSFrederick Mayle
586*9712c20fSFrederick Mayle const MDRawSystemInfo linux_x86 = {
587*9712c20fSFrederick Mayle MD_CPU_ARCHITECTURE_X86, // processor_architecture
588*9712c20fSFrederick Mayle 6, // processor_level
589*9712c20fSFrederick Mayle 0xd08, // processor_revision
590*9712c20fSFrederick Mayle 1, // number_of_processors
591*9712c20fSFrederick Mayle 0, // product_type
592*9712c20fSFrederick Mayle 0, // major_version
593*9712c20fSFrederick Mayle 0, // minor_version
594*9712c20fSFrederick Mayle 0, // build_number
595*9712c20fSFrederick Mayle MD_OS_LINUX, // platform_id
596*9712c20fSFrederick Mayle 0xdeadbeef, // csd_version_rva
597*9712c20fSFrederick Mayle 0x100, // suite_mask
598*9712c20fSFrederick Mayle 0, // reserved2
599*9712c20fSFrederick Mayle { // cpu
600*9712c20fSFrederick Mayle { // x86_cpu_info
601*9712c20fSFrederick Mayle { 0x756e6547, 0x49656e69, 0x6c65746e }, // vendor_id
602*9712c20fSFrederick Mayle 0x6d8, // version_information
603*9712c20fSFrederick Mayle 0xafe9fbff, // feature_information
604*9712c20fSFrederick Mayle 0xffffffff // amd_extended_cpu_features
605*9712c20fSFrederick Mayle }
606*9712c20fSFrederick Mayle }
607*9712c20fSFrederick Mayle };
608*9712c20fSFrederick Mayle String csd_version(dump, "Literally Linux");
609*9712c20fSFrederick Mayle SystemInfo system_info(dump, linux_x86, csd_version);
610*9712c20fSFrederick Mayle
611*9712c20fSFrederick Mayle Module module(dump, 0xa90206ca83eb2852ULL, 0xada542bd,
612*9712c20fSFrederick Mayle module_name,
613*9712c20fSFrederick Mayle 0xb1054d2a,
614*9712c20fSFrederick Mayle 0x34571371,
615*9712c20fSFrederick Mayle fixed_file_info, // from synth_minidump_unittest_data.h
616*9712c20fSFrederick Mayle &cv_info, nullptr);
617*9712c20fSFrederick Mayle
618*9712c20fSFrederick Mayle dump.Add(&module);
619*9712c20fSFrederick Mayle dump.Add(&module_name);
620*9712c20fSFrederick Mayle dump.Add(&cv_info);
621*9712c20fSFrederick Mayle dump.Add(&system_info);
622*9712c20fSFrederick Mayle dump.Add(&csd_version);
623*9712c20fSFrederick Mayle dump.Finish();
624*9712c20fSFrederick Mayle
625*9712c20fSFrederick Mayle string contents;
626*9712c20fSFrederick Mayle ASSERT_TRUE(dump.GetContents(&contents));
627*9712c20fSFrederick Mayle istringstream minidump_stream(contents);
628*9712c20fSFrederick Mayle Minidump minidump(minidump_stream);
629*9712c20fSFrederick Mayle ASSERT_TRUE(minidump.Read());
630*9712c20fSFrederick Mayle
631*9712c20fSFrederick Mayle MinidumpModuleList* md_module_list = minidump.GetModuleList();
632*9712c20fSFrederick Mayle ASSERT_TRUE(md_module_list != NULL);
633*9712c20fSFrederick Mayle ASSERT_EQ(1U, md_module_list->module_count());
634*9712c20fSFrederick Mayle
635*9712c20fSFrederick Mayle const MinidumpModule* md_module = md_module_list->GetModuleAtIndex(0);
636*9712c20fSFrederick Mayle ASSERT_TRUE(md_module != NULL);
637*9712c20fSFrederick Mayle ASSERT_EQ(0xa90206ca83eb2852ULL, md_module->base_address());
638*9712c20fSFrederick Mayle ASSERT_EQ(0xada542bd, md_module->size());
639*9712c20fSFrederick Mayle ASSERT_EQ("elf module", md_module->code_file());
640*9712c20fSFrederick Mayle // debug_file == code_file
641*9712c20fSFrederick Mayle ASSERT_EQ("elf module", md_module->debug_file());
642*9712c20fSFrederick Mayle // just the build_id, directly
643*9712c20fSFrederick Mayle ASSERT_EQ("5fa9cdb41053df1b86fab733b4df3738cea34a87",
644*9712c20fSFrederick Mayle md_module->code_identifier());
645*9712c20fSFrederick Mayle // build_id truncted to GUID length and treated as such, with zero
646*9712c20fSFrederick Mayle // age appended
647*9712c20fSFrederick Mayle ASSERT_EQ("B4CDA95F53101BDF86FAB733B4DF37380", md_module->debug_identifier());
648*9712c20fSFrederick Mayle
649*9712c20fSFrederick Mayle const MDRawModule* md_raw_module = md_module->module();
650*9712c20fSFrederick Mayle ASSERT_TRUE(md_raw_module != NULL);
651*9712c20fSFrederick Mayle ASSERT_EQ(0xb1054d2aU, md_raw_module->time_date_stamp);
652*9712c20fSFrederick Mayle ASSERT_EQ(0x34571371U, md_raw_module->checksum);
653*9712c20fSFrederick Mayle ASSERT_TRUE(memcmp(&md_raw_module->version_info, &fixed_file_info,
654*9712c20fSFrederick Mayle sizeof(fixed_file_info)) == 0);
655*9712c20fSFrederick Mayle }
656*9712c20fSFrederick Mayle
657*9712c20fSFrederick Mayle // Test that a build_id that's shorter than a GUID is handled properly.
TEST(Dump,CVELFShort)658*9712c20fSFrederick Mayle TEST(Dump, CVELFShort) {
659*9712c20fSFrederick Mayle Dump dump(0, kLittleEndian);
660*9712c20fSFrederick Mayle String module_name(dump, "elf module");
661*9712c20fSFrederick Mayle Section cv_info(dump);
662*9712c20fSFrederick Mayle cv_info
663*9712c20fSFrederick Mayle .D32(MD_CVINFOELF_SIGNATURE) // signature
664*9712c20fSFrederick Mayle // build_id, shorter than a GUID
665*9712c20fSFrederick Mayle .Append("\x5f\xa9\xcd\xb4");
666*9712c20fSFrederick Mayle
667*9712c20fSFrederick Mayle const MDRawSystemInfo linux_x86 = {
668*9712c20fSFrederick Mayle MD_CPU_ARCHITECTURE_X86, // processor_architecture
669*9712c20fSFrederick Mayle 6, // processor_level
670*9712c20fSFrederick Mayle 0xd08, // processor_revision
671*9712c20fSFrederick Mayle 1, // number_of_processors
672*9712c20fSFrederick Mayle 0, // product_type
673*9712c20fSFrederick Mayle 0, // major_version
674*9712c20fSFrederick Mayle 0, // minor_version
675*9712c20fSFrederick Mayle 0, // build_number
676*9712c20fSFrederick Mayle MD_OS_LINUX, // platform_id
677*9712c20fSFrederick Mayle 0xdeadbeef, // csd_version_rva
678*9712c20fSFrederick Mayle 0x100, // suite_mask
679*9712c20fSFrederick Mayle 0, // reserved2
680*9712c20fSFrederick Mayle { // cpu
681*9712c20fSFrederick Mayle { // x86_cpu_info
682*9712c20fSFrederick Mayle { 0x756e6547, 0x49656e69, 0x6c65746e }, // vendor_id
683*9712c20fSFrederick Mayle 0x6d8, // version_information
684*9712c20fSFrederick Mayle 0xafe9fbff, // feature_information
685*9712c20fSFrederick Mayle 0xffffffff // amd_extended_cpu_features
686*9712c20fSFrederick Mayle }
687*9712c20fSFrederick Mayle }
688*9712c20fSFrederick Mayle };
689*9712c20fSFrederick Mayle String csd_version(dump, "Literally Linux");
690*9712c20fSFrederick Mayle SystemInfo system_info(dump, linux_x86, csd_version);
691*9712c20fSFrederick Mayle
692*9712c20fSFrederick Mayle Module module(dump, 0xa90206ca83eb2852ULL, 0xada542bd,
693*9712c20fSFrederick Mayle module_name,
694*9712c20fSFrederick Mayle 0xb1054d2a,
695*9712c20fSFrederick Mayle 0x34571371,
696*9712c20fSFrederick Mayle fixed_file_info, // from synth_minidump_unittest_data.h
697*9712c20fSFrederick Mayle &cv_info, nullptr);
698*9712c20fSFrederick Mayle
699*9712c20fSFrederick Mayle dump.Add(&module);
700*9712c20fSFrederick Mayle dump.Add(&module_name);
701*9712c20fSFrederick Mayle dump.Add(&cv_info);
702*9712c20fSFrederick Mayle dump.Add(&system_info);
703*9712c20fSFrederick Mayle dump.Add(&csd_version);
704*9712c20fSFrederick Mayle dump.Finish();
705*9712c20fSFrederick Mayle
706*9712c20fSFrederick Mayle string contents;
707*9712c20fSFrederick Mayle ASSERT_TRUE(dump.GetContents(&contents));
708*9712c20fSFrederick Mayle istringstream minidump_stream(contents);
709*9712c20fSFrederick Mayle Minidump minidump(minidump_stream);
710*9712c20fSFrederick Mayle ASSERT_TRUE(minidump.Read());
711*9712c20fSFrederick Mayle ASSERT_EQ(2U, minidump.GetDirectoryEntryCount());
712*9712c20fSFrederick Mayle
713*9712c20fSFrederick Mayle MinidumpModuleList* md_module_list = minidump.GetModuleList();
714*9712c20fSFrederick Mayle ASSERT_TRUE(md_module_list != NULL);
715*9712c20fSFrederick Mayle ASSERT_EQ(1U, md_module_list->module_count());
716*9712c20fSFrederick Mayle
717*9712c20fSFrederick Mayle const MinidumpModule* md_module = md_module_list->GetModuleAtIndex(0);
718*9712c20fSFrederick Mayle ASSERT_TRUE(md_module != NULL);
719*9712c20fSFrederick Mayle // just the build_id, directly
720*9712c20fSFrederick Mayle ASSERT_EQ("5fa9cdb4", md_module->code_identifier());
721*9712c20fSFrederick Mayle // build_id expanded to GUID length and treated as such, with zero
722*9712c20fSFrederick Mayle // age appended
723*9712c20fSFrederick Mayle ASSERT_EQ("B4CDA95F0000000000000000000000000", md_module->debug_identifier());
724*9712c20fSFrederick Mayle }
725*9712c20fSFrederick Mayle
726*9712c20fSFrederick Mayle // Test that a build_id that's very long is handled properly.
TEST(Dump,CVELFLong)727*9712c20fSFrederick Mayle TEST(Dump, CVELFLong) {
728*9712c20fSFrederick Mayle Dump dump(0, kLittleEndian);
729*9712c20fSFrederick Mayle String module_name(dump, "elf module");
730*9712c20fSFrederick Mayle Section cv_info(dump);
731*9712c20fSFrederick Mayle cv_info
732*9712c20fSFrederick Mayle .D32(MD_CVINFOELF_SIGNATURE) // signature
733*9712c20fSFrederick Mayle // build_id, lots of bytes
734*9712c20fSFrederick Mayle .Append("\x5f\xa9\xcd\xb4\x10\x53\xdf\x1b\x86\xfa\xb7\x33\xb4\xdf"
735*9712c20fSFrederick Mayle "\x37\x38\xce\xa3\x4a\x87\x01\x02\x03\x04\x05\x06\x07\x08"
736*9712c20fSFrederick Mayle "\x09\x0a\x0b\x0c\x0d\x0e\x0f");
737*9712c20fSFrederick Mayle
738*9712c20fSFrederick Mayle
739*9712c20fSFrederick Mayle const MDRawSystemInfo linux_x86 = {
740*9712c20fSFrederick Mayle MD_CPU_ARCHITECTURE_X86, // processor_architecture
741*9712c20fSFrederick Mayle 6, // processor_level
742*9712c20fSFrederick Mayle 0xd08, // processor_revision
743*9712c20fSFrederick Mayle 1, // number_of_processors
744*9712c20fSFrederick Mayle 0, // product_type
745*9712c20fSFrederick Mayle 0, // major_version
746*9712c20fSFrederick Mayle 0, // minor_version
747*9712c20fSFrederick Mayle 0, // build_number
748*9712c20fSFrederick Mayle MD_OS_LINUX, // platform_id
749*9712c20fSFrederick Mayle 0xdeadbeef, // csd_version_rva
750*9712c20fSFrederick Mayle 0x100, // suite_mask
751*9712c20fSFrederick Mayle 0, // reserved2
752*9712c20fSFrederick Mayle { // cpu
753*9712c20fSFrederick Mayle { // x86_cpu_info
754*9712c20fSFrederick Mayle { 0x756e6547, 0x49656e69, 0x6c65746e }, // vendor_id
755*9712c20fSFrederick Mayle 0x6d8, // version_information
756*9712c20fSFrederick Mayle 0xafe9fbff, // feature_information
757*9712c20fSFrederick Mayle 0xffffffff // amd_extended_cpu_features
758*9712c20fSFrederick Mayle }
759*9712c20fSFrederick Mayle }
760*9712c20fSFrederick Mayle };
761*9712c20fSFrederick Mayle String csd_version(dump, "Literally Linux");
762*9712c20fSFrederick Mayle SystemInfo system_info(dump, linux_x86, csd_version);
763*9712c20fSFrederick Mayle
764*9712c20fSFrederick Mayle Module module(dump, 0xa90206ca83eb2852ULL, 0xada542bd,
765*9712c20fSFrederick Mayle module_name,
766*9712c20fSFrederick Mayle 0xb1054d2a,
767*9712c20fSFrederick Mayle 0x34571371,
768*9712c20fSFrederick Mayle fixed_file_info, // from synth_minidump_unittest_data.h
769*9712c20fSFrederick Mayle &cv_info, nullptr);
770*9712c20fSFrederick Mayle
771*9712c20fSFrederick Mayle dump.Add(&module);
772*9712c20fSFrederick Mayle dump.Add(&module_name);
773*9712c20fSFrederick Mayle dump.Add(&cv_info);
774*9712c20fSFrederick Mayle dump.Add(&system_info);
775*9712c20fSFrederick Mayle dump.Add(&csd_version);
776*9712c20fSFrederick Mayle dump.Finish();
777*9712c20fSFrederick Mayle
778*9712c20fSFrederick Mayle string contents;
779*9712c20fSFrederick Mayle ASSERT_TRUE(dump.GetContents(&contents));
780*9712c20fSFrederick Mayle istringstream minidump_stream(contents);
781*9712c20fSFrederick Mayle Minidump minidump(minidump_stream);
782*9712c20fSFrederick Mayle ASSERT_TRUE(minidump.Read());
783*9712c20fSFrederick Mayle ASSERT_EQ(2U, minidump.GetDirectoryEntryCount());
784*9712c20fSFrederick Mayle
785*9712c20fSFrederick Mayle MinidumpModuleList* md_module_list = minidump.GetModuleList();
786*9712c20fSFrederick Mayle ASSERT_TRUE(md_module_list != NULL);
787*9712c20fSFrederick Mayle ASSERT_EQ(1U, md_module_list->module_count());
788*9712c20fSFrederick Mayle
789*9712c20fSFrederick Mayle const MinidumpModule* md_module = md_module_list->GetModuleAtIndex(0);
790*9712c20fSFrederick Mayle ASSERT_TRUE(md_module != NULL);
791*9712c20fSFrederick Mayle // just the build_id, directly
792*9712c20fSFrederick Mayle ASSERT_EQ(
793*9712c20fSFrederick Mayle "5fa9cdb41053df1b86fab733b4df3738cea34a870102030405060708090a0b0c0d0e0f",
794*9712c20fSFrederick Mayle md_module->code_identifier());
795*9712c20fSFrederick Mayle // build_id truncated to GUID length and treated as such, with zero
796*9712c20fSFrederick Mayle // age appended.
797*9712c20fSFrederick Mayle ASSERT_EQ("B4CDA95F53101BDF86FAB733B4DF37380", md_module->debug_identifier());
798*9712c20fSFrederick Mayle }
799*9712c20fSFrederick Mayle
TEST(Dump,OneSystemInfo)800*9712c20fSFrederick Mayle TEST(Dump, OneSystemInfo) {
801*9712c20fSFrederick Mayle Dump dump(0, kLittleEndian);
802*9712c20fSFrederick Mayle String csd_version(dump, "Petulant Pierogi");
803*9712c20fSFrederick Mayle SystemInfo system_info(dump, SystemInfo::windows_x86, csd_version);
804*9712c20fSFrederick Mayle
805*9712c20fSFrederick Mayle dump.Add(&system_info);
806*9712c20fSFrederick Mayle dump.Add(&csd_version);
807*9712c20fSFrederick Mayle dump.Finish();
808*9712c20fSFrederick Mayle
809*9712c20fSFrederick Mayle string contents;
810*9712c20fSFrederick Mayle ASSERT_TRUE(dump.GetContents(&contents));
811*9712c20fSFrederick Mayle istringstream minidump_stream(contents);
812*9712c20fSFrederick Mayle Minidump minidump(minidump_stream);
813*9712c20fSFrederick Mayle ASSERT_TRUE(minidump.Read());
814*9712c20fSFrederick Mayle ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());
815*9712c20fSFrederick Mayle
816*9712c20fSFrederick Mayle const MDRawDirectory* dir = minidump.GetDirectoryEntryAtIndex(0);
817*9712c20fSFrederick Mayle ASSERT_TRUE(dir != NULL);
818*9712c20fSFrederick Mayle EXPECT_EQ((uint32_t) MD_SYSTEM_INFO_STREAM, dir->stream_type);
819*9712c20fSFrederick Mayle
820*9712c20fSFrederick Mayle MinidumpSystemInfo* md_system_info = minidump.GetSystemInfo();
821*9712c20fSFrederick Mayle ASSERT_TRUE(md_system_info != NULL);
822*9712c20fSFrederick Mayle ASSERT_EQ("windows", md_system_info->GetOS());
823*9712c20fSFrederick Mayle ASSERT_EQ("x86", md_system_info->GetCPU());
824*9712c20fSFrederick Mayle ASSERT_EQ("Petulant Pierogi", *md_system_info->GetCSDVersion());
825*9712c20fSFrederick Mayle ASSERT_EQ("GenuineIntel", *md_system_info->GetCPUVendor());
826*9712c20fSFrederick Mayle }
827*9712c20fSFrederick Mayle
TEST(Dump,BigDump)828*9712c20fSFrederick Mayle TEST(Dump, BigDump) {
829*9712c20fSFrederick Mayle Dump dump(0, kLittleEndian);
830*9712c20fSFrederick Mayle
831*9712c20fSFrederick Mayle // A SystemInfo stream.
832*9712c20fSFrederick Mayle String csd_version(dump, "Munificent Macaque");
833*9712c20fSFrederick Mayle SystemInfo system_info(dump, SystemInfo::windows_x86, csd_version);
834*9712c20fSFrederick Mayle dump.Add(&csd_version);
835*9712c20fSFrederick Mayle dump.Add(&system_info);
836*9712c20fSFrederick Mayle
837*9712c20fSFrederick Mayle // Five threads!
838*9712c20fSFrederick Mayle Memory stack0(dump, 0x70b9ebfc);
839*9712c20fSFrederick Mayle stack0.Append("stack for thread zero");
840*9712c20fSFrederick Mayle MDRawContextX86 raw_context0;
841*9712c20fSFrederick Mayle raw_context0.context_flags = MD_CONTEXT_X86_INTEGER;
842*9712c20fSFrederick Mayle raw_context0.eip = 0xaf0709e4;
843*9712c20fSFrederick Mayle Context context0(dump, raw_context0);
844*9712c20fSFrederick Mayle Thread thread0(dump, 0xbbef4432, stack0, context0,
845*9712c20fSFrederick Mayle 0xd0377e7b, 0xdb8eb0cf, 0xd73bc314, 0x09d357bac7f9a163ULL);
846*9712c20fSFrederick Mayle dump.Add(&stack0);
847*9712c20fSFrederick Mayle dump.Add(&context0);
848*9712c20fSFrederick Mayle dump.Add(&thread0);
849*9712c20fSFrederick Mayle
850*9712c20fSFrederick Mayle Memory stack1(dump, 0xf988cc45);
851*9712c20fSFrederick Mayle stack1.Append("stack for thread one");
852*9712c20fSFrederick Mayle MDRawContextX86 raw_context1;
853*9712c20fSFrederick Mayle raw_context1.context_flags = MD_CONTEXT_X86_INTEGER;
854*9712c20fSFrederick Mayle raw_context1.eip = 0xe4f56f81;
855*9712c20fSFrederick Mayle Context context1(dump, raw_context1);
856*9712c20fSFrederick Mayle Thread thread1(dump, 0x657c3f58, stack1, context1,
857*9712c20fSFrederick Mayle 0xa68fa182, 0x6f3cf8dd, 0xe3a78ccf, 0x78cc84775e4534bbULL);
858*9712c20fSFrederick Mayle dump.Add(&stack1);
859*9712c20fSFrederick Mayle dump.Add(&context1);
860*9712c20fSFrederick Mayle dump.Add(&thread1);
861*9712c20fSFrederick Mayle
862*9712c20fSFrederick Mayle Memory stack2(dump, 0xc8a92e7c);
863*9712c20fSFrederick Mayle stack2.Append("stack for thread two");
864*9712c20fSFrederick Mayle MDRawContextX86 raw_context2;
865*9712c20fSFrederick Mayle raw_context2.context_flags = MD_CONTEXT_X86_INTEGER;
866*9712c20fSFrederick Mayle raw_context2.eip = 0xb336a438;
867*9712c20fSFrederick Mayle Context context2(dump, raw_context2);
868*9712c20fSFrederick Mayle Thread thread2(dump, 0xdf4b8a71, stack2, context2,
869*9712c20fSFrederick Mayle 0x674c26b6, 0x445d7120, 0x7e700c56, 0xd89bf778e7793e17ULL);
870*9712c20fSFrederick Mayle dump.Add(&stack2);
871*9712c20fSFrederick Mayle dump.Add(&context2);
872*9712c20fSFrederick Mayle dump.Add(&thread2);
873*9712c20fSFrederick Mayle
874*9712c20fSFrederick Mayle Memory stack3(dump, 0x36d08e08);
875*9712c20fSFrederick Mayle stack3.Append("stack for thread three");
876*9712c20fSFrederick Mayle MDRawContextX86 raw_context3;
877*9712c20fSFrederick Mayle raw_context3.context_flags = MD_CONTEXT_X86_INTEGER;
878*9712c20fSFrederick Mayle raw_context3.eip = 0xdf99a60c;
879*9712c20fSFrederick Mayle Context context3(dump, raw_context3);
880*9712c20fSFrederick Mayle Thread thread3(dump, 0x86e6c341, stack3, context3,
881*9712c20fSFrederick Mayle 0x32dc5c55, 0x17a2aba8, 0xe0cc75e7, 0xa46393994dae83aeULL);
882*9712c20fSFrederick Mayle dump.Add(&stack3);
883*9712c20fSFrederick Mayle dump.Add(&context3);
884*9712c20fSFrederick Mayle dump.Add(&thread3);
885*9712c20fSFrederick Mayle
886*9712c20fSFrederick Mayle Memory stack4(dump, 0x1e0ab4fa);
887*9712c20fSFrederick Mayle stack4.Append("stack for thread four");
888*9712c20fSFrederick Mayle MDRawContextX86 raw_context4;
889*9712c20fSFrederick Mayle raw_context4.context_flags = MD_CONTEXT_X86_INTEGER;
890*9712c20fSFrederick Mayle raw_context4.eip = 0xaa646267;
891*9712c20fSFrederick Mayle Context context4(dump, raw_context4);
892*9712c20fSFrederick Mayle Thread thread4(dump, 0x261a28d4, stack4, context4,
893*9712c20fSFrederick Mayle 0x6ebd389e, 0xa0cd4759, 0x30168846, 0x164f650a0cf39d35ULL);
894*9712c20fSFrederick Mayle dump.Add(&stack4);
895*9712c20fSFrederick Mayle dump.Add(&context4);
896*9712c20fSFrederick Mayle dump.Add(&thread4);
897*9712c20fSFrederick Mayle
898*9712c20fSFrederick Mayle // Three modules!
899*9712c20fSFrederick Mayle String module1_name(dump, "module one");
900*9712c20fSFrederick Mayle Module module1(dump, 0xeb77da57b5d4cbdaULL, 0x83cd5a37, module1_name);
901*9712c20fSFrederick Mayle dump.Add(&module1_name);
902*9712c20fSFrederick Mayle dump.Add(&module1);
903*9712c20fSFrederick Mayle
904*9712c20fSFrederick Mayle String module2_name(dump, "module two");
905*9712c20fSFrederick Mayle Module module2(dump, 0x8675884adfe5ac90ULL, 0xb11e4ea3, module2_name);
906*9712c20fSFrederick Mayle dump.Add(&module2_name);
907*9712c20fSFrederick Mayle dump.Add(&module2);
908*9712c20fSFrederick Mayle
909*9712c20fSFrederick Mayle String module3_name(dump, "module three");
910*9712c20fSFrederick Mayle Module module3(dump, 0x95fc1544da321b6cULL, 0x7c2bf081, module3_name);
911*9712c20fSFrederick Mayle dump.Add(&module3_name);
912*9712c20fSFrederick Mayle dump.Add(&module3);
913*9712c20fSFrederick Mayle
914*9712c20fSFrederick Mayle // Unloaded modules!
915*9712c20fSFrederick Mayle uint64_t umodule1_base = 0xeb77da57b5d4cbdaULL;
916*9712c20fSFrederick Mayle uint32_t umodule1_size = 0x83cd5a37;
917*9712c20fSFrederick Mayle String umodule1_name(dump, "unloaded module one");
918*9712c20fSFrederick Mayle UnloadedModule unloaded_module1(dump, umodule1_base, umodule1_size,
919*9712c20fSFrederick Mayle umodule1_name);
920*9712c20fSFrederick Mayle dump.Add(&umodule1_name);
921*9712c20fSFrederick Mayle dump.Add(&unloaded_module1);
922*9712c20fSFrederick Mayle
923*9712c20fSFrederick Mayle uint64_t umodule2_base = 0xeb77da57b5d4cbdaULL;
924*9712c20fSFrederick Mayle uint32_t umodule2_size = 0x83cd5a37;
925*9712c20fSFrederick Mayle String umodule2_name(dump, "unloaded module two");
926*9712c20fSFrederick Mayle UnloadedModule unloaded_module2(dump, umodule2_base, umodule2_size,
927*9712c20fSFrederick Mayle umodule2_name);
928*9712c20fSFrederick Mayle dump.Add(&umodule2_name);
929*9712c20fSFrederick Mayle dump.Add(&unloaded_module2);
930*9712c20fSFrederick Mayle
931*9712c20fSFrederick Mayle uint64_t umodule3_base = 0xeb77da5839a20000ULL;
932*9712c20fSFrederick Mayle uint32_t umodule3_size = 0x83cd5a37;
933*9712c20fSFrederick Mayle String umodule3_name(dump, "unloaded module three");
934*9712c20fSFrederick Mayle UnloadedModule unloaded_module3(dump, umodule3_base, umodule3_size,
935*9712c20fSFrederick Mayle umodule3_name);
936*9712c20fSFrederick Mayle dump.Add(&umodule3_name);
937*9712c20fSFrederick Mayle dump.Add(&unloaded_module3);
938*9712c20fSFrederick Mayle
939*9712c20fSFrederick Mayle
940*9712c20fSFrederick Mayle // Add one more memory region, on top of the five stacks.
941*9712c20fSFrederick Mayle Memory memory5(dump, 0x61979e828040e564ULL);
942*9712c20fSFrederick Mayle memory5.Append("contents of memory 5");
943*9712c20fSFrederick Mayle dump.Add(&memory5);
944*9712c20fSFrederick Mayle
945*9712c20fSFrederick Mayle dump.Finish();
946*9712c20fSFrederick Mayle
947*9712c20fSFrederick Mayle string contents;
948*9712c20fSFrederick Mayle ASSERT_TRUE(dump.GetContents(&contents));
949*9712c20fSFrederick Mayle istringstream minidump_stream(contents);
950*9712c20fSFrederick Mayle Minidump minidump(minidump_stream);
951*9712c20fSFrederick Mayle ASSERT_TRUE(minidump.Read());
952*9712c20fSFrederick Mayle ASSERT_EQ(5U, minidump.GetDirectoryEntryCount());
953*9712c20fSFrederick Mayle
954*9712c20fSFrederick Mayle // Check the threads.
955*9712c20fSFrederick Mayle MinidumpThreadList* thread_list = minidump.GetThreadList();
956*9712c20fSFrederick Mayle ASSERT_TRUE(thread_list != NULL);
957*9712c20fSFrederick Mayle ASSERT_EQ(5U, thread_list->thread_count());
958*9712c20fSFrederick Mayle uint32_t thread_id;
959*9712c20fSFrederick Mayle ASSERT_TRUE(thread_list->GetThreadAtIndex(0)->GetThreadID(&thread_id));
960*9712c20fSFrederick Mayle ASSERT_EQ(0xbbef4432U, thread_id);
961*9712c20fSFrederick Mayle ASSERT_EQ(0x70b9ebfcU,
962*9712c20fSFrederick Mayle thread_list->GetThreadAtIndex(0)->GetMemory()->GetBase());
963*9712c20fSFrederick Mayle ASSERT_EQ(0xaf0709e4U,
964*9712c20fSFrederick Mayle thread_list->GetThreadAtIndex(0)->GetContext()->GetContextX86()
965*9712c20fSFrederick Mayle ->eip);
966*9712c20fSFrederick Mayle
967*9712c20fSFrederick Mayle ASSERT_TRUE(thread_list->GetThreadAtIndex(1)->GetThreadID(&thread_id));
968*9712c20fSFrederick Mayle ASSERT_EQ(0x657c3f58U, thread_id);
969*9712c20fSFrederick Mayle ASSERT_EQ(0xf988cc45U,
970*9712c20fSFrederick Mayle thread_list->GetThreadAtIndex(1)->GetMemory()->GetBase());
971*9712c20fSFrederick Mayle ASSERT_EQ(0xe4f56f81U,
972*9712c20fSFrederick Mayle thread_list->GetThreadAtIndex(1)->GetContext()->GetContextX86()
973*9712c20fSFrederick Mayle ->eip);
974*9712c20fSFrederick Mayle
975*9712c20fSFrederick Mayle ASSERT_TRUE(thread_list->GetThreadAtIndex(2)->GetThreadID(&thread_id));
976*9712c20fSFrederick Mayle ASSERT_EQ(0xdf4b8a71U, thread_id);
977*9712c20fSFrederick Mayle ASSERT_EQ(0xc8a92e7cU,
978*9712c20fSFrederick Mayle thread_list->GetThreadAtIndex(2)->GetMemory()->GetBase());
979*9712c20fSFrederick Mayle ASSERT_EQ(0xb336a438U,
980*9712c20fSFrederick Mayle thread_list->GetThreadAtIndex(2)->GetContext()->GetContextX86()
981*9712c20fSFrederick Mayle ->eip);
982*9712c20fSFrederick Mayle
983*9712c20fSFrederick Mayle ASSERT_TRUE(thread_list->GetThreadAtIndex(3)->GetThreadID(&thread_id));
984*9712c20fSFrederick Mayle ASSERT_EQ(0x86e6c341U, thread_id);
985*9712c20fSFrederick Mayle ASSERT_EQ(0x36d08e08U,
986*9712c20fSFrederick Mayle thread_list->GetThreadAtIndex(3)->GetMemory()->GetBase());
987*9712c20fSFrederick Mayle ASSERT_EQ(0xdf99a60cU,
988*9712c20fSFrederick Mayle thread_list->GetThreadAtIndex(3)->GetContext()->GetContextX86()
989*9712c20fSFrederick Mayle ->eip);
990*9712c20fSFrederick Mayle
991*9712c20fSFrederick Mayle ASSERT_TRUE(thread_list->GetThreadAtIndex(4)->GetThreadID(&thread_id));
992*9712c20fSFrederick Mayle ASSERT_EQ(0x261a28d4U, thread_id);
993*9712c20fSFrederick Mayle ASSERT_EQ(0x1e0ab4faU,
994*9712c20fSFrederick Mayle thread_list->GetThreadAtIndex(4)->GetMemory()->GetBase());
995*9712c20fSFrederick Mayle ASSERT_EQ(0xaa646267U,
996*9712c20fSFrederick Mayle thread_list->GetThreadAtIndex(4)->GetContext()->GetContextX86()
997*9712c20fSFrederick Mayle ->eip);
998*9712c20fSFrederick Mayle
999*9712c20fSFrederick Mayle // Check the modules.
1000*9712c20fSFrederick Mayle MinidumpModuleList* md_module_list = minidump.GetModuleList();
1001*9712c20fSFrederick Mayle ASSERT_TRUE(md_module_list != NULL);
1002*9712c20fSFrederick Mayle ASSERT_EQ(3U, md_module_list->module_count());
1003*9712c20fSFrederick Mayle EXPECT_EQ(0xeb77da57b5d4cbdaULL,
1004*9712c20fSFrederick Mayle md_module_list->GetModuleAtIndex(0)->base_address());
1005*9712c20fSFrederick Mayle EXPECT_EQ(0x8675884adfe5ac90ULL,
1006*9712c20fSFrederick Mayle md_module_list->GetModuleAtIndex(1)->base_address());
1007*9712c20fSFrederick Mayle EXPECT_EQ(0x95fc1544da321b6cULL,
1008*9712c20fSFrederick Mayle md_module_list->GetModuleAtIndex(2)->base_address());
1009*9712c20fSFrederick Mayle
1010*9712c20fSFrederick Mayle // Check unloaded modules
1011*9712c20fSFrederick Mayle MinidumpUnloadedModuleList* md_unloaded_module_list =
1012*9712c20fSFrederick Mayle minidump.GetUnloadedModuleList();
1013*9712c20fSFrederick Mayle ASSERT_TRUE(md_unloaded_module_list != NULL);
1014*9712c20fSFrederick Mayle ASSERT_EQ(3U, md_unloaded_module_list->module_count());
1015*9712c20fSFrederick Mayle EXPECT_EQ(umodule1_base,
1016*9712c20fSFrederick Mayle md_unloaded_module_list->GetModuleAtIndex(0)->base_address());
1017*9712c20fSFrederick Mayle EXPECT_EQ(umodule2_base,
1018*9712c20fSFrederick Mayle md_unloaded_module_list->GetModuleAtIndex(1)->base_address());
1019*9712c20fSFrederick Mayle EXPECT_EQ(umodule3_base,
1020*9712c20fSFrederick Mayle md_unloaded_module_list->GetModuleAtIndex(2)->base_address());
1021*9712c20fSFrederick Mayle
1022*9712c20fSFrederick Mayle const MinidumpUnloadedModule* umodule =
1023*9712c20fSFrederick Mayle md_unloaded_module_list->GetModuleForAddress(
1024*9712c20fSFrederick Mayle umodule1_base + umodule1_size / 2);
1025*9712c20fSFrederick Mayle EXPECT_EQ(umodule1_base, umodule->base_address());
1026*9712c20fSFrederick Mayle
1027*9712c20fSFrederick Mayle umodule = md_unloaded_module_list->GetModuleAtSequence(0);
1028*9712c20fSFrederick Mayle EXPECT_EQ(umodule1_base, umodule->base_address());
1029*9712c20fSFrederick Mayle
1030*9712c20fSFrederick Mayle EXPECT_EQ(NULL, md_unloaded_module_list->GetMainModule());
1031*9712c20fSFrederick Mayle
1032*9712c20fSFrederick Mayle }
1033*9712c20fSFrederick Mayle
TEST(Dump,OneMemoryInfo)1034*9712c20fSFrederick Mayle TEST(Dump, OneMemoryInfo) {
1035*9712c20fSFrederick Mayle Dump dump(0, kBigEndian);
1036*9712c20fSFrederick Mayle Stream stream(dump, MD_MEMORY_INFO_LIST_STREAM);
1037*9712c20fSFrederick Mayle
1038*9712c20fSFrederick Mayle // Add the MDRawMemoryInfoList header.
1039*9712c20fSFrederick Mayle const uint64_t kNumberOfEntries = 1;
1040*9712c20fSFrederick Mayle stream.D32(sizeof(MDRawMemoryInfoList)) // size_of_header
1041*9712c20fSFrederick Mayle .D32(sizeof(MDRawMemoryInfo)) // size_of_entry
1042*9712c20fSFrederick Mayle .D64(kNumberOfEntries); // number_of_entries
1043*9712c20fSFrederick Mayle
1044*9712c20fSFrederick Mayle
1045*9712c20fSFrederick Mayle // Now add a MDRawMemoryInfo entry.
1046*9712c20fSFrederick Mayle const uint64_t kBaseAddress = 0x1000;
1047*9712c20fSFrederick Mayle const uint64_t kRegionSize = 0x2000;
1048*9712c20fSFrederick Mayle stream.D64(kBaseAddress) // base_address
1049*9712c20fSFrederick Mayle .D64(kBaseAddress) // allocation_base
1050*9712c20fSFrederick Mayle .D32(MD_MEMORY_PROTECT_EXECUTE_READWRITE) // allocation_protection
1051*9712c20fSFrederick Mayle .D32(0) // __alignment1
1052*9712c20fSFrederick Mayle .D64(kRegionSize) // region_size
1053*9712c20fSFrederick Mayle .D32(MD_MEMORY_STATE_COMMIT) // state
1054*9712c20fSFrederick Mayle .D32(MD_MEMORY_PROTECT_EXECUTE_READWRITE) // protection
1055*9712c20fSFrederick Mayle .D32(MD_MEMORY_TYPE_PRIVATE) // type
1056*9712c20fSFrederick Mayle .D32(0); // __alignment2
1057*9712c20fSFrederick Mayle
1058*9712c20fSFrederick Mayle dump.Add(&stream);
1059*9712c20fSFrederick Mayle dump.Finish();
1060*9712c20fSFrederick Mayle
1061*9712c20fSFrederick Mayle string contents;
1062*9712c20fSFrederick Mayle ASSERT_TRUE(dump.GetContents(&contents));
1063*9712c20fSFrederick Mayle istringstream minidump_stream(contents);
1064*9712c20fSFrederick Mayle Minidump minidump(minidump_stream);
1065*9712c20fSFrederick Mayle ASSERT_TRUE(minidump.Read());
1066*9712c20fSFrederick Mayle ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());
1067*9712c20fSFrederick Mayle
1068*9712c20fSFrederick Mayle const MDRawDirectory* dir = minidump.GetDirectoryEntryAtIndex(0);
1069*9712c20fSFrederick Mayle ASSERT_TRUE(dir != NULL);
1070*9712c20fSFrederick Mayle EXPECT_EQ((uint32_t) MD_MEMORY_INFO_LIST_STREAM, dir->stream_type);
1071*9712c20fSFrederick Mayle
1072*9712c20fSFrederick Mayle MinidumpMemoryInfoList* info_list = minidump.GetMemoryInfoList();
1073*9712c20fSFrederick Mayle ASSERT_TRUE(info_list != NULL);
1074*9712c20fSFrederick Mayle ASSERT_EQ(1U, info_list->info_count());
1075*9712c20fSFrederick Mayle
1076*9712c20fSFrederick Mayle const MinidumpMemoryInfo* info1 = info_list->GetMemoryInfoAtIndex(0);
1077*9712c20fSFrederick Mayle ASSERT_EQ(kBaseAddress, info1->GetBase());
1078*9712c20fSFrederick Mayle ASSERT_EQ(kRegionSize, info1->GetSize());
1079*9712c20fSFrederick Mayle ASSERT_TRUE(info1->IsExecutable());
1080*9712c20fSFrederick Mayle ASSERT_TRUE(info1->IsWritable());
1081*9712c20fSFrederick Mayle
1082*9712c20fSFrederick Mayle // Should get back the same memory region here.
1083*9712c20fSFrederick Mayle const MinidumpMemoryInfo* info2 =
1084*9712c20fSFrederick Mayle info_list->GetMemoryInfoForAddress(kBaseAddress + kRegionSize / 2);
1085*9712c20fSFrederick Mayle ASSERT_EQ(kBaseAddress, info2->GetBase());
1086*9712c20fSFrederick Mayle ASSERT_EQ(kRegionSize, info2->GetSize());
1087*9712c20fSFrederick Mayle }
1088*9712c20fSFrederick Mayle
TEST(Dump,OneExceptionX86)1089*9712c20fSFrederick Mayle TEST(Dump, OneExceptionX86) {
1090*9712c20fSFrederick Mayle Dump dump(0, kLittleEndian);
1091*9712c20fSFrederick Mayle
1092*9712c20fSFrederick Mayle MDRawContextX86 raw_context;
1093*9712c20fSFrederick Mayle raw_context.context_flags = MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL;
1094*9712c20fSFrederick Mayle raw_context.edi = 0x3ecba80d;
1095*9712c20fSFrederick Mayle raw_context.esi = 0x382583b9;
1096*9712c20fSFrederick Mayle raw_context.ebx = 0x7fccc03f;
1097*9712c20fSFrederick Mayle raw_context.edx = 0xf62f8ec2;
1098*9712c20fSFrederick Mayle raw_context.ecx = 0x46a6a6a8;
1099*9712c20fSFrederick Mayle raw_context.eax = 0x6a5025e2;
1100*9712c20fSFrederick Mayle raw_context.ebp = 0xd9fabb4a;
1101*9712c20fSFrederick Mayle raw_context.eip = 0x6913f540;
1102*9712c20fSFrederick Mayle raw_context.cs = 0xbffe6eda;
1103*9712c20fSFrederick Mayle raw_context.eflags = 0xb2ce1e2d;
1104*9712c20fSFrederick Mayle raw_context.esp = 0x659caaa4;
1105*9712c20fSFrederick Mayle raw_context.ss = 0x2e951ef7;
1106*9712c20fSFrederick Mayle Context context(dump, raw_context);
1107*9712c20fSFrederick Mayle
1108*9712c20fSFrederick Mayle Exception exception(dump, context,
1109*9712c20fSFrederick Mayle 0x1234abcd, // thread id
1110*9712c20fSFrederick Mayle 0xdcba4321, // exception code
1111*9712c20fSFrederick Mayle 0xf0e0d0c0, // exception flags
1112*9712c20fSFrederick Mayle 0x0919a9b9c9d9e9f9ULL); // exception address
1113*9712c20fSFrederick Mayle
1114*9712c20fSFrederick Mayle dump.Add(&context);
1115*9712c20fSFrederick Mayle dump.Add(&exception);
1116*9712c20fSFrederick Mayle dump.Finish();
1117*9712c20fSFrederick Mayle
1118*9712c20fSFrederick Mayle string contents;
1119*9712c20fSFrederick Mayle ASSERT_TRUE(dump.GetContents(&contents));
1120*9712c20fSFrederick Mayle
1121*9712c20fSFrederick Mayle istringstream minidump_stream(contents);
1122*9712c20fSFrederick Mayle Minidump minidump(minidump_stream);
1123*9712c20fSFrederick Mayle ASSERT_TRUE(minidump.Read());
1124*9712c20fSFrederick Mayle ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());
1125*9712c20fSFrederick Mayle
1126*9712c20fSFrederick Mayle MinidumpException* md_exception = minidump.GetException();
1127*9712c20fSFrederick Mayle ASSERT_TRUE(md_exception != NULL);
1128*9712c20fSFrederick Mayle
1129*9712c20fSFrederick Mayle uint32_t thread_id;
1130*9712c20fSFrederick Mayle ASSERT_TRUE(md_exception->GetThreadID(&thread_id));
1131*9712c20fSFrederick Mayle ASSERT_EQ(0x1234abcdU, thread_id);
1132*9712c20fSFrederick Mayle
1133*9712c20fSFrederick Mayle const MDRawExceptionStream* raw_exception = md_exception->exception();
1134*9712c20fSFrederick Mayle ASSERT_TRUE(raw_exception != NULL);
1135*9712c20fSFrederick Mayle EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code);
1136*9712c20fSFrederick Mayle EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags);
1137*9712c20fSFrederick Mayle EXPECT_EQ(0x0919a9b9c9d9e9f9ULL,
1138*9712c20fSFrederick Mayle raw_exception->exception_record.exception_address);
1139*9712c20fSFrederick Mayle
1140*9712c20fSFrederick Mayle MinidumpContext* md_context = md_exception->GetContext();
1141*9712c20fSFrederick Mayle ASSERT_TRUE(md_context != NULL);
1142*9712c20fSFrederick Mayle ASSERT_EQ((uint32_t) MD_CONTEXT_X86, md_context->GetContextCPU());
1143*9712c20fSFrederick Mayle const MDRawContextX86* md_raw_context = md_context->GetContextX86();
1144*9712c20fSFrederick Mayle ASSERT_TRUE(md_raw_context != NULL);
1145*9712c20fSFrederick Mayle ASSERT_EQ((uint32_t) (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL),
1146*9712c20fSFrederick Mayle (md_raw_context->context_flags
1147*9712c20fSFrederick Mayle & (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL)));
1148*9712c20fSFrederick Mayle EXPECT_EQ(0x3ecba80dU, raw_context.edi);
1149*9712c20fSFrederick Mayle EXPECT_EQ(0x382583b9U, raw_context.esi);
1150*9712c20fSFrederick Mayle EXPECT_EQ(0x7fccc03fU, raw_context.ebx);
1151*9712c20fSFrederick Mayle EXPECT_EQ(0xf62f8ec2U, raw_context.edx);
1152*9712c20fSFrederick Mayle EXPECT_EQ(0x46a6a6a8U, raw_context.ecx);
1153*9712c20fSFrederick Mayle EXPECT_EQ(0x6a5025e2U, raw_context.eax);
1154*9712c20fSFrederick Mayle EXPECT_EQ(0xd9fabb4aU, raw_context.ebp);
1155*9712c20fSFrederick Mayle EXPECT_EQ(0x6913f540U, raw_context.eip);
1156*9712c20fSFrederick Mayle EXPECT_EQ(0xbffe6edaU, raw_context.cs);
1157*9712c20fSFrederick Mayle EXPECT_EQ(0xb2ce1e2dU, raw_context.eflags);
1158*9712c20fSFrederick Mayle EXPECT_EQ(0x659caaa4U, raw_context.esp);
1159*9712c20fSFrederick Mayle EXPECT_EQ(0x2e951ef7U, raw_context.ss);
1160*9712c20fSFrederick Mayle }
1161*9712c20fSFrederick Mayle
TEST(Dump,OneExceptionX86XState)1162*9712c20fSFrederick Mayle TEST(Dump, OneExceptionX86XState) {
1163*9712c20fSFrederick Mayle Dump dump(0, kLittleEndian);
1164*9712c20fSFrederick Mayle
1165*9712c20fSFrederick Mayle MDRawContextX86 raw_context;
1166*9712c20fSFrederick Mayle raw_context.context_flags = MD_CONTEXT_X86_INTEGER |
1167*9712c20fSFrederick Mayle MD_CONTEXT_X86_CONTROL | MD_CONTEXT_X86_XSTATE;
1168*9712c20fSFrederick Mayle raw_context.edi = 0x3ecba80d;
1169*9712c20fSFrederick Mayle raw_context.esi = 0x382583b9;
1170*9712c20fSFrederick Mayle raw_context.ebx = 0x7fccc03f;
1171*9712c20fSFrederick Mayle raw_context.edx = 0xf62f8ec2;
1172*9712c20fSFrederick Mayle raw_context.ecx = 0x46a6a6a8;
1173*9712c20fSFrederick Mayle raw_context.eax = 0x6a5025e2;
1174*9712c20fSFrederick Mayle raw_context.ebp = 0xd9fabb4a;
1175*9712c20fSFrederick Mayle raw_context.eip = 0x6913f540;
1176*9712c20fSFrederick Mayle raw_context.cs = 0xbffe6eda;
1177*9712c20fSFrederick Mayle raw_context.eflags = 0xb2ce1e2d;
1178*9712c20fSFrederick Mayle raw_context.esp = 0x659caaa4;
1179*9712c20fSFrederick Mayle raw_context.ss = 0x2e951ef7;
1180*9712c20fSFrederick Mayle Context context(dump, raw_context);
1181*9712c20fSFrederick Mayle
1182*9712c20fSFrederick Mayle Exception exception(dump, context,
1183*9712c20fSFrederick Mayle 0x1234abcd, // thread id
1184*9712c20fSFrederick Mayle 0xdcba4321, // exception code
1185*9712c20fSFrederick Mayle 0xf0e0d0c0, // exception flags
1186*9712c20fSFrederick Mayle 0x0919a9b9c9d9e9f9ULL); // exception address
1187*9712c20fSFrederick Mayle
1188*9712c20fSFrederick Mayle dump.Add(&context);
1189*9712c20fSFrederick Mayle dump.Add(&exception);
1190*9712c20fSFrederick Mayle dump.Finish();
1191*9712c20fSFrederick Mayle
1192*9712c20fSFrederick Mayle string contents;
1193*9712c20fSFrederick Mayle ASSERT_TRUE(dump.GetContents(&contents));
1194*9712c20fSFrederick Mayle
1195*9712c20fSFrederick Mayle istringstream minidump_stream(contents);
1196*9712c20fSFrederick Mayle Minidump minidump(minidump_stream);
1197*9712c20fSFrederick Mayle ASSERT_TRUE(minidump.Read());
1198*9712c20fSFrederick Mayle ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());
1199*9712c20fSFrederick Mayle
1200*9712c20fSFrederick Mayle MinidumpException* md_exception = minidump.GetException();
1201*9712c20fSFrederick Mayle ASSERT_TRUE(md_exception != NULL);
1202*9712c20fSFrederick Mayle
1203*9712c20fSFrederick Mayle uint32_t thread_id;
1204*9712c20fSFrederick Mayle ASSERT_TRUE(md_exception->GetThreadID(&thread_id));
1205*9712c20fSFrederick Mayle ASSERT_EQ(0x1234abcdU, thread_id);
1206*9712c20fSFrederick Mayle
1207*9712c20fSFrederick Mayle const MDRawExceptionStream* raw_exception = md_exception->exception();
1208*9712c20fSFrederick Mayle ASSERT_TRUE(raw_exception != NULL);
1209*9712c20fSFrederick Mayle EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code);
1210*9712c20fSFrederick Mayle EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags);
1211*9712c20fSFrederick Mayle EXPECT_EQ(0x0919a9b9c9d9e9f9ULL,
1212*9712c20fSFrederick Mayle raw_exception->exception_record.exception_address);
1213*9712c20fSFrederick Mayle
1214*9712c20fSFrederick Mayle MinidumpContext* md_context = md_exception->GetContext();
1215*9712c20fSFrederick Mayle ASSERT_TRUE(md_context != NULL);
1216*9712c20fSFrederick Mayle ASSERT_EQ((uint32_t) MD_CONTEXT_X86, md_context->GetContextCPU());
1217*9712c20fSFrederick Mayle const MDRawContextX86* md_raw_context = md_context->GetContextX86();
1218*9712c20fSFrederick Mayle ASSERT_TRUE(md_raw_context != NULL);
1219*9712c20fSFrederick Mayle ASSERT_EQ((uint32_t) (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL),
1220*9712c20fSFrederick Mayle (md_raw_context->context_flags
1221*9712c20fSFrederick Mayle & (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL)));
1222*9712c20fSFrederick Mayle EXPECT_EQ(0x3ecba80dU, raw_context.edi);
1223*9712c20fSFrederick Mayle EXPECT_EQ(0x382583b9U, raw_context.esi);
1224*9712c20fSFrederick Mayle EXPECT_EQ(0x7fccc03fU, raw_context.ebx);
1225*9712c20fSFrederick Mayle EXPECT_EQ(0xf62f8ec2U, raw_context.edx);
1226*9712c20fSFrederick Mayle EXPECT_EQ(0x46a6a6a8U, raw_context.ecx);
1227*9712c20fSFrederick Mayle EXPECT_EQ(0x6a5025e2U, raw_context.eax);
1228*9712c20fSFrederick Mayle EXPECT_EQ(0xd9fabb4aU, raw_context.ebp);
1229*9712c20fSFrederick Mayle EXPECT_EQ(0x6913f540U, raw_context.eip);
1230*9712c20fSFrederick Mayle EXPECT_EQ(0xbffe6edaU, raw_context.cs);
1231*9712c20fSFrederick Mayle EXPECT_EQ(0xb2ce1e2dU, raw_context.eflags);
1232*9712c20fSFrederick Mayle EXPECT_EQ(0x659caaa4U, raw_context.esp);
1233*9712c20fSFrederick Mayle EXPECT_EQ(0x2e951ef7U, raw_context.ss);
1234*9712c20fSFrederick Mayle }
1235*9712c20fSFrederick Mayle
1236*9712c20fSFrederick Mayle // Testing that the CPU type can be loaded from a system info stream when
1237*9712c20fSFrederick Mayle // the CPU flags are missing from the context_flags of an exception record
TEST(Dump,OneExceptionX86NoCPUFlags)1238*9712c20fSFrederick Mayle TEST(Dump, OneExceptionX86NoCPUFlags) {
1239*9712c20fSFrederick Mayle Dump dump(0, kLittleEndian);
1240*9712c20fSFrederick Mayle
1241*9712c20fSFrederick Mayle MDRawContextX86 raw_context;
1242*9712c20fSFrederick Mayle // Intentionally not setting CPU type in the context_flags
1243*9712c20fSFrederick Mayle raw_context.context_flags = 0;
1244*9712c20fSFrederick Mayle raw_context.edi = 0x3ecba80d;
1245*9712c20fSFrederick Mayle raw_context.esi = 0x382583b9;
1246*9712c20fSFrederick Mayle raw_context.ebx = 0x7fccc03f;
1247*9712c20fSFrederick Mayle raw_context.edx = 0xf62f8ec2;
1248*9712c20fSFrederick Mayle raw_context.ecx = 0x46a6a6a8;
1249*9712c20fSFrederick Mayle raw_context.eax = 0x6a5025e2;
1250*9712c20fSFrederick Mayle raw_context.ebp = 0xd9fabb4a;
1251*9712c20fSFrederick Mayle raw_context.eip = 0x6913f540;
1252*9712c20fSFrederick Mayle raw_context.cs = 0xbffe6eda;
1253*9712c20fSFrederick Mayle raw_context.eflags = 0xb2ce1e2d;
1254*9712c20fSFrederick Mayle raw_context.esp = 0x659caaa4;
1255*9712c20fSFrederick Mayle raw_context.ss = 0x2e951ef7;
1256*9712c20fSFrederick Mayle Context context(dump, raw_context);
1257*9712c20fSFrederick Mayle
1258*9712c20fSFrederick Mayle Exception exception(dump, context,
1259*9712c20fSFrederick Mayle 0x1234abcd, // thread id
1260*9712c20fSFrederick Mayle 0xdcba4321, // exception code
1261*9712c20fSFrederick Mayle 0xf0e0d0c0, // exception flags
1262*9712c20fSFrederick Mayle 0x0919a9b9c9d9e9f9ULL); // exception address
1263*9712c20fSFrederick Mayle
1264*9712c20fSFrederick Mayle dump.Add(&context);
1265*9712c20fSFrederick Mayle dump.Add(&exception);
1266*9712c20fSFrederick Mayle
1267*9712c20fSFrederick Mayle // Add system info. This is needed as an alternative source for CPU type
1268*9712c20fSFrederick Mayle // information. Note, that the CPU flags were intentionally skipped from
1269*9712c20fSFrederick Mayle // the context_flags and this alternative source is required.
1270*9712c20fSFrederick Mayle String csd_version(dump, "Service Pack 2");
1271*9712c20fSFrederick Mayle SystemInfo system_info(dump, SystemInfo::windows_x86, csd_version);
1272*9712c20fSFrederick Mayle dump.Add(&system_info);
1273*9712c20fSFrederick Mayle dump.Add(&csd_version);
1274*9712c20fSFrederick Mayle
1275*9712c20fSFrederick Mayle dump.Finish();
1276*9712c20fSFrederick Mayle
1277*9712c20fSFrederick Mayle string contents;
1278*9712c20fSFrederick Mayle ASSERT_TRUE(dump.GetContents(&contents));
1279*9712c20fSFrederick Mayle
1280*9712c20fSFrederick Mayle istringstream minidump_stream(contents);
1281*9712c20fSFrederick Mayle Minidump minidump(minidump_stream);
1282*9712c20fSFrederick Mayle ASSERT_TRUE(minidump.Read());
1283*9712c20fSFrederick Mayle ASSERT_EQ(2U, minidump.GetDirectoryEntryCount());
1284*9712c20fSFrederick Mayle
1285*9712c20fSFrederick Mayle MinidumpException* md_exception = minidump.GetException();
1286*9712c20fSFrederick Mayle ASSERT_TRUE(md_exception != NULL);
1287*9712c20fSFrederick Mayle
1288*9712c20fSFrederick Mayle uint32_t thread_id;
1289*9712c20fSFrederick Mayle ASSERT_TRUE(md_exception->GetThreadID(&thread_id));
1290*9712c20fSFrederick Mayle ASSERT_EQ(0x1234abcdU, thread_id);
1291*9712c20fSFrederick Mayle
1292*9712c20fSFrederick Mayle const MDRawExceptionStream* raw_exception = md_exception->exception();
1293*9712c20fSFrederick Mayle ASSERT_TRUE(raw_exception != NULL);
1294*9712c20fSFrederick Mayle EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code);
1295*9712c20fSFrederick Mayle EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags);
1296*9712c20fSFrederick Mayle EXPECT_EQ(0x0919a9b9c9d9e9f9ULL,
1297*9712c20fSFrederick Mayle raw_exception->exception_record.exception_address);
1298*9712c20fSFrederick Mayle
1299*9712c20fSFrederick Mayle MinidumpContext* md_context = md_exception->GetContext();
1300*9712c20fSFrederick Mayle ASSERT_TRUE(md_context != NULL);
1301*9712c20fSFrederick Mayle
1302*9712c20fSFrederick Mayle ASSERT_EQ((uint32_t) MD_CONTEXT_X86, md_context->GetContextCPU());
1303*9712c20fSFrederick Mayle const MDRawContextX86* md_raw_context = md_context->GetContextX86();
1304*9712c20fSFrederick Mayle ASSERT_TRUE(md_raw_context != NULL);
1305*9712c20fSFrederick Mayle
1306*9712c20fSFrederick Mayle // Even though the CPU flags were missing from the context_flags, the
1307*9712c20fSFrederick Mayle // GetContext call above is expected to load the missing CPU flags from the
1308*9712c20fSFrederick Mayle // system info stream and set the CPU type bits in context_flags.
1309*9712c20fSFrederick Mayle ASSERT_EQ((uint32_t) (MD_CONTEXT_X86), md_raw_context->context_flags);
1310*9712c20fSFrederick Mayle
1311*9712c20fSFrederick Mayle EXPECT_EQ(0x3ecba80dU, raw_context.edi);
1312*9712c20fSFrederick Mayle EXPECT_EQ(0x382583b9U, raw_context.esi);
1313*9712c20fSFrederick Mayle EXPECT_EQ(0x7fccc03fU, raw_context.ebx);
1314*9712c20fSFrederick Mayle EXPECT_EQ(0xf62f8ec2U, raw_context.edx);
1315*9712c20fSFrederick Mayle EXPECT_EQ(0x46a6a6a8U, raw_context.ecx);
1316*9712c20fSFrederick Mayle EXPECT_EQ(0x6a5025e2U, raw_context.eax);
1317*9712c20fSFrederick Mayle EXPECT_EQ(0xd9fabb4aU, raw_context.ebp);
1318*9712c20fSFrederick Mayle EXPECT_EQ(0x6913f540U, raw_context.eip);
1319*9712c20fSFrederick Mayle EXPECT_EQ(0xbffe6edaU, raw_context.cs);
1320*9712c20fSFrederick Mayle EXPECT_EQ(0xb2ce1e2dU, raw_context.eflags);
1321*9712c20fSFrederick Mayle EXPECT_EQ(0x659caaa4U, raw_context.esp);
1322*9712c20fSFrederick Mayle EXPECT_EQ(0x2e951ef7U, raw_context.ss);
1323*9712c20fSFrederick Mayle }
1324*9712c20fSFrederick Mayle
1325*9712c20fSFrederick Mayle // This test covers a scenario where a dump contains an exception but the
1326*9712c20fSFrederick Mayle // context record of the exception is missing the CPU type information in its
1327*9712c20fSFrederick Mayle // context_flags. The dump has no system info stream so it is imposible to
1328*9712c20fSFrederick Mayle // deduce the CPU type, hence the context record is unusable.
TEST(Dump,OneExceptionX86NoCPUFlagsNoSystemInfo)1329*9712c20fSFrederick Mayle TEST(Dump, OneExceptionX86NoCPUFlagsNoSystemInfo) {
1330*9712c20fSFrederick Mayle Dump dump(0, kLittleEndian);
1331*9712c20fSFrederick Mayle
1332*9712c20fSFrederick Mayle MDRawContextX86 raw_context;
1333*9712c20fSFrederick Mayle // Intentionally not setting CPU type in the context_flags
1334*9712c20fSFrederick Mayle raw_context.context_flags = 0;
1335*9712c20fSFrederick Mayle raw_context.edi = 0x3ecba80d;
1336*9712c20fSFrederick Mayle raw_context.esi = 0x382583b9;
1337*9712c20fSFrederick Mayle raw_context.ebx = 0x7fccc03f;
1338*9712c20fSFrederick Mayle raw_context.edx = 0xf62f8ec2;
1339*9712c20fSFrederick Mayle raw_context.ecx = 0x46a6a6a8;
1340*9712c20fSFrederick Mayle raw_context.eax = 0x6a5025e2;
1341*9712c20fSFrederick Mayle raw_context.ebp = 0xd9fabb4a;
1342*9712c20fSFrederick Mayle raw_context.eip = 0x6913f540;
1343*9712c20fSFrederick Mayle raw_context.cs = 0xbffe6eda;
1344*9712c20fSFrederick Mayle raw_context.eflags = 0xb2ce1e2d;
1345*9712c20fSFrederick Mayle raw_context.esp = 0x659caaa4;
1346*9712c20fSFrederick Mayle raw_context.ss = 0x2e951ef7;
1347*9712c20fSFrederick Mayle Context context(dump, raw_context);
1348*9712c20fSFrederick Mayle
1349*9712c20fSFrederick Mayle Exception exception(dump, context,
1350*9712c20fSFrederick Mayle 0x1234abcd, // thread id
1351*9712c20fSFrederick Mayle 0xdcba4321, // exception code
1352*9712c20fSFrederick Mayle 0xf0e0d0c0, // exception flags
1353*9712c20fSFrederick Mayle 0x0919a9b9c9d9e9f9ULL); // exception address
1354*9712c20fSFrederick Mayle
1355*9712c20fSFrederick Mayle dump.Add(&context);
1356*9712c20fSFrederick Mayle dump.Add(&exception);
1357*9712c20fSFrederick Mayle dump.Finish();
1358*9712c20fSFrederick Mayle
1359*9712c20fSFrederick Mayle string contents;
1360*9712c20fSFrederick Mayle ASSERT_TRUE(dump.GetContents(&contents));
1361*9712c20fSFrederick Mayle
1362*9712c20fSFrederick Mayle istringstream minidump_stream(contents);
1363*9712c20fSFrederick Mayle Minidump minidump(minidump_stream);
1364*9712c20fSFrederick Mayle ASSERT_TRUE(minidump.Read());
1365*9712c20fSFrederick Mayle ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());
1366*9712c20fSFrederick Mayle
1367*9712c20fSFrederick Mayle MinidumpException* md_exception = minidump.GetException();
1368*9712c20fSFrederick Mayle ASSERT_TRUE(md_exception != NULL);
1369*9712c20fSFrederick Mayle
1370*9712c20fSFrederick Mayle uint32_t thread_id;
1371*9712c20fSFrederick Mayle ASSERT_TRUE(md_exception->GetThreadID(&thread_id));
1372*9712c20fSFrederick Mayle ASSERT_EQ(0x1234abcdU, thread_id);
1373*9712c20fSFrederick Mayle
1374*9712c20fSFrederick Mayle const MDRawExceptionStream* raw_exception = md_exception->exception();
1375*9712c20fSFrederick Mayle ASSERT_TRUE(raw_exception != NULL);
1376*9712c20fSFrederick Mayle EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code);
1377*9712c20fSFrederick Mayle EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags);
1378*9712c20fSFrederick Mayle EXPECT_EQ(0x0919a9b9c9d9e9f9ULL,
1379*9712c20fSFrederick Mayle raw_exception->exception_record.exception_address);
1380*9712c20fSFrederick Mayle
1381*9712c20fSFrederick Mayle // The context record of the exception is unusable because the context_flags
1382*9712c20fSFrederick Mayle // don't have CPU type information and at the same time the minidump lacks
1383*9712c20fSFrederick Mayle // system info stream so it is impossible to deduce the CPU type.
1384*9712c20fSFrederick Mayle MinidumpContext* md_context = md_exception->GetContext();
1385*9712c20fSFrederick Mayle ASSERT_EQ(NULL, md_context);
1386*9712c20fSFrederick Mayle }
1387*9712c20fSFrederick Mayle
TEST(Dump,OneExceptionARM)1388*9712c20fSFrederick Mayle TEST(Dump, OneExceptionARM) {
1389*9712c20fSFrederick Mayle Dump dump(0, kLittleEndian);
1390*9712c20fSFrederick Mayle
1391*9712c20fSFrederick Mayle MDRawContextARM raw_context;
1392*9712c20fSFrederick Mayle raw_context.context_flags = MD_CONTEXT_ARM_INTEGER;
1393*9712c20fSFrederick Mayle raw_context.iregs[0] = 0x3ecba80d;
1394*9712c20fSFrederick Mayle raw_context.iregs[1] = 0x382583b9;
1395*9712c20fSFrederick Mayle raw_context.iregs[2] = 0x7fccc03f;
1396*9712c20fSFrederick Mayle raw_context.iregs[3] = 0xf62f8ec2;
1397*9712c20fSFrederick Mayle raw_context.iregs[4] = 0x46a6a6a8;
1398*9712c20fSFrederick Mayle raw_context.iregs[5] = 0x6a5025e2;
1399*9712c20fSFrederick Mayle raw_context.iregs[6] = 0xd9fabb4a;
1400*9712c20fSFrederick Mayle raw_context.iregs[7] = 0x6913f540;
1401*9712c20fSFrederick Mayle raw_context.iregs[8] = 0xbffe6eda;
1402*9712c20fSFrederick Mayle raw_context.iregs[9] = 0xb2ce1e2d;
1403*9712c20fSFrederick Mayle raw_context.iregs[10] = 0x659caaa4;
1404*9712c20fSFrederick Mayle raw_context.iregs[11] = 0xf0e0d0c0;
1405*9712c20fSFrederick Mayle raw_context.iregs[12] = 0xa9b8c7d6;
1406*9712c20fSFrederick Mayle raw_context.iregs[13] = 0x12345678;
1407*9712c20fSFrederick Mayle raw_context.iregs[14] = 0xabcd1234;
1408*9712c20fSFrederick Mayle raw_context.iregs[15] = 0x10203040;
1409*9712c20fSFrederick Mayle raw_context.cpsr = 0x2e951ef7;
1410*9712c20fSFrederick Mayle Context context(dump, raw_context);
1411*9712c20fSFrederick Mayle
1412*9712c20fSFrederick Mayle Exception exception(dump, context,
1413*9712c20fSFrederick Mayle 0x1234abcd, // thread id
1414*9712c20fSFrederick Mayle 0xdcba4321, // exception code
1415*9712c20fSFrederick Mayle 0xf0e0d0c0, // exception flags
1416*9712c20fSFrederick Mayle 0x0919a9b9c9d9e9f9ULL); // exception address
1417*9712c20fSFrederick Mayle
1418*9712c20fSFrederick Mayle dump.Add(&context);
1419*9712c20fSFrederick Mayle dump.Add(&exception);
1420*9712c20fSFrederick Mayle dump.Finish();
1421*9712c20fSFrederick Mayle
1422*9712c20fSFrederick Mayle string contents;
1423*9712c20fSFrederick Mayle ASSERT_TRUE(dump.GetContents(&contents));
1424*9712c20fSFrederick Mayle
1425*9712c20fSFrederick Mayle istringstream minidump_stream(contents);
1426*9712c20fSFrederick Mayle Minidump minidump(minidump_stream);
1427*9712c20fSFrederick Mayle ASSERT_TRUE(minidump.Read());
1428*9712c20fSFrederick Mayle ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());
1429*9712c20fSFrederick Mayle
1430*9712c20fSFrederick Mayle MinidumpException* md_exception = minidump.GetException();
1431*9712c20fSFrederick Mayle ASSERT_TRUE(md_exception != NULL);
1432*9712c20fSFrederick Mayle
1433*9712c20fSFrederick Mayle uint32_t thread_id;
1434*9712c20fSFrederick Mayle ASSERT_TRUE(md_exception->GetThreadID(&thread_id));
1435*9712c20fSFrederick Mayle ASSERT_EQ(0x1234abcdU, thread_id);
1436*9712c20fSFrederick Mayle
1437*9712c20fSFrederick Mayle const MDRawExceptionStream* raw_exception = md_exception->exception();
1438*9712c20fSFrederick Mayle ASSERT_TRUE(raw_exception != NULL);
1439*9712c20fSFrederick Mayle EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code);
1440*9712c20fSFrederick Mayle EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags);
1441*9712c20fSFrederick Mayle EXPECT_EQ(0x0919a9b9c9d9e9f9ULL,
1442*9712c20fSFrederick Mayle raw_exception->exception_record.exception_address);
1443*9712c20fSFrederick Mayle
1444*9712c20fSFrederick Mayle MinidumpContext* md_context = md_exception->GetContext();
1445*9712c20fSFrederick Mayle ASSERT_TRUE(md_context != NULL);
1446*9712c20fSFrederick Mayle ASSERT_EQ((uint32_t) MD_CONTEXT_ARM, md_context->GetContextCPU());
1447*9712c20fSFrederick Mayle const MDRawContextARM* md_raw_context = md_context->GetContextARM();
1448*9712c20fSFrederick Mayle ASSERT_TRUE(md_raw_context != NULL);
1449*9712c20fSFrederick Mayle ASSERT_EQ((uint32_t) MD_CONTEXT_ARM_INTEGER,
1450*9712c20fSFrederick Mayle (md_raw_context->context_flags
1451*9712c20fSFrederick Mayle & MD_CONTEXT_ARM_INTEGER));
1452*9712c20fSFrederick Mayle EXPECT_EQ(0x3ecba80dU, raw_context.iregs[0]);
1453*9712c20fSFrederick Mayle EXPECT_EQ(0x382583b9U, raw_context.iregs[1]);
1454*9712c20fSFrederick Mayle EXPECT_EQ(0x7fccc03fU, raw_context.iregs[2]);
1455*9712c20fSFrederick Mayle EXPECT_EQ(0xf62f8ec2U, raw_context.iregs[3]);
1456*9712c20fSFrederick Mayle EXPECT_EQ(0x46a6a6a8U, raw_context.iregs[4]);
1457*9712c20fSFrederick Mayle EXPECT_EQ(0x6a5025e2U, raw_context.iregs[5]);
1458*9712c20fSFrederick Mayle EXPECT_EQ(0xd9fabb4aU, raw_context.iregs[6]);
1459*9712c20fSFrederick Mayle EXPECT_EQ(0x6913f540U, raw_context.iregs[7]);
1460*9712c20fSFrederick Mayle EXPECT_EQ(0xbffe6edaU, raw_context.iregs[8]);
1461*9712c20fSFrederick Mayle EXPECT_EQ(0xb2ce1e2dU, raw_context.iregs[9]);
1462*9712c20fSFrederick Mayle EXPECT_EQ(0x659caaa4U, raw_context.iregs[10]);
1463*9712c20fSFrederick Mayle EXPECT_EQ(0xf0e0d0c0U, raw_context.iregs[11]);
1464*9712c20fSFrederick Mayle EXPECT_EQ(0xa9b8c7d6U, raw_context.iregs[12]);
1465*9712c20fSFrederick Mayle EXPECT_EQ(0x12345678U, raw_context.iregs[13]);
1466*9712c20fSFrederick Mayle EXPECT_EQ(0xabcd1234U, raw_context.iregs[14]);
1467*9712c20fSFrederick Mayle EXPECT_EQ(0x10203040U, raw_context.iregs[15]);
1468*9712c20fSFrederick Mayle EXPECT_EQ(0x2e951ef7U, raw_context.cpsr);
1469*9712c20fSFrederick Mayle }
1470*9712c20fSFrederick Mayle
TEST(Dump,OneExceptionARMOldFlags)1471*9712c20fSFrederick Mayle TEST(Dump, OneExceptionARMOldFlags) {
1472*9712c20fSFrederick Mayle Dump dump(0, kLittleEndian);
1473*9712c20fSFrederick Mayle
1474*9712c20fSFrederick Mayle MDRawContextARM raw_context;
1475*9712c20fSFrederick Mayle // MD_CONTEXT_ARM_INTEGER, but with _OLD
1476*9712c20fSFrederick Mayle raw_context.context_flags = MD_CONTEXT_ARM_OLD | 0x00000002;
1477*9712c20fSFrederick Mayle raw_context.iregs[0] = 0x3ecba80d;
1478*9712c20fSFrederick Mayle raw_context.iregs[1] = 0x382583b9;
1479*9712c20fSFrederick Mayle raw_context.iregs[2] = 0x7fccc03f;
1480*9712c20fSFrederick Mayle raw_context.iregs[3] = 0xf62f8ec2;
1481*9712c20fSFrederick Mayle raw_context.iregs[4] = 0x46a6a6a8;
1482*9712c20fSFrederick Mayle raw_context.iregs[5] = 0x6a5025e2;
1483*9712c20fSFrederick Mayle raw_context.iregs[6] = 0xd9fabb4a;
1484*9712c20fSFrederick Mayle raw_context.iregs[7] = 0x6913f540;
1485*9712c20fSFrederick Mayle raw_context.iregs[8] = 0xbffe6eda;
1486*9712c20fSFrederick Mayle raw_context.iregs[9] = 0xb2ce1e2d;
1487*9712c20fSFrederick Mayle raw_context.iregs[10] = 0x659caaa4;
1488*9712c20fSFrederick Mayle raw_context.iregs[11] = 0xf0e0d0c0;
1489*9712c20fSFrederick Mayle raw_context.iregs[12] = 0xa9b8c7d6;
1490*9712c20fSFrederick Mayle raw_context.iregs[13] = 0x12345678;
1491*9712c20fSFrederick Mayle raw_context.iregs[14] = 0xabcd1234;
1492*9712c20fSFrederick Mayle raw_context.iregs[15] = 0x10203040;
1493*9712c20fSFrederick Mayle raw_context.cpsr = 0x2e951ef7;
1494*9712c20fSFrederick Mayle Context context(dump, raw_context);
1495*9712c20fSFrederick Mayle
1496*9712c20fSFrederick Mayle Exception exception(dump, context,
1497*9712c20fSFrederick Mayle 0x1234abcd, // thread id
1498*9712c20fSFrederick Mayle 0xdcba4321, // exception code
1499*9712c20fSFrederick Mayle 0xf0e0d0c0, // exception flags
1500*9712c20fSFrederick Mayle 0x0919a9b9c9d9e9f9ULL); // exception address
1501*9712c20fSFrederick Mayle
1502*9712c20fSFrederick Mayle dump.Add(&context);
1503*9712c20fSFrederick Mayle dump.Add(&exception);
1504*9712c20fSFrederick Mayle dump.Finish();
1505*9712c20fSFrederick Mayle
1506*9712c20fSFrederick Mayle string contents;
1507*9712c20fSFrederick Mayle ASSERT_TRUE(dump.GetContents(&contents));
1508*9712c20fSFrederick Mayle
1509*9712c20fSFrederick Mayle istringstream minidump_stream(contents);
1510*9712c20fSFrederick Mayle Minidump minidump(minidump_stream);
1511*9712c20fSFrederick Mayle ASSERT_TRUE(minidump.Read());
1512*9712c20fSFrederick Mayle ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());
1513*9712c20fSFrederick Mayle
1514*9712c20fSFrederick Mayle MinidumpException* md_exception = minidump.GetException();
1515*9712c20fSFrederick Mayle ASSERT_TRUE(md_exception != NULL);
1516*9712c20fSFrederick Mayle
1517*9712c20fSFrederick Mayle uint32_t thread_id;
1518*9712c20fSFrederick Mayle ASSERT_TRUE(md_exception->GetThreadID(&thread_id));
1519*9712c20fSFrederick Mayle ASSERT_EQ(0x1234abcdU, thread_id);
1520*9712c20fSFrederick Mayle
1521*9712c20fSFrederick Mayle const MDRawExceptionStream* raw_exception = md_exception->exception();
1522*9712c20fSFrederick Mayle ASSERT_TRUE(raw_exception != NULL);
1523*9712c20fSFrederick Mayle EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code);
1524*9712c20fSFrederick Mayle EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags);
1525*9712c20fSFrederick Mayle EXPECT_EQ(0x0919a9b9c9d9e9f9ULL,
1526*9712c20fSFrederick Mayle raw_exception->exception_record.exception_address);
1527*9712c20fSFrederick Mayle
1528*9712c20fSFrederick Mayle MinidumpContext* md_context = md_exception->GetContext();
1529*9712c20fSFrederick Mayle ASSERT_TRUE(md_context != NULL);
1530*9712c20fSFrederick Mayle ASSERT_EQ((uint32_t) MD_CONTEXT_ARM, md_context->GetContextCPU());
1531*9712c20fSFrederick Mayle const MDRawContextARM* md_raw_context = md_context->GetContextARM();
1532*9712c20fSFrederick Mayle ASSERT_TRUE(md_raw_context != NULL);
1533*9712c20fSFrederick Mayle ASSERT_EQ((uint32_t) MD_CONTEXT_ARM_INTEGER,
1534*9712c20fSFrederick Mayle (md_raw_context->context_flags
1535*9712c20fSFrederick Mayle & MD_CONTEXT_ARM_INTEGER));
1536*9712c20fSFrederick Mayle EXPECT_EQ(0x3ecba80dU, raw_context.iregs[0]);
1537*9712c20fSFrederick Mayle EXPECT_EQ(0x382583b9U, raw_context.iregs[1]);
1538*9712c20fSFrederick Mayle EXPECT_EQ(0x7fccc03fU, raw_context.iregs[2]);
1539*9712c20fSFrederick Mayle EXPECT_EQ(0xf62f8ec2U, raw_context.iregs[3]);
1540*9712c20fSFrederick Mayle EXPECT_EQ(0x46a6a6a8U, raw_context.iregs[4]);
1541*9712c20fSFrederick Mayle EXPECT_EQ(0x6a5025e2U, raw_context.iregs[5]);
1542*9712c20fSFrederick Mayle EXPECT_EQ(0xd9fabb4aU, raw_context.iregs[6]);
1543*9712c20fSFrederick Mayle EXPECT_EQ(0x6913f540U, raw_context.iregs[7]);
1544*9712c20fSFrederick Mayle EXPECT_EQ(0xbffe6edaU, raw_context.iregs[8]);
1545*9712c20fSFrederick Mayle EXPECT_EQ(0xb2ce1e2dU, raw_context.iregs[9]);
1546*9712c20fSFrederick Mayle EXPECT_EQ(0x659caaa4U, raw_context.iregs[10]);
1547*9712c20fSFrederick Mayle EXPECT_EQ(0xf0e0d0c0U, raw_context.iregs[11]);
1548*9712c20fSFrederick Mayle EXPECT_EQ(0xa9b8c7d6U, raw_context.iregs[12]);
1549*9712c20fSFrederick Mayle EXPECT_EQ(0x12345678U, raw_context.iregs[13]);
1550*9712c20fSFrederick Mayle EXPECT_EQ(0xabcd1234U, raw_context.iregs[14]);
1551*9712c20fSFrederick Mayle EXPECT_EQ(0x10203040U, raw_context.iregs[15]);
1552*9712c20fSFrederick Mayle EXPECT_EQ(0x2e951ef7U, raw_context.cpsr);
1553*9712c20fSFrederick Mayle }
1554*9712c20fSFrederick Mayle
TEST(Dump,OneExceptionMIPS)1555*9712c20fSFrederick Mayle TEST(Dump, OneExceptionMIPS) {
1556*9712c20fSFrederick Mayle Dump dump(0, kLittleEndian);
1557*9712c20fSFrederick Mayle
1558*9712c20fSFrederick Mayle MDRawContextMIPS raw_context;
1559*9712c20fSFrederick Mayle raw_context.context_flags = MD_CONTEXT_MIPS_INTEGER;
1560*9712c20fSFrederick Mayle raw_context.iregs[0] = 0x3ecba80d;
1561*9712c20fSFrederick Mayle raw_context.iregs[1] = 0x382583b9;
1562*9712c20fSFrederick Mayle raw_context.iregs[2] = 0x7fccc03f;
1563*9712c20fSFrederick Mayle raw_context.iregs[3] = 0xf62f8ec2;
1564*9712c20fSFrederick Mayle raw_context.iregs[4] = 0x46a6a6a8;
1565*9712c20fSFrederick Mayle raw_context.iregs[5] = 0x6a5025e2;
1566*9712c20fSFrederick Mayle raw_context.iregs[6] = 0xd9fabb4a;
1567*9712c20fSFrederick Mayle raw_context.iregs[7] = 0x6913f540;
1568*9712c20fSFrederick Mayle raw_context.iregs[8] = 0xbffe6eda;
1569*9712c20fSFrederick Mayle raw_context.iregs[9] = 0xb2ce1e2d;
1570*9712c20fSFrederick Mayle raw_context.iregs[10] = 0x659caaa4;
1571*9712c20fSFrederick Mayle raw_context.iregs[11] = 0xf0e0d0c0;
1572*9712c20fSFrederick Mayle raw_context.iregs[12] = 0xa9b8c7d6;
1573*9712c20fSFrederick Mayle raw_context.iregs[13] = 0x12345678;
1574*9712c20fSFrederick Mayle raw_context.iregs[14] = 0xabcd1234;
1575*9712c20fSFrederick Mayle raw_context.iregs[15] = 0x10203040;
1576*9712c20fSFrederick Mayle raw_context.iregs[16] = 0xa80d3ecb;
1577*9712c20fSFrederick Mayle raw_context.iregs[17] = 0x83b93825;
1578*9712c20fSFrederick Mayle raw_context.iregs[18] = 0xc03f7fcc;
1579*9712c20fSFrederick Mayle raw_context.iregs[19] = 0x8ec2f62f;
1580*9712c20fSFrederick Mayle raw_context.iregs[20] = 0xa6a846a6;
1581*9712c20fSFrederick Mayle raw_context.iregs[21] = 0x25e26a50;
1582*9712c20fSFrederick Mayle raw_context.iregs[22] = 0xbb4ad9fa;
1583*9712c20fSFrederick Mayle raw_context.iregs[23] = 0xf5406913;
1584*9712c20fSFrederick Mayle raw_context.iregs[24] = 0x6edabffe;
1585*9712c20fSFrederick Mayle raw_context.iregs[25] = 0x1e2db2ce;
1586*9712c20fSFrederick Mayle raw_context.iregs[26] = 0xaaa4659c;
1587*9712c20fSFrederick Mayle raw_context.iregs[27] = 0xd0c0f0e0;
1588*9712c20fSFrederick Mayle raw_context.iregs[28] = 0xc7d6a9b8;
1589*9712c20fSFrederick Mayle raw_context.iregs[29] = 0x56781234;
1590*9712c20fSFrederick Mayle raw_context.iregs[30] = 0x1234abcd;
1591*9712c20fSFrederick Mayle raw_context.iregs[31] = 0x30401020;
1592*9712c20fSFrederick Mayle
1593*9712c20fSFrederick Mayle Context context(dump, raw_context);
1594*9712c20fSFrederick Mayle
1595*9712c20fSFrederick Mayle Exception exception(dump, context,
1596*9712c20fSFrederick Mayle 0x1234abcd, // Thread id.
1597*9712c20fSFrederick Mayle 0xdcba4321, // Exception code.
1598*9712c20fSFrederick Mayle 0xf0e0d0c0, // Exception flags.
1599*9712c20fSFrederick Mayle 0x0919a9b9); // Exception address.
1600*9712c20fSFrederick Mayle
1601*9712c20fSFrederick Mayle dump.Add(&context);
1602*9712c20fSFrederick Mayle dump.Add(&exception);
1603*9712c20fSFrederick Mayle dump.Finish();
1604*9712c20fSFrederick Mayle
1605*9712c20fSFrederick Mayle string contents;
1606*9712c20fSFrederick Mayle ASSERT_TRUE(dump.GetContents(&contents));
1607*9712c20fSFrederick Mayle
1608*9712c20fSFrederick Mayle istringstream minidump_stream(contents);
1609*9712c20fSFrederick Mayle Minidump minidump(minidump_stream);
1610*9712c20fSFrederick Mayle ASSERT_TRUE(minidump.Read());
1611*9712c20fSFrederick Mayle ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());
1612*9712c20fSFrederick Mayle
1613*9712c20fSFrederick Mayle MinidumpException* md_exception = minidump.GetException();
1614*9712c20fSFrederick Mayle ASSERT_TRUE(md_exception != NULL);
1615*9712c20fSFrederick Mayle
1616*9712c20fSFrederick Mayle uint32_t thread_id;
1617*9712c20fSFrederick Mayle ASSERT_TRUE(md_exception->GetThreadID(&thread_id));
1618*9712c20fSFrederick Mayle ASSERT_EQ(0x1234abcdU, thread_id);
1619*9712c20fSFrederick Mayle
1620*9712c20fSFrederick Mayle const MDRawExceptionStream* raw_exception = md_exception->exception();
1621*9712c20fSFrederick Mayle ASSERT_TRUE(raw_exception != NULL);
1622*9712c20fSFrederick Mayle EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code);
1623*9712c20fSFrederick Mayle EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags);
1624*9712c20fSFrederick Mayle EXPECT_EQ(0x0919a9b9U,
1625*9712c20fSFrederick Mayle raw_exception->exception_record.exception_address);
1626*9712c20fSFrederick Mayle
1627*9712c20fSFrederick Mayle MinidumpContext* md_context = md_exception->GetContext();
1628*9712c20fSFrederick Mayle ASSERT_TRUE(md_context != NULL);
1629*9712c20fSFrederick Mayle ASSERT_EQ((uint32_t) MD_CONTEXT_MIPS, md_context->GetContextCPU());
1630*9712c20fSFrederick Mayle const MDRawContextMIPS* md_raw_context = md_context->GetContextMIPS();
1631*9712c20fSFrederick Mayle ASSERT_TRUE(md_raw_context != NULL);
1632*9712c20fSFrederick Mayle ASSERT_EQ((uint32_t) MD_CONTEXT_MIPS_INTEGER,
1633*9712c20fSFrederick Mayle (md_raw_context->context_flags & MD_CONTEXT_MIPS_INTEGER));
1634*9712c20fSFrederick Mayle EXPECT_EQ(0x3ecba80dU, raw_context.iregs[0]);
1635*9712c20fSFrederick Mayle EXPECT_EQ(0x382583b9U, raw_context.iregs[1]);
1636*9712c20fSFrederick Mayle EXPECT_EQ(0x7fccc03fU, raw_context.iregs[2]);
1637*9712c20fSFrederick Mayle EXPECT_EQ(0xf62f8ec2U, raw_context.iregs[3]);
1638*9712c20fSFrederick Mayle EXPECT_EQ(0x46a6a6a8U, raw_context.iregs[4]);
1639*9712c20fSFrederick Mayle EXPECT_EQ(0x6a5025e2U, raw_context.iregs[5]);
1640*9712c20fSFrederick Mayle EXPECT_EQ(0xd9fabb4aU, raw_context.iregs[6]);
1641*9712c20fSFrederick Mayle EXPECT_EQ(0x6913f540U, raw_context.iregs[7]);
1642*9712c20fSFrederick Mayle EXPECT_EQ(0xbffe6edaU, raw_context.iregs[8]);
1643*9712c20fSFrederick Mayle EXPECT_EQ(0xb2ce1e2dU, raw_context.iregs[9]);
1644*9712c20fSFrederick Mayle EXPECT_EQ(0x659caaa4U, raw_context.iregs[10]);
1645*9712c20fSFrederick Mayle EXPECT_EQ(0xf0e0d0c0U, raw_context.iregs[11]);
1646*9712c20fSFrederick Mayle EXPECT_EQ(0xa9b8c7d6U, raw_context.iregs[12]);
1647*9712c20fSFrederick Mayle EXPECT_EQ(0x12345678U, raw_context.iregs[13]);
1648*9712c20fSFrederick Mayle EXPECT_EQ(0xabcd1234U, raw_context.iregs[14]);
1649*9712c20fSFrederick Mayle EXPECT_EQ(0x10203040U, raw_context.iregs[15]);
1650*9712c20fSFrederick Mayle EXPECT_EQ(0xa80d3ecbU, raw_context.iregs[16]);
1651*9712c20fSFrederick Mayle EXPECT_EQ(0x83b93825U, raw_context.iregs[17]);
1652*9712c20fSFrederick Mayle EXPECT_EQ(0xc03f7fccU, raw_context.iregs[18]);
1653*9712c20fSFrederick Mayle EXPECT_EQ(0x8ec2f62fU, raw_context.iregs[19]);
1654*9712c20fSFrederick Mayle EXPECT_EQ(0xa6a846a6U, raw_context.iregs[20]);
1655*9712c20fSFrederick Mayle EXPECT_EQ(0x25e26a50U, raw_context.iregs[21]);
1656*9712c20fSFrederick Mayle EXPECT_EQ(0xbb4ad9faU, raw_context.iregs[22]);
1657*9712c20fSFrederick Mayle EXPECT_EQ(0xf5406913U, raw_context.iregs[23]);
1658*9712c20fSFrederick Mayle EXPECT_EQ(0x6edabffeU, raw_context.iregs[24]);
1659*9712c20fSFrederick Mayle EXPECT_EQ(0x1e2db2ceU, raw_context.iregs[25]);
1660*9712c20fSFrederick Mayle EXPECT_EQ(0xaaa4659cU, raw_context.iregs[26]);
1661*9712c20fSFrederick Mayle EXPECT_EQ(0xd0c0f0e0U, raw_context.iregs[27]);
1662*9712c20fSFrederick Mayle EXPECT_EQ(0xc7d6a9b8U, raw_context.iregs[28]);
1663*9712c20fSFrederick Mayle EXPECT_EQ(0x56781234U, raw_context.iregs[29]);
1664*9712c20fSFrederick Mayle EXPECT_EQ(0x1234abcdU, raw_context.iregs[30]);
1665*9712c20fSFrederick Mayle EXPECT_EQ(0x30401020U, raw_context.iregs[31]);
1666*9712c20fSFrederick Mayle }
1667*9712c20fSFrederick Mayle
1668*9712c20fSFrederick Mayle } // namespace
1669