| OLD | NEW |
| 1 // Copyright 2014 The Crashpad Authors. All rights reserved. | 1 // Copyright 2014 The Crashpad Authors. All rights reserved. |
| 2 // | 2 // |
| 3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 // you may not use this file except in compliance with the License. | 4 // you may not use this file except in compliance with the License. |
| 5 // You may obtain a copy of the License at | 5 // You may obtain a copy of the License at |
| 6 // | 6 // |
| 7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 // | 8 // |
| 9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
| 10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 // See the License for the specific language governing permissions and | 12 // See the License for the specific language governing permissions and |
| 13 // limitations under the License. | 13 // limitations under the License. |
| 14 | 14 |
| 15 #include "minidump/minidump_exception_writer.h" | 15 #include "minidump/minidump_exception_writer.h" |
| 16 | 16 |
| 17 #include <dbghelp.h> | 17 #include <dbghelp.h> |
| 18 #include <stdint.h> | 18 #include <stdint.h> |
| 19 | 19 |
| 20 #include <string> | 20 #include <string> |
| 21 #include <vector> | 21 #include <vector> |
| 22 | 22 |
| 23 #include "gtest/gtest.h" | 23 #include "gtest/gtest.h" |
| 24 #include "minidump/minidump_context.h" | 24 #include "minidump/minidump_context.h" |
| 25 #include "minidump/minidump_context_writer.h" | 25 #include "minidump/minidump_context_writer.h" |
| 26 #include "minidump/minidump_extensions.h" | 26 #include "minidump/minidump_extensions.h" |
| 27 #include "minidump/minidump_file_writer.h" | 27 #include "minidump/minidump_file_writer.h" |
| 28 #include "minidump/test/minidump_context_test_util.h" | 28 #include "minidump/test/minidump_context_test_util.h" |
| 29 #include "minidump/test/minidump_file_writer_test_util.h" | 29 #include "minidump/test/minidump_file_writer_test_util.h" |
| 30 #include "minidump/test/minidump_writable_test_util.h" |
| 30 #include "util/file/string_file_writer.h" | 31 #include "util/file/string_file_writer.h" |
| 31 | 32 |
| 32 namespace crashpad { | 33 namespace crashpad { |
| 33 namespace test { | 34 namespace test { |
| 34 namespace { | 35 namespace { |
| 35 | 36 |
| 36 // This returns the MINIDUMP_EXCEPTION_STREAM stream in |exception_stream|. | 37 // This returns the MINIDUMP_EXCEPTION_STREAM stream in |exception_stream|. |
| 37 void GetExceptionStream(const std::string& file_contents, | 38 void GetExceptionStream(const std::string& file_contents, |
| 38 const MINIDUMP_EXCEPTION_STREAM** exception_stream) { | 39 const MINIDUMP_EXCEPTION_STREAM** exception_stream) { |
| 39 const size_t kDirectoryOffset = sizeof(MINIDUMP_HEADER); | 40 const size_t kDirectoryOffset = sizeof(MINIDUMP_HEADER); |
| 40 const size_t kExceptionStreamOffset = | 41 const size_t kExceptionStreamOffset = |
| 41 kDirectoryOffset + sizeof(MINIDUMP_DIRECTORY); | 42 kDirectoryOffset + sizeof(MINIDUMP_DIRECTORY); |
| 42 const size_t kContextOffset = | 43 const size_t kContextOffset = |
| 43 kExceptionStreamOffset + sizeof(MINIDUMP_EXCEPTION_STREAM); | 44 kExceptionStreamOffset + sizeof(MINIDUMP_EXCEPTION_STREAM); |
| 44 const size_t kFileSize = kContextOffset + sizeof(MinidumpContextX86); | 45 const size_t kFileSize = kContextOffset + sizeof(MinidumpContextX86); |
| 45 ASSERT_EQ(file_contents.size(), kFileSize); | 46 ASSERT_EQ(file_contents.size(), kFileSize); |
| 46 | 47 |
| 47 const MINIDUMP_DIRECTORY* directory; | 48 const MINIDUMP_DIRECTORY* directory; |
| 48 const MINIDUMP_HEADER* header = | 49 const MINIDUMP_HEADER* header = |
| 49 MinidumpHeaderAtStart(file_contents, &directory); | 50 MinidumpHeaderAtStart(file_contents, &directory); |
| 50 ASSERT_NO_FATAL_FAILURE(VerifyMinidumpHeader(header, 1, 0)); | 51 ASSERT_NO_FATAL_FAILURE(VerifyMinidumpHeader(header, 1, 0)); |
| 51 | 52 |
| 52 ASSERT_EQ(kMinidumpStreamTypeException, directory[0].StreamType); | 53 ASSERT_EQ(kMinidumpStreamTypeException, directory[0].StreamType); |
| 53 ASSERT_GE(directory[0].Location.DataSize, sizeof(MINIDUMP_EXCEPTION_STREAM)); | 54 EXPECT_EQ(kExceptionStreamOffset, directory[0].Location.Rva); |
| 54 ASSERT_EQ(kExceptionStreamOffset, directory[0].Location.Rva); | |
| 55 | 55 |
| 56 *exception_stream = reinterpret_cast<const MINIDUMP_EXCEPTION_STREAM*>( | 56 *exception_stream = |
| 57 &file_contents[kExceptionStreamOffset]); | 57 MinidumpWritableAtLocationDescriptor<MINIDUMP_EXCEPTION_STREAM>( |
| 58 file_contents, directory[0].Location); |
| 59 ASSERT_TRUE(exception_stream); |
| 58 } | 60 } |
| 59 | 61 |
| 60 // The MINIDUMP_EXCEPTION_STREAMs |expected| and |observed| are compared against | 62 // The MINIDUMP_EXCEPTION_STREAMs |expected| and |observed| are compared against |
| 61 // each other using gtest assertions. The context will be recovered from | 63 // each other using gtest assertions. The context will be recovered from |
| 62 // |file_contents| and stored in |context|. | 64 // |file_contents| and stored in |context|. |
| 63 void ExpectExceptionStream(const MINIDUMP_EXCEPTION_STREAM* expected, | 65 void ExpectExceptionStream(const MINIDUMP_EXCEPTION_STREAM* expected, |
| 64 const MINIDUMP_EXCEPTION_STREAM* observed, | 66 const MINIDUMP_EXCEPTION_STREAM* observed, |
| 65 const std::string& file_contents, | 67 const std::string& file_contents, |
| 66 const MinidumpContextX86** context) { | 68 const MinidumpContextX86** context) { |
| 67 EXPECT_EQ(expected->ThreadId, observed->ThreadId); | 69 EXPECT_EQ(expected->ThreadId, observed->ThreadId); |
| 68 EXPECT_EQ(0u, observed->__alignment); | 70 EXPECT_EQ(0u, observed->__alignment); |
| 69 EXPECT_EQ(expected->ExceptionRecord.ExceptionCode, | 71 EXPECT_EQ(expected->ExceptionRecord.ExceptionCode, |
| 70 observed->ExceptionRecord.ExceptionCode); | 72 observed->ExceptionRecord.ExceptionCode); |
| 71 EXPECT_EQ(expected->ExceptionRecord.ExceptionFlags, | 73 EXPECT_EQ(expected->ExceptionRecord.ExceptionFlags, |
| 72 observed->ExceptionRecord.ExceptionFlags); | 74 observed->ExceptionRecord.ExceptionFlags); |
| 73 EXPECT_EQ(expected->ExceptionRecord.ExceptionRecord, | 75 EXPECT_EQ(expected->ExceptionRecord.ExceptionRecord, |
| 74 observed->ExceptionRecord.ExceptionRecord); | 76 observed->ExceptionRecord.ExceptionRecord); |
| 75 EXPECT_EQ(expected->ExceptionRecord.ExceptionAddress, | 77 EXPECT_EQ(expected->ExceptionRecord.ExceptionAddress, |
| 76 observed->ExceptionRecord.ExceptionAddress); | 78 observed->ExceptionRecord.ExceptionAddress); |
| 77 EXPECT_EQ(expected->ExceptionRecord.NumberParameters, | 79 EXPECT_EQ(expected->ExceptionRecord.NumberParameters, |
| 78 observed->ExceptionRecord.NumberParameters); | 80 observed->ExceptionRecord.NumberParameters); |
| 79 EXPECT_EQ(0u, observed->ExceptionRecord.__unusedAlignment); | 81 EXPECT_EQ(0u, observed->ExceptionRecord.__unusedAlignment); |
| 80 for (size_t index = 0; | 82 for (size_t index = 0; |
| 81 index < arraysize(observed->ExceptionRecord.ExceptionInformation); | 83 index < arraysize(observed->ExceptionRecord.ExceptionInformation); |
| 82 ++index) { | 84 ++index) { |
| 83 EXPECT_EQ(expected->ExceptionRecord.ExceptionInformation[index], | 85 EXPECT_EQ(expected->ExceptionRecord.ExceptionInformation[index], |
| 84 observed->ExceptionRecord.ExceptionInformation[index]); | 86 observed->ExceptionRecord.ExceptionInformation[index]); |
| 85 } | 87 } |
| 86 EXPECT_EQ(expected->ThreadContext.DataSize, observed->ThreadContext.DataSize); | 88 *context = MinidumpWritableAtLocationDescriptor<MinidumpContextX86>( |
| 87 ASSERT_NE(0u, observed->ThreadContext.DataSize); | 89 file_contents, observed->ThreadContext); |
| 88 ASSERT_NE(0u, observed->ThreadContext.Rva); | 90 ASSERT_TRUE(context); |
| 89 ASSERT_GE(file_contents.size(), | |
| 90 observed->ThreadContext.Rva + observed->ThreadContext.DataSize); | |
| 91 *context = reinterpret_cast<const MinidumpContextX86*>( | |
| 92 &file_contents[observed->ThreadContext.Rva]); | |
| 93 } | 91 } |
| 94 | 92 |
| 95 TEST(MinidumpExceptionWriter, Minimal) { | 93 TEST(MinidumpExceptionWriter, Minimal) { |
| 96 MinidumpFileWriter minidump_file_writer; | 94 MinidumpFileWriter minidump_file_writer; |
| 97 MinidumpExceptionWriter exception_writer; | 95 MinidumpExceptionWriter exception_writer; |
| 98 | 96 |
| 99 const uint32_t kSeed = 100; | 97 const uint32_t kSeed = 100; |
| 100 | 98 |
| 101 MinidumpContextX86Writer context_x86_writer; | 99 MinidumpContextX86Writer context_x86_writer; |
| 102 InitializeMinidumpContextX86(context_x86_writer.context(), kSeed); | 100 InitializeMinidumpContextX86(context_x86_writer.context(), kSeed); |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 207 MinidumpExceptionWriter exception_writer; | 205 MinidumpExceptionWriter exception_writer; |
| 208 std::vector<uint64_t> exception_information(EXCEPTION_MAXIMUM_PARAMETERS + 1, | 206 std::vector<uint64_t> exception_information(EXCEPTION_MAXIMUM_PARAMETERS + 1, |
| 209 0x5a5a5a5a5a5a5a5a); | 207 0x5a5a5a5a5a5a5a5a); |
| 210 ASSERT_DEATH(exception_writer.SetExceptionInformation(exception_information), | 208 ASSERT_DEATH(exception_writer.SetExceptionInformation(exception_information), |
| 211 "kMaxParameters"); | 209 "kMaxParameters"); |
| 212 } | 210 } |
| 213 | 211 |
| 214 } // namespace | 212 } // namespace |
| 215 } // namespace test | 213 } // namespace test |
| 216 } // namespace crashpad | 214 } // namespace crashpad |
| OLD | NEW |