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

Side by Side Diff: minidump/minidump_module_writer.cc

Issue 460933004: Add MinidumpModuleWriter, MinidumpModuleListWriter, related classes, and their test (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
Patch Set: Don’t suffix uint64_t constants Created 6 years, 4 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_module_writer.h ('k') | minidump/minidump_module_writer_test.cc » ('j') | 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_module_writer.h"
16
17 #include "base/logging.h"
18 #include "minidump/minidump_string_writer.h"
19 #include "minidump/minidump_writer_util.h"
20 #include "util/numeric/safe_assignment.h"
21
22 namespace crashpad {
23
24 MinidumpModuleCodeViewRecordWriter::~MinidumpModuleCodeViewRecordWriter() {
25 }
26
27 namespace internal {
28
29 template <typename CodeViewRecordType>
30 MinidumpModuleCodeViewRecordPDBLinkWriter<
31 CodeViewRecordType>::MinidumpModuleCodeViewRecordPDBLinkWriter()
32 : MinidumpModuleCodeViewRecordWriter(), codeview_record_(), pdb_name_() {
33 codeview_record_.signature = CodeViewRecordType::kSignature;
34 }
35
36 template <typename CodeViewRecordType>
37 MinidumpModuleCodeViewRecordPDBLinkWriter<
38 CodeViewRecordType>::~MinidumpModuleCodeViewRecordPDBLinkWriter() {
39 }
40
41 template <typename CodeViewRecordType>
42 size_t
43 MinidumpModuleCodeViewRecordPDBLinkWriter<CodeViewRecordType>::SizeOfObject() {
44 DCHECK_GE(state(), kStateFrozen);
45
46 // NUL-terminate.
47 return offsetof(typeof(codeview_record_), pdb_name) +
48 (pdb_name_.size() + 1) * sizeof(pdb_name_[0]);
49 }
50
51 template <typename CodeViewRecordType>
52 bool MinidumpModuleCodeViewRecordPDBLinkWriter<CodeViewRecordType>::WriteObject(
53 FileWriterInterface* file_writer) {
54 DCHECK_EQ(state(), kStateWritable);
55
56 WritableIoVec iov;
57 iov.iov_base = &codeview_record_;
58 iov.iov_len = offsetof(typeof(codeview_record_), pdb_name);
59 std::vector<WritableIoVec> iovecs(1, iov);
60
61 // NUL-terminate.
62 iov.iov_base = &pdb_name_[0];
63 iov.iov_len = (pdb_name_.size() + 1) * sizeof(pdb_name_[0]);
64 iovecs.push_back(iov);
65
66 return file_writer->WriteIoVec(&iovecs);
67 }
68
69 } // namespace internal
70
71 template class internal::MinidumpModuleCodeViewRecordPDBLinkWriter<
72 MinidumpModuleCodeViewRecordPDB20>;
73
74 MinidumpModuleCodeViewRecordPDB20Writer::
75 ~MinidumpModuleCodeViewRecordPDB20Writer() {
76 }
77
78 void MinidumpModuleCodeViewRecordPDB20Writer::SetTimestampAndAge(
79 time_t timestamp,
80 uint32_t age) {
81 DCHECK_EQ(state(), kStateMutable);
82
83 internal::MinidumpWriterUtil::AssignTimeT(&codeview_record()->timestamp,
84 timestamp);
85
86 codeview_record()->age = age;
87 }
88
89 template class internal::MinidumpModuleCodeViewRecordPDBLinkWriter<
90 MinidumpModuleCodeViewRecordPDB70>;
91
92 MinidumpModuleCodeViewRecordPDB70Writer::
93 ~MinidumpModuleCodeViewRecordPDB70Writer() {
94 }
95
96 MinidumpModuleMiscDebugRecordWriter::MinidumpModuleMiscDebugRecordWriter()
97 : internal::MinidumpWritable(),
98 image_debug_misc_(),
99 data_(),
100 data_utf16_() {
101 }
102
103 void MinidumpModuleMiscDebugRecordWriter::SetData(const std::string& data,
104 bool utf16) {
105 DCHECK_EQ(state(), kStateMutable);
106
107 if (!utf16) {
108 data_utf16_.clear();
109 image_debug_misc_.Unicode = 0;
110 data_ = data;
111 } else {
112 data_.clear();
113 image_debug_misc_.Unicode = 1;
114 data_utf16_ = internal::MinidumpWriterUtil::ConvertUTF8ToUTF16(data);
115 }
116 }
117
118 bool MinidumpModuleMiscDebugRecordWriter::Freeze() {
119 DCHECK_EQ(state(), kStateMutable);
120
121 if (!MinidumpWritable::Freeze()) {
122 return false;
123 }
124
125 // NUL-terminate.
126 if (!image_debug_misc_.Unicode) {
127 DCHECK(data_utf16_.empty());
128 image_debug_misc_.Length = offsetof(typeof(image_debug_misc_), Data) +
129 (data_.size() + 1) * sizeof(data_[0]);
130 } else {
131 DCHECK(data_.empty());
132 image_debug_misc_.Length =
133 offsetof(typeof(image_debug_misc_), Data) +
134 (data_utf16_.size() + 1) * sizeof(data_utf16_[0]);
135 }
136
137 return true;
138 }
139
140 size_t MinidumpModuleMiscDebugRecordWriter::SizeOfObject() {
141 DCHECK_GE(state(), kStateFrozen);
142
143 return image_debug_misc_.Length;
144 }
145
146 bool MinidumpModuleMiscDebugRecordWriter::WriteObject(
147 FileWriterInterface* file_writer) {
148 DCHECK_EQ(state(), kStateWritable);
149
150 const size_t base_length = offsetof(typeof(image_debug_misc_), Data);
151
152 WritableIoVec iov;
153 iov.iov_base = &image_debug_misc_;
154 iov.iov_len = base_length;
155 std::vector<WritableIoVec> iovecs(1, iov);
156
157 iov.iov_len = image_debug_misc_.Length - base_length;
158 if (!image_debug_misc_.Unicode) {
159 DCHECK(data_utf16_.empty());
160 iov.iov_base = &data_[0];
161 } else {
162 DCHECK(data_.empty());
163 iov.iov_base = &data_utf16_[0];
164 }
165 iovecs.push_back(iov);
166
167 return file_writer->WriteIoVec(&iovecs);
168 }
169
170 MinidumpModuleWriter::MinidumpModuleWriter()
171 : MinidumpWritable(),
172 module_(),
173 name_(),
174 codeview_record_(NULL),
175 misc_debug_record_(NULL) {
176 module_.VersionInfo.dwSignature = VS_FFI_SIGNATURE;
177 module_.VersionInfo.dwStrucVersion = VS_FFI_STRUCVERSION;
178 }
179
180 MinidumpModuleWriter::~MinidumpModuleWriter() {
181 }
182
183 const MINIDUMP_MODULE* MinidumpModuleWriter::MinidumpModule() const {
184 DCHECK_EQ(state(), kStateWritable);
185
186 return &module_;
187 }
188
189 void MinidumpModuleWriter::SetName(const std::string& name) {
190 DCHECK_EQ(state(), kStateMutable);
191
192 if (!name_) {
193 name_.reset(new internal::MinidumpUTF16StringWriter());
194 }
195 name_->SetUTF8(name);
196 }
197
198 void MinidumpModuleWriter::SetCodeViewRecord(
199 MinidumpModuleCodeViewRecordWriter* codeview_record) {
200 DCHECK_EQ(state(), kStateMutable);
201
202 codeview_record_ = codeview_record;
203 }
204
205 void MinidumpModuleWriter::SetMiscDebugRecord(
206 MinidumpModuleMiscDebugRecordWriter* misc_debug_record) {
207 DCHECK_EQ(state(), kStateMutable);
208
209 misc_debug_record_ = misc_debug_record;
210 }
211
212 void MinidumpModuleWriter::SetTimestamp(time_t timestamp) {
213 DCHECK_EQ(state(), kStateMutable);
214
215 internal::MinidumpWriterUtil::AssignTimeT(&module_.TimeDateStamp, timestamp);
216 }
217
218 void MinidumpModuleWriter::SetFileVersion(uint16_t version_0,
219 uint16_t version_1,
220 uint16_t version_2,
221 uint16_t version_3) {
222 DCHECK_EQ(state(), kStateMutable);
223
224 module_.VersionInfo.dwFileVersionMS =
225 (static_cast<uint32_t>(version_0) << 16) | version_1;
226 module_.VersionInfo.dwFileVersionLS =
227 (static_cast<uint32_t>(version_2) << 16) | version_3;
228 }
229
230 void MinidumpModuleWriter::SetProductVersion(uint16_t version_0,
231 uint16_t version_1,
232 uint16_t version_2,
233 uint16_t version_3) {
234 DCHECK_EQ(state(), kStateMutable);
235
236 module_.VersionInfo.dwProductVersionMS =
237 (static_cast<uint32_t>(version_0) << 16) | version_1;
238 module_.VersionInfo.dwProductVersionLS =
239 (static_cast<uint32_t>(version_2) << 16) | version_3;
240 }
241
242 void MinidumpModuleWriter::SetFileFlagsAndMask(uint32_t file_flags,
243 uint32_t file_flags_mask) {
244 DCHECK_EQ(state(), kStateMutable);
245 DCHECK_EQ(file_flags & ~file_flags_mask, 0u);
246
247 module_.VersionInfo.dwFileFlags = file_flags;
248 module_.VersionInfo.dwFileFlagsMask = file_flags_mask;
249 }
250
251 bool MinidumpModuleWriter::Freeze() {
252 DCHECK_EQ(state(), kStateMutable);
253
254 if (!MinidumpWritable::Freeze()) {
255 return false;
256 }
257
258 CHECK(name_);
259
260 name_->RegisterRVA(&module_.ModuleNameRva);
261
262 if (codeview_record_) {
263 codeview_record_->RegisterLocationDescriptor(&module_.CvRecord);
264 }
265
266 if (misc_debug_record_) {
267 misc_debug_record_->RegisterLocationDescriptor(&module_.MiscRecord);
268 }
269
270 return true;
271 }
272
273 size_t MinidumpModuleWriter::SizeOfObject() {
274 DCHECK_GE(state(), kStateFrozen);
275
276 // This object doesn’t directly write anything itself. Its MINIDUMP_MODULE is
277 // written by its parent as part of a MINIDUMP_MODULE_LIST, and its children
278 // are responsible for writing themselves.
279 return 0;
280 }
281
282 std::vector<internal::MinidumpWritable*> MinidumpModuleWriter::Children() {
283 DCHECK_GE(state(), kStateFrozen);
284
285 std::vector<MinidumpWritable*> children;
286 if (name_) {
287 children.push_back(name_.get());
288 }
289 if (codeview_record_) {
290 children.push_back(codeview_record_);
291 }
292 if (misc_debug_record_) {
293 children.push_back(misc_debug_record_);
294 }
295
296 return children;
297 }
298
299 bool MinidumpModuleWriter::WriteObject(FileWriterInterface* file_writer) {
300 DCHECK_EQ(state(), kStateWritable);
301
302 // This object doesn’t directly write anything itself. Its MINIDUMP_MODULE is
303 // written by its parent as part of a MINIDUMP_MODULE_LIST, and its children
304 // are responsible for writing themselves.
305 return true;
306 }
307
308 MinidumpModuleListWriter::MinidumpModuleListWriter()
309 : MinidumpStreamWriter(), module_list_base_(), modules_() {
310 }
311
312 MinidumpModuleListWriter::~MinidumpModuleListWriter() {
313 }
314
315 void MinidumpModuleListWriter::AddModule(MinidumpModuleWriter* module) {
316 DCHECK_EQ(state(), kStateMutable);
317
318 modules_.push_back(module);
319 }
320
321 bool MinidumpModuleListWriter::Freeze() {
322 DCHECK_EQ(state(), kStateMutable);
323
324 if (!MinidumpStreamWriter::Freeze()) {
325 return false;
326 }
327
328 size_t module_count = modules_.size();
329 if (!AssignIfInRange(&module_list_base_.NumberOfModules, module_count)) {
330 LOG(ERROR) << "module_count " << module_count << " out of range";
331 return false;
332 }
333
334 return true;
335 }
336
337 size_t MinidumpModuleListWriter::SizeOfObject() {
338 DCHECK_GE(state(), kStateFrozen);
339
340 return sizeof(module_list_base_) + modules_.size() * sizeof(MINIDUMP_MODULE);
341 }
342
343 std::vector<internal::MinidumpWritable*> MinidumpModuleListWriter::Children() {
344 DCHECK_GE(state(), kStateFrozen);
345
346 std::vector<MinidumpWritable*> children;
347 for (MinidumpModuleWriter* module : modules_) {
348 children.push_back(module);
349 }
350
351 return children;
352 }
353
354 bool MinidumpModuleListWriter::WriteObject(FileWriterInterface* file_writer) {
355 DCHECK_EQ(state(), kStateWritable);
356
357 WritableIoVec iov;
358 iov.iov_base = &module_list_base_;
359 iov.iov_len = sizeof(module_list_base_);
360 std::vector<WritableIoVec> iovecs(1, iov);
361
362 for (const MinidumpModuleWriter* module : modules_) {
363 iov.iov_len = sizeof(MINIDUMP_MODULE);
364 iov.iov_base = module->MinidumpModule();
365 iovecs.push_back(iov);
366 }
367
368 return file_writer->WriteIoVec(&iovecs);
369 }
370
371 MinidumpStreamType MinidumpModuleListWriter::StreamType() const {
372 return kMinidumpStreamTypeModuleList;
373 }
374
375 } // namespace crashpad
OLDNEW
« no previous file with comments | « minidump/minidump_module_writer.h ('k') | minidump/minidump_module_writer_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698