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 <windows.h> | 17 #include <windows.h> |
18 #include <dbghelp.h> | 18 #include <dbghelp.h> |
19 #include <stdint.h> | 19 #include <stdint.h> |
20 #include <sys/types.h> | 20 #include <sys/types.h> |
21 | 21 |
22 #include <string> | 22 #include <string> |
| 23 #include <utility> |
23 #include <vector> | 24 #include <vector> |
24 | 25 |
25 #include "gtest/gtest.h" | 26 #include "gtest/gtest.h" |
26 #include "minidump/minidump_context.h" | 27 #include "minidump/minidump_context.h" |
27 #include "minidump/minidump_context_writer.h" | 28 #include "minidump/minidump_context_writer.h" |
28 #include "minidump/minidump_extensions.h" | 29 #include "minidump/minidump_extensions.h" |
29 #include "minidump/minidump_file_writer.h" | 30 #include "minidump/minidump_file_writer.h" |
30 #include "minidump/minidump_thread_id_map.h" | 31 #include "minidump/minidump_thread_id_map.h" |
31 #include "minidump/test/minidump_context_test_util.h" | 32 #include "minidump/test/minidump_context_test_util.h" |
32 #include "minidump/test/minidump_file_writer_test_util.h" | 33 #include "minidump/test/minidump_file_writer_test_util.h" |
33 #include "minidump/test/minidump_writable_test_util.h" | 34 #include "minidump/test/minidump_writable_test_util.h" |
34 #include "snapshot/test/test_cpu_context.h" | 35 #include "snapshot/test/test_cpu_context.h" |
35 #include "snapshot/test/test_exception_snapshot.h" | 36 #include "snapshot/test/test_exception_snapshot.h" |
36 #include "test/gtest_death_check.h" | 37 #include "test/gtest_death_check.h" |
37 #include "util/file/string_file.h" | 38 #include "util/file/string_file.h" |
38 #include "util/stdlib/move.h" | |
39 | 39 |
40 namespace crashpad { | 40 namespace crashpad { |
41 namespace test { | 41 namespace test { |
42 namespace { | 42 namespace { |
43 | 43 |
44 // This returns the MINIDUMP_EXCEPTION_STREAM stream in |exception_stream|. | 44 // This returns the MINIDUMP_EXCEPTION_STREAM stream in |exception_stream|. |
45 void GetExceptionStream(const std::string& file_contents, | 45 void GetExceptionStream(const std::string& file_contents, |
46 const MINIDUMP_EXCEPTION_STREAM** exception_stream) { | 46 const MINIDUMP_EXCEPTION_STREAM** exception_stream) { |
47 const size_t kDirectoryOffset = sizeof(MINIDUMP_HEADER); | 47 const size_t kDirectoryOffset = sizeof(MINIDUMP_HEADER); |
48 const size_t kExceptionStreamOffset = | 48 const size_t kExceptionStreamOffset = |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 } | 98 } |
99 | 99 |
100 TEST(MinidumpExceptionWriter, Minimal) { | 100 TEST(MinidumpExceptionWriter, Minimal) { |
101 MinidumpFileWriter minidump_file_writer; | 101 MinidumpFileWriter minidump_file_writer; |
102 auto exception_writer = make_scoped_ptr(new MinidumpExceptionWriter()); | 102 auto exception_writer = make_scoped_ptr(new MinidumpExceptionWriter()); |
103 | 103 |
104 const uint32_t kSeed = 100; | 104 const uint32_t kSeed = 100; |
105 | 105 |
106 auto context_x86_writer = make_scoped_ptr(new MinidumpContextX86Writer()); | 106 auto context_x86_writer = make_scoped_ptr(new MinidumpContextX86Writer()); |
107 InitializeMinidumpContextX86(context_x86_writer->context(), kSeed); | 107 InitializeMinidumpContextX86(context_x86_writer->context(), kSeed); |
108 exception_writer->SetContext(crashpad::move(context_x86_writer)); | 108 exception_writer->SetContext(std::move(context_x86_writer)); |
109 | 109 |
110 minidump_file_writer.AddStream(crashpad::move(exception_writer)); | 110 minidump_file_writer.AddStream(std::move(exception_writer)); |
111 | 111 |
112 StringFile string_file; | 112 StringFile string_file; |
113 ASSERT_TRUE(minidump_file_writer.WriteEverything(&string_file)); | 113 ASSERT_TRUE(minidump_file_writer.WriteEverything(&string_file)); |
114 | 114 |
115 const MINIDUMP_EXCEPTION_STREAM* observed_exception_stream = nullptr; | 115 const MINIDUMP_EXCEPTION_STREAM* observed_exception_stream = nullptr; |
116 ASSERT_NO_FATAL_FAILURE( | 116 ASSERT_NO_FATAL_FAILURE( |
117 GetExceptionStream(string_file.string(), &observed_exception_stream)); | 117 GetExceptionStream(string_file.string(), &observed_exception_stream)); |
118 | 118 |
119 MINIDUMP_EXCEPTION_STREAM expected_exception_stream = {}; | 119 MINIDUMP_EXCEPTION_STREAM expected_exception_stream = {}; |
120 expected_exception_stream.ThreadContext.DataSize = sizeof(MinidumpContextX86); | 120 expected_exception_stream.ThreadContext.DataSize = sizeof(MinidumpContextX86); |
(...skipping 17 matching lines...) Expand all Loading... |
138 const uint32_t kExceptionCode = 2; | 138 const uint32_t kExceptionCode = 2; |
139 const uint32_t kExceptionFlags = 3; | 139 const uint32_t kExceptionFlags = 3; |
140 const uint32_t kExceptionRecord = 4; | 140 const uint32_t kExceptionRecord = 4; |
141 const uint32_t kExceptionAddress = 5; | 141 const uint32_t kExceptionAddress = 5; |
142 const uint64_t kExceptionInformation0 = 6; | 142 const uint64_t kExceptionInformation0 = 6; |
143 const uint64_t kExceptionInformation1 = 7; | 143 const uint64_t kExceptionInformation1 = 7; |
144 const uint64_t kExceptionInformation2 = 7; | 144 const uint64_t kExceptionInformation2 = 7; |
145 | 145 |
146 auto context_x86_writer = make_scoped_ptr(new MinidumpContextX86Writer()); | 146 auto context_x86_writer = make_scoped_ptr(new MinidumpContextX86Writer()); |
147 InitializeMinidumpContextX86(context_x86_writer->context(), kSeed); | 147 InitializeMinidumpContextX86(context_x86_writer->context(), kSeed); |
148 exception_writer->SetContext(crashpad::move(context_x86_writer)); | 148 exception_writer->SetContext(std::move(context_x86_writer)); |
149 | 149 |
150 exception_writer->SetThreadID(kThreadID); | 150 exception_writer->SetThreadID(kThreadID); |
151 exception_writer->SetExceptionCode(kExceptionCode); | 151 exception_writer->SetExceptionCode(kExceptionCode); |
152 exception_writer->SetExceptionFlags(kExceptionFlags); | 152 exception_writer->SetExceptionFlags(kExceptionFlags); |
153 exception_writer->SetExceptionRecord(kExceptionRecord); | 153 exception_writer->SetExceptionRecord(kExceptionRecord); |
154 exception_writer->SetExceptionAddress(kExceptionAddress); | 154 exception_writer->SetExceptionAddress(kExceptionAddress); |
155 | 155 |
156 // Set a lot of exception information at first, and then replace it with less. | 156 // Set a lot of exception information at first, and then replace it with less. |
157 // This tests that the exception that is written does not contain the | 157 // This tests that the exception that is written does not contain the |
158 // “garbage” from the initial SetExceptionInformation() call. | 158 // “garbage” from the initial SetExceptionInformation() call. |
159 std::vector<uint64_t> exception_information(EXCEPTION_MAXIMUM_PARAMETERS, | 159 std::vector<uint64_t> exception_information(EXCEPTION_MAXIMUM_PARAMETERS, |
160 0x5a5a5a5a5a5a5a5a); | 160 0x5a5a5a5a5a5a5a5a); |
161 exception_writer->SetExceptionInformation(exception_information); | 161 exception_writer->SetExceptionInformation(exception_information); |
162 | 162 |
163 exception_information.clear(); | 163 exception_information.clear(); |
164 exception_information.push_back(kExceptionInformation0); | 164 exception_information.push_back(kExceptionInformation0); |
165 exception_information.push_back(kExceptionInformation1); | 165 exception_information.push_back(kExceptionInformation1); |
166 exception_information.push_back(kExceptionInformation2); | 166 exception_information.push_back(kExceptionInformation2); |
167 exception_writer->SetExceptionInformation(exception_information); | 167 exception_writer->SetExceptionInformation(exception_information); |
168 | 168 |
169 minidump_file_writer.AddStream(crashpad::move(exception_writer)); | 169 minidump_file_writer.AddStream(std::move(exception_writer)); |
170 | 170 |
171 StringFile string_file; | 171 StringFile string_file; |
172 ASSERT_TRUE(minidump_file_writer.WriteEverything(&string_file)); | 172 ASSERT_TRUE(minidump_file_writer.WriteEverything(&string_file)); |
173 | 173 |
174 const MINIDUMP_EXCEPTION_STREAM* observed_exception_stream = nullptr; | 174 const MINIDUMP_EXCEPTION_STREAM* observed_exception_stream = nullptr; |
175 ASSERT_NO_FATAL_FAILURE( | 175 ASSERT_NO_FATAL_FAILURE( |
176 GetExceptionStream(string_file.string(), &observed_exception_stream)); | 176 GetExceptionStream(string_file.string(), &observed_exception_stream)); |
177 | 177 |
178 MINIDUMP_EXCEPTION_STREAM expected_exception_stream = {}; | 178 MINIDUMP_EXCEPTION_STREAM expected_exception_stream = {}; |
179 expected_exception_stream.ThreadId = kThreadID; | 179 expected_exception_stream.ThreadId = kThreadID; |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
232 | 232 |
233 InitializeCPUContextX86(exception_snapshot.MutableContext(), kSeed); | 233 InitializeCPUContextX86(exception_snapshot.MutableContext(), kSeed); |
234 | 234 |
235 MinidumpThreadIDMap thread_id_map; | 235 MinidumpThreadIDMap thread_id_map; |
236 thread_id_map[kThreadID] = expect_exception.ThreadId; | 236 thread_id_map[kThreadID] = expect_exception.ThreadId; |
237 | 237 |
238 auto exception_writer = make_scoped_ptr(new MinidumpExceptionWriter()); | 238 auto exception_writer = make_scoped_ptr(new MinidumpExceptionWriter()); |
239 exception_writer->InitializeFromSnapshot(&exception_snapshot, thread_id_map); | 239 exception_writer->InitializeFromSnapshot(&exception_snapshot, thread_id_map); |
240 | 240 |
241 MinidumpFileWriter minidump_file_writer; | 241 MinidumpFileWriter minidump_file_writer; |
242 minidump_file_writer.AddStream(crashpad::move(exception_writer)); | 242 minidump_file_writer.AddStream(std::move(exception_writer)); |
243 | 243 |
244 StringFile string_file; | 244 StringFile string_file; |
245 ASSERT_TRUE(minidump_file_writer.WriteEverything(&string_file)); | 245 ASSERT_TRUE(minidump_file_writer.WriteEverything(&string_file)); |
246 | 246 |
247 const MINIDUMP_EXCEPTION_STREAM* exception = nullptr; | 247 const MINIDUMP_EXCEPTION_STREAM* exception = nullptr; |
248 ASSERT_NO_FATAL_FAILURE(GetExceptionStream(string_file.string(), &exception)); | 248 ASSERT_NO_FATAL_FAILURE(GetExceptionStream(string_file.string(), &exception)); |
249 | 249 |
250 const MinidumpContextX86* observed_context = nullptr; | 250 const MinidumpContextX86* observed_context = nullptr; |
251 ASSERT_NO_FATAL_FAILURE(ExpectExceptionStream(&expect_exception, | 251 ASSERT_NO_FATAL_FAILURE(ExpectExceptionStream(&expect_exception, |
252 exception, | 252 exception, |
253 string_file.string(), | 253 string_file.string(), |
254 &observed_context)); | 254 &observed_context)); |
255 | 255 |
256 ASSERT_NO_FATAL_FAILURE( | 256 ASSERT_NO_FATAL_FAILURE( |
257 ExpectMinidumpContextX86(kSeed, observed_context, true)); | 257 ExpectMinidumpContextX86(kSeed, observed_context, true)); |
258 } | 258 } |
259 | 259 |
260 TEST(MinidumpExceptionWriterDeathTest, NoContext) { | 260 TEST(MinidumpExceptionWriterDeathTest, NoContext) { |
261 MinidumpFileWriter minidump_file_writer; | 261 MinidumpFileWriter minidump_file_writer; |
262 auto exception_writer = make_scoped_ptr(new MinidumpExceptionWriter()); | 262 auto exception_writer = make_scoped_ptr(new MinidumpExceptionWriter()); |
263 | 263 |
264 minidump_file_writer.AddStream(crashpad::move(exception_writer)); | 264 minidump_file_writer.AddStream(std::move(exception_writer)); |
265 | 265 |
266 StringFile string_file; | 266 StringFile string_file; |
267 ASSERT_DEATH_CHECK(minidump_file_writer.WriteEverything(&string_file), | 267 ASSERT_DEATH_CHECK(minidump_file_writer.WriteEverything(&string_file), |
268 "context_"); | 268 "context_"); |
269 } | 269 } |
270 | 270 |
271 TEST(MinidumpExceptionWriterDeathTest, TooMuchInformation) { | 271 TEST(MinidumpExceptionWriterDeathTest, TooMuchInformation) { |
272 MinidumpExceptionWriter exception_writer; | 272 MinidumpExceptionWriter exception_writer; |
273 std::vector<uint64_t> exception_information(EXCEPTION_MAXIMUM_PARAMETERS + 1, | 273 std::vector<uint64_t> exception_information(EXCEPTION_MAXIMUM_PARAMETERS + 1, |
274 0x5a5a5a5a5a5a5a5a); | 274 0x5a5a5a5a5a5a5a5a); |
275 ASSERT_DEATH_CHECK( | 275 ASSERT_DEATH_CHECK( |
276 exception_writer.SetExceptionInformation(exception_information), | 276 exception_writer.SetExceptionInformation(exception_information), |
277 "kMaxParameters"); | 277 "kMaxParameters"); |
278 } | 278 } |
279 | 279 |
280 } // namespace | 280 } // namespace |
281 } // namespace test | 281 } // namespace test |
282 } // namespace crashpad | 282 } // namespace crashpad |
OLD | NEW |