1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/crashreporter/google-breakpad/src/processor/synth_minidump_unittest.cc Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,336 @@ 1.4 +// Copyright (c) 2010, Google Inc. 1.5 +// All rights reserved. 1.6 +// 1.7 +// Redistribution and use in source and binary forms, with or without 1.8 +// modification, are permitted provided that the following conditions are 1.9 +// met: 1.10 +// 1.11 +// * Redistributions of source code must retain the above copyright 1.12 +// notice, this list of conditions and the following disclaimer. 1.13 +// * Redistributions in binary form must reproduce the above 1.14 +// copyright notice, this list of conditions and the following disclaimer 1.15 +// in the documentation and/or other materials provided with the 1.16 +// distribution. 1.17 +// * Neither the name of Google Inc. nor the names of its 1.18 +// contributors may be used to endorse or promote products derived from 1.19 +// this software without specific prior written permission. 1.20 +// 1.21 +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1.22 +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1.23 +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1.24 +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1.25 +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1.26 +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1.27 +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1.28 +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1.29 +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1.30 +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1.31 +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1.32 + 1.33 +// Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com> 1.34 + 1.35 +// synth_minidump_unittest.cc: Unit tests for google_breakpad::SynthMinidump 1.36 +// classes. 1.37 + 1.38 +#include <sstream> 1.39 +#include <string> 1.40 + 1.41 +#include "breakpad_googletest_includes.h" 1.42 +#include "common/using_std_string.h" 1.43 +#include "google_breakpad/common/minidump_format.h" 1.44 +#include "processor/synth_minidump.h" 1.45 +#include "processor/synth_minidump_unittest_data.h" 1.46 + 1.47 +using google_breakpad::SynthMinidump::Context; 1.48 +using google_breakpad::SynthMinidump::Dump; 1.49 +using google_breakpad::SynthMinidump::Exception; 1.50 +using google_breakpad::SynthMinidump::List; 1.51 +using google_breakpad::SynthMinidump::Memory; 1.52 +using google_breakpad::SynthMinidump::Module; 1.53 +using google_breakpad::SynthMinidump::Section; 1.54 +using google_breakpad::SynthMinidump::Stream; 1.55 +using google_breakpad::SynthMinidump::String; 1.56 +using google_breakpad::SynthMinidump::SystemInfo; 1.57 +using google_breakpad::test_assembler::kBigEndian; 1.58 +using google_breakpad::test_assembler::kLittleEndian; 1.59 +using google_breakpad::test_assembler::Label; 1.60 + 1.61 +TEST(Section, Simple) { 1.62 + Dump dump(0); 1.63 + Section section(dump); 1.64 + section.L32(0x12345678); 1.65 + section.Finish(0); 1.66 + string contents; 1.67 + ASSERT_TRUE(section.GetContents(&contents)); 1.68 + EXPECT_EQ(string("\x78\x56\x34\x12", 4), contents); 1.69 +} 1.70 + 1.71 +TEST(Section, CiteLocationIn) { 1.72 + Dump dump(0, kBigEndian); 1.73 + Section section1(dump), section2(dump); 1.74 + section1.Append("order"); 1.75 + section2.Append("mayhem"); 1.76 + section2.Finish(0x32287ec2); 1.77 + section2.CiteLocationIn(§ion1); 1.78 + string contents; 1.79 + ASSERT_TRUE(section1.GetContents(&contents)); 1.80 + string expected("order\0\0\0\x06\x32\x28\x7e\xc2", 13); 1.81 + EXPECT_EQ(expected, contents); 1.82 +} 1.83 + 1.84 +TEST(Stream, CiteStreamIn) { 1.85 + Dump dump(0, kLittleEndian); 1.86 + Stream stream(dump, 0x40cae2b3); 1.87 + Section section(dump); 1.88 + stream.Append("stream contents"); 1.89 + section.Append("section contents"); 1.90 + stream.Finish(0x41424344); 1.91 + stream.CiteStreamIn(§ion); 1.92 + string contents; 1.93 + ASSERT_TRUE(section.GetContents(&contents)); 1.94 + string expected("section contents" 1.95 + "\xb3\xe2\xca\x40" 1.96 + "\x0f\0\0\0" 1.97 + "\x44\x43\x42\x41", 1.98 + 16 + 4 + 4 + 4); 1.99 + EXPECT_EQ(expected, contents); 1.100 +} 1.101 + 1.102 +TEST(Memory, CiteMemoryIn) { 1.103 + Dump dump(0, kBigEndian); 1.104 + Memory memory(dump, 0x76d010874ab019f9ULL); 1.105 + Section section(dump); 1.106 + memory.Append("memory contents"); 1.107 + section.Append("section contents"); 1.108 + memory.Finish(0x51525354); 1.109 + memory.CiteMemoryIn(§ion); 1.110 + string contents; 1.111 + ASSERT_TRUE(section.GetContents(&contents)); 1.112 + string expected("section contents" 1.113 + "\x76\xd0\x10\x87\x4a\xb0\x19\xf9" 1.114 + "\0\0\0\x0f" 1.115 + "\x51\x52\x53\x54", 1.116 + 16 + 8 + 4 + 4); 1.117 + EXPECT_EQ(contents, expected); 1.118 +} 1.119 + 1.120 +TEST(Memory, Here) { 1.121 + Dump dump(0, kBigEndian); 1.122 + Memory memory(dump, 0x89979731eb060ed4ULL); 1.123 + memory.Append(1729, 42); 1.124 + Label l = memory.Here(); 1.125 + ASSERT_EQ(0x89979731eb060ed4ULL + 1729, l.Value()); 1.126 +} 1.127 + 1.128 +TEST(Context, X86) { 1.129 + Dump dump(0, kLittleEndian); 1.130 + assert(x86_raw_context.context_flags & MD_CONTEXT_X86); 1.131 + Context context(dump, x86_raw_context); 1.132 + string contents; 1.133 + ASSERT_TRUE(context.GetContents(&contents)); 1.134 + EXPECT_EQ(sizeof(x86_expected_contents), contents.size()); 1.135 + EXPECT_TRUE(memcmp(contents.data(), x86_expected_contents, contents.size()) 1.136 + == 0); 1.137 +} 1.138 + 1.139 +TEST(Context, ARM) { 1.140 + Dump dump(0, kLittleEndian); 1.141 + assert(arm_raw_context.context_flags & MD_CONTEXT_ARM); 1.142 + Context context(dump, arm_raw_context); 1.143 + string contents; 1.144 + ASSERT_TRUE(context.GetContents(&contents)); 1.145 + EXPECT_EQ(sizeof(arm_expected_contents), contents.size()); 1.146 + EXPECT_TRUE(memcmp(contents.data(), arm_expected_contents, contents.size()) 1.147 + == 0); 1.148 +} 1.149 + 1.150 +TEST(ContextDeathTest, X86BadFlags) { 1.151 + Dump dump(0, kLittleEndian); 1.152 + MDRawContextX86 raw; 1.153 + raw.context_flags = MD_CONTEXT_AMD64; 1.154 + ASSERT_DEATH(Context context(dump, raw);, 1.155 + "context\\.context_flags & (0x[0-9a-f]+|MD_CONTEXT_X86)"); 1.156 +} 1.157 + 1.158 +TEST(ContextDeathTest, X86BadEndianness) { 1.159 + Dump dump(0, kBigEndian); 1.160 + MDRawContextX86 raw; 1.161 + raw.context_flags = MD_CONTEXT_X86; 1.162 + ASSERT_DEATH(Context context(dump, raw);, 1.163 + "dump\\.endianness\\(\\) == kLittleEndian"); 1.164 +} 1.165 + 1.166 +TEST(Thread, Simple) { 1.167 + Dump dump(0, kLittleEndian); 1.168 + Context context(dump, x86_raw_context); 1.169 + context.Finish(0x8665da0c); 1.170 + Memory stack(dump, 0xaad55a93cc3c0efcULL); 1.171 + stack.Append("stack contents"); 1.172 + stack.Finish(0xe08cdbd1); 1.173 + google_breakpad::SynthMinidump::Thread thread( 1.174 + dump, 0x3d7ec360, stack, context, 1.175 + 0x3593f44d, // suspend count 1.176 + 0xab352b82, // priority class 1.177 + 0x2753d838, // priority 1.178 + 0xeb2de4be3f29e3e9ULL); // thread environment block 1.179 + string contents; 1.180 + ASSERT_TRUE(thread.GetContents(&contents)); 1.181 + static const uint8_t expected_bytes[] = { 1.182 + 0x60, 0xc3, 0x7e, 0x3d, // thread id 1.183 + 0x4d, 0xf4, 0x93, 0x35, // suspend count 1.184 + 0x82, 0x2b, 0x35, 0xab, // priority class 1.185 + 0x38, 0xd8, 0x53, 0x27, // priority 1.186 + 0xe9, 0xe3, 0x29, 0x3f, 0xbe, 0xe4, 0x2d, 0xeb, // thread environment block 1.187 + 0xfc, 0x0e, 0x3c, 0xcc, 0x93, 0x5a, 0xd5, 0xaa, // stack address 1.188 + 0x0e, 0x00, 0x00, 0x00, // stack size 1.189 + 0xd1, 0xdb, 0x8c, 0xe0, // stack MDRVA 1.190 + 0xcc, 0x02, 0x00, 0x00, // context size 1.191 + 0x0c, 0xda, 0x65, 0x86 // context MDRVA 1.192 + }; 1.193 + EXPECT_EQ(sizeof(expected_bytes), contents.size()); 1.194 + EXPECT_TRUE(memcmp(contents.data(), expected_bytes, contents.size()) == 0); 1.195 +} 1.196 + 1.197 +TEST(Exception, Simple) { 1.198 + Dump dump(0, kLittleEndian); 1.199 + Context context(dump, x86_raw_context); 1.200 + context.Finish(0x8665da0c); 1.201 + 1.202 + Exception exception(dump, context, 1.203 + 0x1234abcd, // thread id 1.204 + 0xdcba4321, // exception code 1.205 + 0xf0e0d0c0, // exception flags 1.206 + 0x0919a9b9c9d9e9f9ULL); // exception address 1.207 + string contents; 1.208 + ASSERT_TRUE(exception.GetContents(&contents)); 1.209 + static const uint8_t expected_bytes[] = { 1.210 + 0xcd, 0xab, 0x34, 0x12, // thread id 1.211 + 0x00, 0x00, 0x00, 0x00, // __align 1.212 + 0x21, 0x43, 0xba, 0xdc, // exception code 1.213 + 0xc0, 0xd0, 0xe0, 0xf0, // exception flags 1.214 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception record 1.215 + 0xf9, 0xe9, 0xd9, 0xc9, 0xb9, 0xa9, 0x19, 0x09, // exception address 1.216 + 0x00, 0x00, 0x00, 0x00, // number parameters 1.217 + 0x00, 0x00, 0x00, 0x00, // __align 1.218 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information 1.219 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information 1.220 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information 1.221 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information 1.222 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information 1.223 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information 1.224 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information 1.225 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information 1.226 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information 1.227 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information 1.228 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information 1.229 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information 1.230 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information 1.231 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information 1.232 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information 1.233 + 0xcc, 0x02, 0x00, 0x00, // context size 1.234 + 0x0c, 0xda, 0x65, 0x86 // context MDRVA 1.235 + }; 1.236 + EXPECT_EQ(sizeof(expected_bytes), contents.size()); 1.237 + EXPECT_TRUE(memcmp(contents.data(), expected_bytes, contents.size()) == 0); 1.238 +} 1.239 + 1.240 +TEST(String, Simple) { 1.241 + Dump dump(0, kBigEndian); 1.242 + String s(dump, "All mimsy were the borogoves"); 1.243 + string contents; 1.244 + ASSERT_TRUE(s.GetContents(&contents)); 1.245 + static const char expected[] = 1.246 + "\x00\x00\x00\x38\0A\0l\0l\0 \0m\0i\0m\0s\0y\0 \0w\0e\0r\0e" 1.247 + "\0 \0t\0h\0e\0 \0b\0o\0r\0o\0g\0o\0v\0e\0s"; 1.248 + string expected_string(expected, sizeof(expected) - 1); 1.249 + EXPECT_EQ(expected_string, contents); 1.250 +} 1.251 + 1.252 +TEST(String, CiteStringIn) { 1.253 + Dump dump(0, kLittleEndian); 1.254 + String s(dump, "and the mome wraths outgrabe"); 1.255 + Section section(dump); 1.256 + section.Append("initial"); 1.257 + s.CiteStringIn(§ion); 1.258 + s.Finish(0xdc2bb469); 1.259 + string contents; 1.260 + ASSERT_TRUE(section.GetContents(&contents)); 1.261 + EXPECT_EQ(string("initial\x69\xb4\x2b\xdc", 7 + 4), contents); 1.262 +} 1.263 + 1.264 +TEST(List, Empty) { 1.265 + Dump dump(0, kBigEndian); 1.266 + List<Section> list(dump, 0x2442779c); 1.267 + EXPECT_TRUE(list.Empty()); 1.268 + list.Finish(0x84e09808); 1.269 + string contents; 1.270 + ASSERT_TRUE(list.GetContents(&contents)); 1.271 + EXPECT_EQ(string("\0\0\0\0", 4), contents); 1.272 +} 1.273 + 1.274 +TEST(List, Two) { 1.275 + Dump dump(0, kBigEndian); 1.276 + List<Section> list(dump, 0x26c9f498); 1.277 + Section section1(dump); 1.278 + section1.Append("section one contents"); 1.279 + EXPECT_TRUE(list.Empty()); 1.280 + list.Add(§ion1); 1.281 + EXPECT_FALSE(list.Empty()); 1.282 + Section section2(dump); 1.283 + section2.Append("section two contents"); 1.284 + list.Add(§ion2); 1.285 + list.Finish(0x1e5bb60e); 1.286 + string contents; 1.287 + ASSERT_TRUE(list.GetContents(&contents)); 1.288 + EXPECT_EQ(string("\0\0\0\x02section one contentssection two contents", 44), 1.289 + contents); 1.290 +} 1.291 + 1.292 +TEST(Dump, Header) { 1.293 + Dump dump(0x9f738b33685cc84cULL, kLittleEndian, 0xb3817faf, 0x2c741c0a); 1.294 + dump.Finish(); 1.295 + string contents; 1.296 + ASSERT_TRUE(dump.GetContents(&contents)); 1.297 + ASSERT_EQ(string("\x4d\x44\x4d\x50" // signature 1.298 + "\xaf\x7f\x81\xb3" // version 1.299 + "\0\0\0\0" // stream count 1.300 + "\x20\0\0\0" // directory RVA (could be anything) 1.301 + "\0\0\0\0" // checksum 1.302 + "\x0a\x1c\x74\x2c" // time_date_stamp 1.303 + "\x4c\xc8\x5c\x68\x33\x8b\x73\x9f", // flags 1.304 + 32), 1.305 + contents); 1.306 +} 1.307 + 1.308 +TEST(Dump, HeaderBigEndian) { 1.309 + Dump dump(0x206ce3cc6fb8e0f0ULL, kBigEndian, 0x161693e2, 0x35667744); 1.310 + dump.Finish(); 1.311 + string contents; 1.312 + ASSERT_TRUE(dump.GetContents(&contents)); 1.313 + ASSERT_EQ(string("\x50\x4d\x44\x4d" // signature 1.314 + "\x16\x16\x93\xe2" // version 1.315 + "\0\0\0\0" // stream count 1.316 + "\0\0\0\x20" // directory RVA (could be anything) 1.317 + "\0\0\0\0" // checksum 1.318 + "\x35\x66\x77\x44" // time_date_stamp 1.319 + "\x20\x6c\xe3\xcc\x6f\xb8\xe0\xf0", // flags 1.320 + 32), 1.321 + contents); 1.322 +} 1.323 + 1.324 +TEST(Dump, OneSection) { 1.325 + Dump dump(0, kLittleEndian); 1.326 + Section section(dump); 1.327 + section.Append("section contents"); 1.328 + dump.Add(§ion); 1.329 + dump.Finish(); 1.330 + string dump_contents; 1.331 + // Just check for undefined labels; don't worry about the contents. 1.332 + ASSERT_TRUE(dump.GetContents(&dump_contents)); 1.333 + 1.334 + Section referencing_section(dump); 1.335 + section.CiteLocationIn(&referencing_section); 1.336 + string contents; 1.337 + ASSERT_TRUE(referencing_section.GetContents(&contents)); 1.338 + ASSERT_EQ(string("\x10\0\0\0\x20\0\0\0", 8), contents); 1.339 +}