xref: /aosp_15_r20/external/google-breakpad/src/processor/synth_minidump_unittest.cc (revision 9712c20fc9bbfbac4935993a2ca0b3958c5adad2)
1 // Copyright 2010 Google LLC
2 //
3 // Redistribution and use in source and binary forms, with or without
4 // modification, are permitted provided that the following conditions are
5 // met:
6 //
7 //     * Redistributions of source code must retain the above copyright
8 // notice, this list of conditions and the following disclaimer.
9 //     * Redistributions in binary form must reproduce the above
10 // copyright notice, this list of conditions and the following disclaimer
11 // in the documentation and/or other materials provided with the
12 // distribution.
13 //     * Neither the name of Google LLC nor the names of its
14 // contributors may be used to endorse or promote products derived from
15 // this software without specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 
29 // Original author: Jim Blandy <[email protected]> <[email protected]>
30 
31 // synth_minidump_unittest.cc: Unit tests for google_breakpad::SynthMinidump
32 // classes.
33 
34 #ifdef HAVE_CONFIG_H
35 #include <config.h>  // Must come first
36 #endif
37 
38 #include <sstream>
39 #include <string>
40 
41 #include "breakpad_googletest_includes.h"
42 #include "common/using_std_string.h"
43 #include "google_breakpad/common/minidump_format.h"
44 #include "processor/synth_minidump.h"
45 #include "processor/synth_minidump_unittest_data.h"
46 
47 using google_breakpad::SynthMinidump::Context;
48 using google_breakpad::SynthMinidump::Dump;
49 using google_breakpad::SynthMinidump::Exception;
50 using google_breakpad::SynthMinidump::List;
51 using google_breakpad::SynthMinidump::Memory;
52 using google_breakpad::SynthMinidump::Module;
53 using google_breakpad::SynthMinidump::Section;
54 using google_breakpad::SynthMinidump::Stream;
55 using google_breakpad::SynthMinidump::String;
56 using google_breakpad::SynthMinidump::SystemInfo;
57 using google_breakpad::test_assembler::kBigEndian;
58 using google_breakpad::test_assembler::kLittleEndian;
59 using google_breakpad::test_assembler::Label;
60 
TEST(Section,Simple)61 TEST(Section, Simple) {
62   Dump dump(0);
63   Section section(dump);
64   section.L32(0x12345678);
65   section.Finish(0);
66   string contents;
67   ASSERT_TRUE(section.GetContents(&contents));
68   EXPECT_EQ(string("\x78\x56\x34\x12", 4), contents);
69 }
70 
TEST(Section,CiteLocationIn)71 TEST(Section, CiteLocationIn) {
72   Dump dump(0, kBigEndian);
73   Section section1(dump), section2(dump);
74   section1.Append("order");
75   section2.Append("mayhem");
76   section2.Finish(0x32287ec2);
77   section2.CiteLocationIn(&section1);
78   string contents;
79   ASSERT_TRUE(section1.GetContents(&contents));
80   string expected("order\0\0\0\x06\x32\x28\x7e\xc2", 13);
81   EXPECT_EQ(expected, contents);
82 }
83 
TEST(Stream,CiteStreamIn)84 TEST(Stream, CiteStreamIn) {
85   Dump dump(0, kLittleEndian);
86   Stream stream(dump, 0x40cae2b3);
87   Section section(dump);
88   stream.Append("stream contents");
89   section.Append("section contents");
90   stream.Finish(0x41424344);
91   stream.CiteStreamIn(&section);
92   string contents;
93   ASSERT_TRUE(section.GetContents(&contents));
94   string expected("section contents"
95                   "\xb3\xe2\xca\x40"
96                   "\x0f\0\0\0"
97                   "\x44\x43\x42\x41",
98                   16 + 4 + 4 + 4);
99   EXPECT_EQ(expected, contents);
100 }
101 
TEST(Memory,CiteMemoryIn)102 TEST(Memory, CiteMemoryIn) {
103   Dump dump(0, kBigEndian);
104   Memory memory(dump, 0x76d010874ab019f9ULL);
105   Section section(dump);
106   memory.Append("memory contents");
107   section.Append("section contents");
108   memory.Finish(0x51525354);
109   memory.CiteMemoryIn(&section);
110   string contents;
111   ASSERT_TRUE(section.GetContents(&contents));
112   string expected("section contents"
113                   "\x76\xd0\x10\x87\x4a\xb0\x19\xf9"
114                   "\0\0\0\x0f"
115                   "\x51\x52\x53\x54",
116                   16 + 8 + 4 + 4);
117   EXPECT_EQ(contents, expected);
118 }
119 
TEST(Memory,Here)120 TEST(Memory, Here) {
121   Dump dump(0, kBigEndian);
122   Memory memory(dump, 0x89979731eb060ed4ULL);
123   memory.Append(1729, 42);
124   Label l = memory.Here();
125   ASSERT_EQ(0x89979731eb060ed4ULL + 1729, l.Value());
126 }
127 
TEST(Context,X86)128 TEST(Context, X86) {
129   Dump dump(0, kLittleEndian);
130   assert(x86_raw_context.context_flags & MD_CONTEXT_X86);
131   Context context(dump, x86_raw_context);
132   string contents;
133   ASSERT_TRUE(context.GetContents(&contents));
134   EXPECT_EQ(sizeof(x86_expected_contents), contents.size());
135   EXPECT_TRUE(memcmp(contents.data(), x86_expected_contents, contents.size())
136               == 0);
137 }
138 
TEST(Context,ARM)139 TEST(Context, ARM) {
140   Dump dump(0, kLittleEndian);
141   assert(arm_raw_context.context_flags & MD_CONTEXT_ARM);
142   Context context(dump, arm_raw_context);
143   string contents;
144   ASSERT_TRUE(context.GetContents(&contents));
145   EXPECT_EQ(sizeof(arm_expected_contents), contents.size());
146   EXPECT_TRUE(memcmp(contents.data(), arm_expected_contents, contents.size())
147               == 0);
148 }
149 
TEST(ContextDeathTest,X86BadFlags)150 TEST(ContextDeathTest, X86BadFlags) {
151   Dump dump(0, kLittleEndian);
152   MDRawContextX86 raw;
153   raw.context_flags = MD_CONTEXT_AMD64;
154   ASSERT_DEATH(Context context(dump, raw);,
155                "context\\.context_flags & (0x[0-9a-f]+|MD_CONTEXT_X86)");
156 }
157 
TEST(ContextDeathTest,X86BadEndianness)158 TEST(ContextDeathTest, X86BadEndianness) {
159   Dump dump(0, kBigEndian);
160   MDRawContextX86 raw;
161   raw.context_flags = MD_CONTEXT_X86;
162   ASSERT_DEATH(Context context(dump, raw);,
163                "dump\\.endianness\\(\\) == kLittleEndian");
164 }
165 
TEST(Thread,Simple)166 TEST(Thread, Simple) {
167   Dump dump(0, kLittleEndian);
168   Context context(dump, x86_raw_context);
169   context.Finish(0x8665da0c);
170   Memory stack(dump, 0xaad55a93cc3c0efcULL);
171   stack.Append("stack contents");
172   stack.Finish(0xe08cdbd1);
173   google_breakpad::SynthMinidump::Thread thread(
174       dump, 0x3d7ec360, stack, context,
175       0x3593f44d, // suspend count
176       0xab352b82, // priority class
177       0x2753d838, // priority
178       0xeb2de4be3f29e3e9ULL); // thread environment block
179   string contents;
180   ASSERT_TRUE(thread.GetContents(&contents));
181   static const uint8_t expected_bytes[] = {
182     0x60, 0xc3, 0x7e, 0x3d, // thread id
183     0x4d, 0xf4, 0x93, 0x35, // suspend count
184     0x82, 0x2b, 0x35, 0xab, // priority class
185     0x38, 0xd8, 0x53, 0x27, // priority
186     0xe9, 0xe3, 0x29, 0x3f, 0xbe, 0xe4, 0x2d, 0xeb, // thread environment block
187     0xfc, 0x0e, 0x3c, 0xcc, 0x93, 0x5a, 0xd5, 0xaa, // stack address
188     0x0e, 0x00, 0x00, 0x00, // stack size
189     0xd1, 0xdb, 0x8c, 0xe0, // stack MDRVA
190     0xcc, 0x02, 0x00, 0x00, // context size
191     0x0c, 0xda, 0x65, 0x86  // context MDRVA
192   };
193   EXPECT_EQ(sizeof(expected_bytes), contents.size());
194   EXPECT_TRUE(memcmp(contents.data(), expected_bytes, contents.size()) == 0);
195 }
196 
TEST(Exception,Simple)197 TEST(Exception, Simple) {
198   Dump dump(0, kLittleEndian);
199   Context context(dump, x86_raw_context);
200   context.Finish(0x8665da0c);
201 
202   Exception exception(dump, context,
203                       0x1234abcd, // thread id
204                       0xdcba4321, // exception code
205                       0xf0e0d0c0, // exception flags
206                       0x0919a9b9c9d9e9f9ULL); // exception address
207   string contents;
208   ASSERT_TRUE(exception.GetContents(&contents));
209   static const uint8_t expected_bytes[] = {
210     0xcd, 0xab, 0x34, 0x12, // thread id
211     0x00, 0x00, 0x00, 0x00, // __align
212     0x21, 0x43, 0xba, 0xdc, // exception code
213     0xc0, 0xd0, 0xe0, 0xf0, // exception flags
214     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception record
215     0xf9, 0xe9, 0xd9, 0xc9, 0xb9, 0xa9, 0x19, 0x09, // exception address
216     0x00, 0x00, 0x00, 0x00, // number parameters
217     0x00, 0x00, 0x00, 0x00, // __align
218     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information
219     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information
220     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information
221     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information
222     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information
223     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information
224     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information
225     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information
226     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information
227     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information
228     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information
229     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information
230     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information
231     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information
232     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information
233     0xcc, 0x02, 0x00, 0x00, // context size
234     0x0c, 0xda, 0x65, 0x86  // context MDRVA
235   };
236   EXPECT_EQ(sizeof(expected_bytes), contents.size());
237   EXPECT_TRUE(memcmp(contents.data(), expected_bytes, contents.size()) == 0);
238 }
239 
TEST(String,Simple)240 TEST(String, Simple) {
241   Dump dump(0, kBigEndian);
242   String s(dump, "All mimsy were the borogoves");
243   string contents;
244   ASSERT_TRUE(s.GetContents(&contents));
245   static const char expected[] =
246     "\x00\x00\x00\x38\0A\0l\0l\0 \0m\0i\0m\0s\0y\0 \0w\0e\0r\0e"
247     "\0 \0t\0h\0e\0 \0b\0o\0r\0o\0g\0o\0v\0e\0s";
248   string expected_string(expected, sizeof(expected) - 1);
249   EXPECT_EQ(expected_string, contents);
250 }
251 
TEST(String,CiteStringIn)252 TEST(String, CiteStringIn) {
253   Dump dump(0, kLittleEndian);
254   String s(dump, "and the mome wraths outgrabe");
255   Section section(dump);
256   section.Append("initial");
257   s.CiteStringIn(&section);
258   s.Finish(0xdc2bb469);
259   string contents;
260   ASSERT_TRUE(section.GetContents(&contents));
261   EXPECT_EQ(string("initial\x69\xb4\x2b\xdc", 7 + 4), contents);
262 }
263 
TEST(List,Empty)264 TEST(List, Empty) {
265   Dump dump(0, kBigEndian);
266   List<Section> list(dump, 0x2442779c);
267   EXPECT_TRUE(list.Empty());
268   list.Finish(0x84e09808);
269   string contents;
270   ASSERT_TRUE(list.GetContents(&contents));
271   EXPECT_EQ(string("\0\0\0\0", 4), contents);
272 }
273 
TEST(List,Two)274 TEST(List, Two) {
275   Dump dump(0, kBigEndian);
276   List<Section> list(dump, 0x26c9f498);
277   Section section1(dump);
278   section1.Append("section one contents");
279   EXPECT_TRUE(list.Empty());
280   list.Add(&section1);
281   EXPECT_FALSE(list.Empty());
282   Section section2(dump);
283   section2.Append("section two contents");
284   list.Add(&section2);
285   list.Finish(0x1e5bb60e);
286   string contents;
287   ASSERT_TRUE(list.GetContents(&contents));
288   EXPECT_EQ(string("\0\0\0\x02section one contentssection two contents", 44),
289             contents);
290 }
291 
TEST(Dump,Header)292 TEST(Dump, Header) {
293   Dump dump(0x9f738b33685cc84cULL, kLittleEndian, 0xb3817faf, 0x2c741c0a);
294   dump.Finish();
295   string contents;
296   ASSERT_TRUE(dump.GetContents(&contents));
297   ASSERT_EQ(string("\x4d\x44\x4d\x50"   // signature
298                    "\xaf\x7f\x81\xb3"   // version
299                    "\0\0\0\0"           // stream count
300                    "\x20\0\0\0"         // directory RVA (could be anything)
301                    "\0\0\0\0"           // checksum
302                    "\x0a\x1c\x74\x2c"   // time_date_stamp
303                    "\x4c\xc8\x5c\x68\x33\x8b\x73\x9f", // flags
304                    32),
305             contents);
306 }
307 
TEST(Dump,HeaderBigEndian)308 TEST(Dump, HeaderBigEndian) {
309   Dump dump(0x206ce3cc6fb8e0f0ULL, kBigEndian, 0x161693e2, 0x35667744);
310   dump.Finish();
311   string contents;
312   ASSERT_TRUE(dump.GetContents(&contents));
313   ASSERT_EQ(string("\x50\x4d\x44\x4d"   // signature
314                    "\x16\x16\x93\xe2"   // version
315                    "\0\0\0\0"           // stream count
316                    "\0\0\0\x20"         // directory RVA (could be anything)
317                    "\0\0\0\0"           // checksum
318                    "\x35\x66\x77\x44"   // time_date_stamp
319                    "\x20\x6c\xe3\xcc\x6f\xb8\xe0\xf0", // flags
320                    32),
321             contents);
322 }
323 
TEST(Dump,OneSection)324 TEST(Dump, OneSection) {
325   Dump dump(0, kLittleEndian);
326   Section section(dump);
327   section.Append("section contents");
328   dump.Add(&section);
329   dump.Finish();
330   string dump_contents;
331   // Just check for undefined labels; don't worry about the contents.
332   ASSERT_TRUE(dump.GetContents(&dump_contents));
333 
334   Section referencing_section(dump);
335   section.CiteLocationIn(&referencing_section);
336   string contents;
337   ASSERT_TRUE(referencing_section.GetContents(&contents));
338   ASSERT_EQ(string("\x10\0\0\0\x20\0\0\0", 8), contents);
339 }
340