Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(228)

Side by Side Diff: minidump/minidump_exception_writer_test.cc

Issue 639573002: Add MinidumpExceptionWriter and its test (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
Patch Set: Use ASSERT_NO_FATAL_FAILURE() Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « minidump/minidump_exception_writer.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 The Crashpad Authors. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (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
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "minidump/minidump_exception_writer.h"
16
17 #include <dbghelp.h>
18 #include <stdint.h>
19
20 #include <string>
21 #include <vector>
22
23 #include "gtest/gtest.h"
24 #include "minidump/minidump_context.h"
25 #include "minidump/minidump_context_test_util.h"
26 #include "minidump/minidump_context_writer.h"
27 #include "minidump/minidump_extensions.h"
28 #include "minidump/minidump_file_writer.h"
29 #include "minidump/minidump_test_util.h"
30 #include "util/file/string_file_writer.h"
31
32 namespace crashpad {
33 namespace test {
34 namespace {
35
36 // This returns the MINIDUMP_EXCEPTION_STREAM stream in |exception_stream|.
37 void GetExceptionStream(const std::string& file_contents,
38 const MINIDUMP_EXCEPTION_STREAM** exception_stream) {
39 const size_t kDirectoryOffset = sizeof(MINIDUMP_HEADER);
40 const size_t kExceptionStreamOffset =
41 kDirectoryOffset + sizeof(MINIDUMP_DIRECTORY);
42 const size_t kContextOffset =
43 kExceptionStreamOffset + sizeof(MINIDUMP_EXCEPTION_STREAM);
44 const size_t kFileSize = kContextOffset + sizeof(MinidumpContextX86);
45 ASSERT_EQ(file_contents.size(), kFileSize);
46
47 const MINIDUMP_HEADER* header =
48 reinterpret_cast<const MINIDUMP_HEADER*>(&file_contents[0]);
49
50 ASSERT_NO_FATAL_FAILURE(VerifyMinidumpHeader(header, 1, 0));
51
52 const MINIDUMP_DIRECTORY* directory =
53 reinterpret_cast<const MINIDUMP_DIRECTORY*>(
54 &file_contents[kDirectoryOffset]);
55
56 ASSERT_EQ(kMinidumpStreamTypeException, directory[0].StreamType);
57 ASSERT_GE(directory[0].Location.DataSize, sizeof(MINIDUMP_EXCEPTION_STREAM));
58 ASSERT_EQ(kExceptionStreamOffset, directory[0].Location.Rva);
59
60 *exception_stream = reinterpret_cast<const MINIDUMP_EXCEPTION_STREAM*>(
61 &file_contents[kExceptionStreamOffset]);
62 }
63
64 // The MINIDUMP_EXCEPTION_STREAMs |expected| and |observed| are compared against
65 // each other using gtest assertions. The context will be recovered from
66 // |file_contents| and stored in |context|.
67 void ExpectExceptionStream(const MINIDUMP_EXCEPTION_STREAM* expected,
68 const MINIDUMP_EXCEPTION_STREAM* observed,
69 const std::string& file_contents,
70 const MinidumpContextX86** context) {
71 EXPECT_EQ(expected->ThreadId, observed->ThreadId);
72 EXPECT_EQ(0u, observed->__alignment);
73 EXPECT_EQ(expected->ExceptionRecord.ExceptionCode,
74 observed->ExceptionRecord.ExceptionCode);
75 EXPECT_EQ(expected->ExceptionRecord.ExceptionFlags,
76 observed->ExceptionRecord.ExceptionFlags);
77 EXPECT_EQ(expected->ExceptionRecord.ExceptionRecord,
78 observed->ExceptionRecord.ExceptionRecord);
79 EXPECT_EQ(expected->ExceptionRecord.ExceptionAddress,
80 observed->ExceptionRecord.ExceptionAddress);
81 EXPECT_EQ(expected->ExceptionRecord.NumberParameters,
82 observed->ExceptionRecord.NumberParameters);
83 EXPECT_EQ(0u, observed->ExceptionRecord.__unusedAlignment);
84 for (size_t index = 0;
85 index < arraysize(observed->ExceptionRecord.ExceptionInformation);
86 ++index) {
87 EXPECT_EQ(expected->ExceptionRecord.ExceptionInformation[index],
88 observed->ExceptionRecord.ExceptionInformation[index]);
89 }
90 EXPECT_EQ(expected->ThreadContext.DataSize, observed->ThreadContext.DataSize);
91 ASSERT_NE(0u, observed->ThreadContext.DataSize);
92 ASSERT_NE(0u, observed->ThreadContext.Rva);
93 ASSERT_GE(file_contents.size(),
94 observed->ThreadContext.Rva + observed->ThreadContext.DataSize);
95 *context = reinterpret_cast<const MinidumpContextX86*>(
96 &file_contents[observed->ThreadContext.Rva]);
97 }
98
99 TEST(MinidumpExceptionWriter, Minimal) {
100 MinidumpFileWriter minidump_file_writer;
101 MinidumpExceptionWriter exception_writer;
102
103 const uint32_t kSeed = 100;
104
105 MinidumpContextX86Writer context_x86_writer;
106 InitializeMinidumpContextX86(context_x86_writer.context(), kSeed);
107 exception_writer.SetContext(&context_x86_writer);
108
109 minidump_file_writer.AddStream(&exception_writer);
110
111 StringFileWriter file_writer;
112 ASSERT_TRUE(minidump_file_writer.WriteEverything(&file_writer));
113
114 const MINIDUMP_EXCEPTION_STREAM* observed_exception_stream;
115 ASSERT_NO_FATAL_FAILURE(
116 GetExceptionStream(file_writer.string(), &observed_exception_stream));
117
118 MINIDUMP_EXCEPTION_STREAM expected_exception_stream = {};
119 expected_exception_stream.ThreadContext.DataSize = sizeof(MinidumpContextX86);
120
121 const MinidumpContextX86* observed_context;
122 ASSERT_NO_FATAL_FAILURE(ExpectExceptionStream(&expected_exception_stream,
123 observed_exception_stream,
124 file_writer.string(),
125 &observed_context));
126
127 ASSERT_NO_FATAL_FAILURE(ExpectMinidumpContextX86(kSeed, observed_context));
128 }
129
130 TEST(MinidumpExceptionWriter, Standard) {
131 MinidumpFileWriter minidump_file_writer;
132 MinidumpExceptionWriter exception_writer;
133
134 const uint32_t kSeed = 200;
135 const uint32_t kThreadID = 1;
136 const uint32_t kExceptionCode = 2;
137 const uint32_t kExceptionFlags = 3;
138 const uint32_t kExceptionRecord = 4;
139 const uint32_t kExceptionAddress = 5;
140 const uint64_t kExceptionInformation0 = 6;
141 const uint64_t kExceptionInformation1 = 7;
142 const uint64_t kExceptionInformation2 = 7;
143
144 MinidumpContextX86Writer context_x86_writer;
145 InitializeMinidumpContextX86(context_x86_writer.context(), kSeed);
146 exception_writer.SetContext(&context_x86_writer);
147
148 exception_writer.SetThreadID(kThreadID);
149 exception_writer.SetExceptionCode(kExceptionCode);
150 exception_writer.SetExceptionFlags(kExceptionFlags);
151 exception_writer.SetExceptionRecord(kExceptionRecord);
152 exception_writer.SetExceptionAddress(kExceptionAddress);
153
154 // Set a lot of exception information at first, and then replace it with less.
155 // This tests that the exception that is written does not contain the
156 // “garbage” from the initial SetExceptionInformation() call.
157 std::vector<uint64_t> exception_information(EXCEPTION_MAXIMUM_PARAMETERS,
158 0x5a5a5a5a5a5a5a5a);
159 exception_writer.SetExceptionInformation(exception_information);
160
161 exception_information.clear();
162 exception_information.push_back(kExceptionInformation0);
163 exception_information.push_back(kExceptionInformation1);
164 exception_information.push_back(kExceptionInformation2);
165 exception_writer.SetExceptionInformation(exception_information);
166
167 minidump_file_writer.AddStream(&exception_writer);
168
169 StringFileWriter file_writer;
170 ASSERT_TRUE(minidump_file_writer.WriteEverything(&file_writer));
171
172 const MINIDUMP_EXCEPTION_STREAM* observed_exception_stream;
173 ASSERT_NO_FATAL_FAILURE(
174 GetExceptionStream(file_writer.string(), &observed_exception_stream));
175
176 MINIDUMP_EXCEPTION_STREAM expected_exception_stream = {};
177 expected_exception_stream.ThreadId = kThreadID;
178 expected_exception_stream.ExceptionRecord.ExceptionCode = kExceptionCode;
179 expected_exception_stream.ExceptionRecord.ExceptionFlags = kExceptionFlags;
180 expected_exception_stream.ExceptionRecord.ExceptionRecord = kExceptionRecord;
181 expected_exception_stream.ExceptionRecord.ExceptionAddress =
182 kExceptionAddress;
183 expected_exception_stream.ExceptionRecord.NumberParameters =
184 exception_information.size();
185 for (size_t index = 0; index < exception_information.size(); ++index) {
186 expected_exception_stream.ExceptionRecord.ExceptionInformation[index] =
187 exception_information[index];
188 }
189 expected_exception_stream.ThreadContext.DataSize = sizeof(MinidumpContextX86);
190
191 const MinidumpContextX86* observed_context;
192 ASSERT_NO_FATAL_FAILURE(ExpectExceptionStream(&expected_exception_stream,
193 observed_exception_stream,
194 file_writer.string(),
195 &observed_context));
196
197 ASSERT_NO_FATAL_FAILURE(ExpectMinidumpContextX86(kSeed, observed_context));
198 }
199
200 TEST(MinidumpExceptionWriterDeathTest, NoContext) {
201 MinidumpFileWriter minidump_file_writer;
202 MinidumpExceptionWriter exception_writer;
203
204 minidump_file_writer.AddStream(&exception_writer);
205
206 StringFileWriter file_writer;
207 ASSERT_DEATH(minidump_file_writer.WriteEverything(&file_writer), "context_");
208 }
209
210 TEST(MinidumpExceptionWriterDeathTest, TooMuchInformation) {
211 MinidumpExceptionWriter exception_writer;
212 std::vector<uint64_t> exception_information(EXCEPTION_MAXIMUM_PARAMETERS + 1,
213 0x5a5a5a5a5a5a5a5a);
214 ASSERT_DEATH(exception_writer.SetExceptionInformation(exception_information),
215 "kMaxParameters");
216 }
217
218 } // namespace
219 } // namespace test
220 } // namespace crashpad
OLDNEW
« no previous file with comments | « minidump/minidump_exception_writer.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698