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

Side by Side Diff: minidump/minidump_writable_test.cc

Issue 432003005: Introduce MinidumpWritable, its dependencies, and their tests (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
Patch Set: Address review comments 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_writable.cc ('k') | util/file/fd_io.h » ('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_writable.h"
16
17 #include <string>
18 #include <vector>
19
20 #include "base/basictypes.h"
21 #include "gtest/gtest.h"
22 #include "util/file/string_file_writer.h"
23
24 namespace {
25
26 using namespace crashpad;
27 using namespace testing;
28
29 class BaseTestMinidumpWritable : public crashpad::internal::MinidumpWritable {
30 public:
31 BaseTestMinidumpWritable()
32 : MinidumpWritable(),
33 children_(),
34 expected_offset_(-1),
35 alignment_(0),
36 phase_(kPhaseEarly),
37 has_alignment_(false),
38 has_phase_(false),
39 verified_(false) {}
40
41 ~BaseTestMinidumpWritable() { EXPECT_TRUE(verified_); }
42
43 void SetAlignment(size_t alignment) {
44 alignment_ = alignment;
45 has_alignment_ = true;
46 }
47
48 void AddChild(BaseTestMinidumpWritable* child) { children_.push_back(child); }
49
50 void SetPhaseLate() {
51 phase_ = kPhaseLate;
52 has_phase_ = true;
53 }
54
55 void Verify() {
56 verified_ = true;
57 EXPECT_EQ(kStateWritten, state());
58 for (BaseTestMinidumpWritable* child : children_) {
59 child->Verify();
60 }
61 }
62
63 protected:
64 virtual bool Freeze() override {
65 EXPECT_EQ(kStateMutable, state());
66 bool rv = MinidumpWritable::Freeze();
67 EXPECT_TRUE(rv);
68 EXPECT_EQ(kStateFrozen, state());
69 return rv;
70 }
71
72 virtual size_t Alignment() override {
73 EXPECT_GE(state(), kStateFrozen);
74 return has_alignment_ ? alignment_ : MinidumpWritable::Alignment();
75 }
76
77 virtual std::vector<MinidumpWritable*> Children() override {
78 EXPECT_GE(state(), kStateFrozen);
79 if (!children_.empty()) {
80 std::vector<MinidumpWritable*> children;
81 for (BaseTestMinidumpWritable* child : children_) {
82 children.push_back(child);
83 }
84 return children;
85 }
86 return MinidumpWritable::Children();
87 }
88
89 virtual Phase WritePhase() override {
90 return has_phase_ ? phase_ : MinidumpWritable::Phase();
91 }
92
93 virtual bool WillWriteAtOffsetImpl(off_t offset) override {
94 EXPECT_EQ(state(), kStateFrozen);
95 expected_offset_ = offset;
96 bool rv = MinidumpWritable::WillWriteAtOffsetImpl(offset);
97 EXPECT_TRUE(rv);
98 return rv;
99 }
100
101 virtual bool WriteObject(FileWriterInterface* file_writer) override {
102 EXPECT_EQ(state(), kStateWritable);
103 EXPECT_EQ(expected_offset_, file_writer->Seek(0, SEEK_CUR));
104
105 // Subclasses must override this.
106 return false;
107 }
108
109 private:
110 std::vector<BaseTestMinidumpWritable*> children_;
111 off_t expected_offset_;
112 size_t alignment_;
113 Phase phase_;
114 bool has_alignment_;
115 bool has_phase_;
116 bool verified_;
117
118 DISALLOW_COPY_AND_ASSIGN(BaseTestMinidumpWritable);
119 };
120
121 class TestStringMinidumpWritable final : public BaseTestMinidumpWritable {
122 public:
123 TestStringMinidumpWritable() : BaseTestMinidumpWritable(), data_() {}
124
125 ~TestStringMinidumpWritable() {}
126
127 void SetData(const std::string& string) { data_ = string; }
128
129 protected:
130 virtual size_t SizeOfObject() override {
131 EXPECT_GE(state(), kStateFrozen);
132 return data_.size();
133 }
134
135 virtual bool WriteObject(FileWriterInterface* file_writer) override {
136 BaseTestMinidumpWritable::WriteObject(file_writer);
137 EXPECT_TRUE(file_writer->Write(&data_[0], data_.size()));
138 return true;
139 }
140
141 private:
142 std::string data_;
143
144 DISALLOW_COPY_AND_ASSIGN(TestStringMinidumpWritable);
145 };
146
147 TEST(MinidumpWritable, MinidumpWritable) {
148 StringFileWriter writer;
149
150 {
151 SCOPED_TRACE("empty");
152 writer.Reset();
153 TestStringMinidumpWritable string_writable;
154 EXPECT_TRUE(string_writable.WriteEverything(&writer));
155 EXPECT_TRUE(writer.string().empty());
156 string_writable.Verify();
157 }
158
159 {
160 SCOPED_TRACE("childless");
161 writer.Reset();
162 TestStringMinidumpWritable string_writable;
163 string_writable.SetData("a");
164 EXPECT_TRUE(string_writable.WriteEverything(&writer));
165 EXPECT_EQ(1u, writer.string().size());
166 EXPECT_EQ("a", writer.string());
167 string_writable.Verify();
168 }
169
170 {
171 SCOPED_TRACE("parent-child");
172 writer.Reset();
173 TestStringMinidumpWritable parent;
174 parent.SetData("b");
175 TestStringMinidumpWritable child;
176 child.SetData("c");
177 parent.AddChild(&child);
178 EXPECT_TRUE(parent.WriteEverything(&writer));
179 EXPECT_EQ(5u, writer.string().size());
180 EXPECT_EQ(std::string("b\0\0\0c", 5), writer.string());
181 parent.Verify();
182 }
183
184 {
185 SCOPED_TRACE("base alignment 2");
186 writer.Reset();
187 TestStringMinidumpWritable parent;
188 parent.SetData("de");
189 TestStringMinidumpWritable child;
190 child.SetData("f");
191 parent.AddChild(&child);
192 EXPECT_TRUE(parent.WriteEverything(&writer));
193 EXPECT_EQ(5u, writer.string().size());
194 EXPECT_EQ(std::string("de\0\0f", 5), writer.string());
195 parent.Verify();
196 }
197
198 {
199 SCOPED_TRACE("base alignment 3");
200 writer.Reset();
201 TestStringMinidumpWritable parent;
202 parent.SetData("ghi");
203 TestStringMinidumpWritable child;
204 child.SetData("j");
205 parent.AddChild(&child);
206 EXPECT_TRUE(parent.WriteEverything(&writer));
207 EXPECT_EQ(5u, writer.string().size());
208 EXPECT_EQ(std::string("ghi\0j", 5), writer.string());
209 parent.Verify();
210 }
211
212 {
213 SCOPED_TRACE("base alignment 4");
214 writer.Reset();
215 TestStringMinidumpWritable parent;
216 parent.SetData("klmn");
217 TestStringMinidumpWritable child;
218 child.SetData("o");
219 parent.AddChild(&child);
220 EXPECT_TRUE(parent.WriteEverything(&writer));
221 EXPECT_EQ(5u, writer.string().size());
222 EXPECT_EQ("klmno", writer.string());
223 parent.Verify();
224 }
225
226 {
227 SCOPED_TRACE("base alignment 5");
228 writer.Reset();
229 TestStringMinidumpWritable parent;
230 parent.SetData("pqrst");
231 TestStringMinidumpWritable child;
232 child.SetData("u");
233 parent.AddChild(&child);
234 EXPECT_TRUE(parent.WriteEverything(&writer));
235 EXPECT_EQ(9u, writer.string().size());
236 EXPECT_EQ(std::string("pqrst\0\0\0u", 9), writer.string());
237 parent.Verify();
238 }
239
240 {
241 SCOPED_TRACE("two children");
242 writer.Reset();
243 TestStringMinidumpWritable parent;
244 parent.SetData("parent");
245 TestStringMinidumpWritable child_0;
246 child_0.SetData("child_0");
247 parent.AddChild(&child_0);
248 TestStringMinidumpWritable child_1;
249 child_1.SetData("child_1");
250 parent.AddChild(&child_1);
251 EXPECT_TRUE(parent.WriteEverything(&writer));
252 EXPECT_EQ(23u, writer.string().size());
253 EXPECT_EQ(std::string("parent\0\0child_0\0child_1", 23), writer.string());
254 parent.Verify();
255 }
256
257 {
258 SCOPED_TRACE("grandchild");
259 writer.Reset();
260 TestStringMinidumpWritable parent;
261 parent.SetData("parent");
262 TestStringMinidumpWritable child;
263 child.SetData("child");
264 parent.AddChild(&child);
265 TestStringMinidumpWritable grandchild;
266 grandchild.SetData("grandchild");
267 child.AddChild(&grandchild);
268 EXPECT_TRUE(parent.WriteEverything(&writer));
269 EXPECT_EQ(26u, writer.string().size());
270 EXPECT_EQ(std::string("parent\0\0child\0\0\0grandchild", 26),
271 writer.string());
272 parent.Verify();
273 }
274
275 {
276 SCOPED_TRACE("grandchild with empty parent");
277 writer.Reset();
278 TestStringMinidumpWritable parent;
279 TestStringMinidumpWritable child;
280 child.SetData("child");
281 parent.AddChild(&child);
282 TestStringMinidumpWritable grandchild;
283 grandchild.SetData("grandchild");
284 child.AddChild(&grandchild);
285 EXPECT_TRUE(parent.WriteEverything(&writer));
286 EXPECT_EQ(18u, writer.string().size());
287 EXPECT_EQ(std::string("child\0\0\0grandchild", 18), writer.string());
288 parent.Verify();
289 }
290
291 {
292 SCOPED_TRACE("grandchild with empty child");
293 writer.Reset();
294 TestStringMinidumpWritable parent;
295 parent.SetData("parent");
296 TestStringMinidumpWritable child;
297 parent.AddChild(&child);
298 TestStringMinidumpWritable grandchild;
299 grandchild.SetData("grandchild");
300 child.AddChild(&grandchild);
301 EXPECT_TRUE(parent.WriteEverything(&writer));
302 EXPECT_EQ(18u, writer.string().size());
303 EXPECT_EQ(std::string("parent\0\0grandchild", 18), writer.string());
304 parent.Verify();
305 }
306
307 {
308 SCOPED_TRACE("grandchild with empty grandchild");
309 writer.Reset();
310 TestStringMinidumpWritable parent;
311 parent.SetData("parent");
312 TestStringMinidumpWritable child;
313 child.SetData("child");
314 parent.AddChild(&child);
315 TestStringMinidumpWritable grandchild;
316 child.AddChild(&grandchild);
317 EXPECT_TRUE(parent.WriteEverything(&writer));
318 EXPECT_EQ(13u, writer.string().size());
319 EXPECT_EQ(std::string("parent\0\0child", 13), writer.string());
320 parent.Verify();
321 }
322
323 {
324 SCOPED_TRACE("grandchild with late-phase grandchild");
325 writer.Reset();
326 TestStringMinidumpWritable parent;
327 parent.SetData("parent");
328 TestStringMinidumpWritable child;
329 child.SetData("child");
330 parent.AddChild(&child);
331 TestStringMinidumpWritable grandchild;
332 grandchild.SetData("grandchild");
333 grandchild.SetPhaseLate();
334 child.AddChild(&grandchild);
335 EXPECT_TRUE(parent.WriteEverything(&writer));
336 EXPECT_EQ(26u, writer.string().size());
337 EXPECT_EQ(std::string("parent\0\0child\0\0\0grandchild", 26),
338 writer.string());
339 parent.Verify();
340 }
341
342 {
343 SCOPED_TRACE("grandchild with late-phase child");
344 writer.Reset();
345 TestStringMinidumpWritable parent;
346 parent.SetData("parent");
347 TestStringMinidumpWritable child;
348 child.SetData("child");
349 child.SetPhaseLate();
350 parent.AddChild(&child);
351 TestStringMinidumpWritable grandchild;
352 grandchild.SetData("grandchild");
353 child.AddChild(&grandchild);
354 EXPECT_TRUE(parent.WriteEverything(&writer));
355 EXPECT_EQ(25u, writer.string().size());
356 EXPECT_EQ(std::string("parent\0\0grandchild\0\0child", 25),
357 writer.string());
358 parent.Verify();
359 }
360
361 {
362 SCOPED_TRACE("family tree");
363 writer.Reset();
364 TestStringMinidumpWritable parent;
365 parent.SetData("P..");
366 TestStringMinidumpWritable child_0;
367 child_0.SetData("C0.");
368 parent.AddChild(&child_0);
369 TestStringMinidumpWritable child_1;
370 child_1.SetData("C1.");
371 parent.AddChild(&child_1);
372 TestStringMinidumpWritable grandchild_00;
373 grandchild_00.SetData("G00");
374 child_0.AddChild(&grandchild_00);
375 TestStringMinidumpWritable grandchild_01;
376 grandchild_01.SetData("G01");
377 child_0.AddChild(&grandchild_01);
378 TestStringMinidumpWritable grandchild_10;
379 grandchild_10.SetData("G10");
380 child_1.AddChild(&grandchild_10);
381 TestStringMinidumpWritable grandchild_11;
382 grandchild_11.SetData("G11");
383 child_1.AddChild(&grandchild_11);
384 EXPECT_TRUE(parent.WriteEverything(&writer));
385 EXPECT_EQ(27u, writer.string().size());
386 EXPECT_EQ(std::string("P..\0C0.\0G00\0G01\0C1.\0G10\0G11", 27),
387 writer.string());
388 parent.Verify();
389 }
390
391 {
392 SCOPED_TRACE("family tree with C0 late");
393 writer.Reset();
394 TestStringMinidumpWritable parent;
395 parent.SetData("P..");
396 TestStringMinidumpWritable child_0;
397 child_0.SetData("C0.");
398 child_0.SetPhaseLate();
399 parent.AddChild(&child_0);
400 TestStringMinidumpWritable child_1;
401 child_1.SetData("C1.");
402 parent.AddChild(&child_1);
403 TestStringMinidumpWritable grandchild_00;
404 grandchild_00.SetData("G00");
405 child_0.AddChild(&grandchild_00);
406 TestStringMinidumpWritable grandchild_01;
407 grandchild_01.SetData("G01");
408 child_0.AddChild(&grandchild_01);
409 TestStringMinidumpWritable grandchild_10;
410 grandchild_10.SetData("G10");
411 child_1.AddChild(&grandchild_10);
412 TestStringMinidumpWritable grandchild_11;
413 grandchild_11.SetData("G11");
414 child_1.AddChild(&grandchild_11);
415 EXPECT_TRUE(parent.WriteEverything(&writer));
416 EXPECT_EQ(27u, writer.string().size());
417 EXPECT_EQ(std::string("P..\0G00\0G01\0C1.\0G10\0G11\0C0.", 27),
418 writer.string());
419 parent.Verify();
420 }
421
422 {
423 SCOPED_TRACE("family tree with G0 late");
424 writer.Reset();
425 TestStringMinidumpWritable parent;
426 parent.SetData("P..");
427 TestStringMinidumpWritable child_0;
428 child_0.SetData("C0.");
429 parent.AddChild(&child_0);
430 TestStringMinidumpWritable child_1;
431 child_1.SetData("C1.");
432 parent.AddChild(&child_1);
433 TestStringMinidumpWritable grandchild_00;
434 grandchild_00.SetData("G00");
435 grandchild_00.SetPhaseLate();
436 child_0.AddChild(&grandchild_00);
437 TestStringMinidumpWritable grandchild_01;
438 grandchild_01.SetData("G01");
439 grandchild_01.SetPhaseLate();
440 child_0.AddChild(&grandchild_01);
441 TestStringMinidumpWritable grandchild_10;
442 grandchild_10.SetData("G10");
443 child_1.AddChild(&grandchild_10);
444 TestStringMinidumpWritable grandchild_11;
445 grandchild_11.SetData("G11");
446 child_1.AddChild(&grandchild_11);
447 EXPECT_TRUE(parent.WriteEverything(&writer));
448 EXPECT_EQ(27u, writer.string().size());
449 EXPECT_EQ(std::string("P..\0C0.\0C1.\0G10\0G11\0G00\0G01", 27),
450 writer.string());
451 parent.Verify();
452 }
453
454 {
455 SCOPED_TRACE("align 1");
456 writer.Reset();
457 TestStringMinidumpWritable parent;
458 parent.SetData("p");
459 TestStringMinidumpWritable child;
460 child.SetData("c");
461 child.SetAlignment(1);
462 parent.AddChild(&child);
463 EXPECT_TRUE(parent.WriteEverything(&writer));
464 EXPECT_EQ(2u, writer.string().size());
465 EXPECT_EQ("pc", writer.string());
466 parent.Verify();
467 }
468
469 {
470 SCOPED_TRACE("align 2");
471 writer.Reset();
472 TestStringMinidumpWritable parent;
473 parent.SetData("p");
474 TestStringMinidumpWritable child;
475 child.SetData("c");
476 child.SetAlignment(2);
477 parent.AddChild(&child);
478 EXPECT_TRUE(parent.WriteEverything(&writer));
479 EXPECT_EQ(3u, writer.string().size());
480 EXPECT_EQ(std::string("p\0c", 3), writer.string());
481 parent.Verify();
482 }
483 }
484
485 class TestRVAMinidumpWritable final : public BaseTestMinidumpWritable {
486 public:
487 TestRVAMinidumpWritable() : BaseTestMinidumpWritable(), rva_() {}
488
489 ~TestRVAMinidumpWritable() {}
490
491 void SetRVA(MinidumpWritable* other) { other->RegisterRVA(&rva_); }
492
493 protected:
494 virtual size_t SizeOfObject() override {
495 EXPECT_GE(state(), kStateFrozen);
496 return sizeof(rva_);
497 }
498
499 virtual bool WriteObject(FileWriterInterface* file_writer) override {
500 BaseTestMinidumpWritable::WriteObject(file_writer);
501 EXPECT_TRUE(file_writer->Write(&rva_, sizeof(rva_)));
502 return true;
503 }
504
505 private:
506 RVA rva_;
507
508 DISALLOW_COPY_AND_ASSIGN(TestRVAMinidumpWritable);
509 };
510
511 RVA RVAAtIndex(const std::string& string, size_t index) {
512 return *reinterpret_cast<const RVA*>(&string[index * sizeof(RVA)]);
513 }
514
515 TEST(MinidumpWritable, RVA) {
516 StringFileWriter writer;
517
518 {
519 SCOPED_TRACE("unset");
520 writer.Reset();
521 TestRVAMinidumpWritable rva_writable;
522 EXPECT_TRUE(rva_writable.WriteEverything(&writer));
523
524 ASSERT_EQ(sizeof(RVA), writer.string().size());
525 EXPECT_EQ(0 * sizeof(RVA), RVAAtIndex(writer.string(), 0));
526 rva_writable.Verify();
527 }
528
529 {
530 SCOPED_TRACE("self");
531 writer.Reset();
532 TestRVAMinidumpWritable rva_writable;
533 rva_writable.SetRVA(&rva_writable);
534 EXPECT_TRUE(rva_writable.WriteEverything(&writer));
535
536 ASSERT_EQ(sizeof(RVA), writer.string().size());
537 EXPECT_EQ(0 * sizeof(RVA), RVAAtIndex(writer.string(), 0));
538 rva_writable.Verify();
539 }
540
541 {
542 SCOPED_TRACE("parent-child self");
543 writer.Reset();
544 TestRVAMinidumpWritable parent;
545 parent.SetRVA(&parent);
546 TestRVAMinidumpWritable child;
547 child.SetRVA(&child);
548 parent.AddChild(&child);
549 EXPECT_TRUE(parent.WriteEverything(&writer));
550
551 ASSERT_EQ(2 * sizeof(RVA), writer.string().size());
552 EXPECT_EQ(0 * sizeof(RVA), RVAAtIndex(writer.string(), 0));
553 EXPECT_EQ(1 * sizeof(RVA), RVAAtIndex(writer.string(), 1));
554 parent.Verify();
555 }
556
557 {
558 SCOPED_TRACE("parent-child only");
559 writer.Reset();
560 TestRVAMinidumpWritable parent;
561 TestRVAMinidumpWritable child;
562 parent.SetRVA(&child);
563 parent.AddChild(&child);
564 EXPECT_TRUE(parent.WriteEverything(&writer));
565
566 ASSERT_EQ(2 * sizeof(RVA), writer.string().size());
567 EXPECT_EQ(1 * sizeof(RVA), RVAAtIndex(writer.string(), 0));
568 EXPECT_EQ(0 * sizeof(RVA), RVAAtIndex(writer.string(), 1));
569 parent.Verify();
570 }
571
572 {
573 SCOPED_TRACE("parent-child circular");
574 writer.Reset();
575 TestRVAMinidumpWritable parent;
576 TestRVAMinidumpWritable child;
577 parent.SetRVA(&child);
578 child.SetRVA(&parent);
579 parent.AddChild(&child);
580 EXPECT_TRUE(parent.WriteEverything(&writer));
581
582 ASSERT_EQ(2 * sizeof(RVA), writer.string().size());
583 EXPECT_EQ(1 * sizeof(RVA), RVAAtIndex(writer.string(), 0));
584 EXPECT_EQ(0 * sizeof(RVA), RVAAtIndex(writer.string(), 1));
585 parent.Verify();
586 }
587
588 {
589 SCOPED_TRACE("grandchildren");
590 writer.Reset();
591 TestRVAMinidumpWritable parent;
592 TestRVAMinidumpWritable child;
593 parent.SetRVA(&child);
594 parent.AddChild(&child);
595 TestRVAMinidumpWritable grandchild_0;
596 grandchild_0.SetRVA(&child);
597 child.AddChild(&grandchild_0);
598 TestRVAMinidumpWritable grandchild_1;
599 grandchild_1.SetRVA(&child);
600 child.AddChild(&grandchild_1);
601 TestRVAMinidumpWritable grandchild_2;
602 grandchild_2.SetRVA(&child);
603 child.AddChild(&grandchild_2);
604 EXPECT_TRUE(parent.WriteEverything(&writer));
605
606 ASSERT_EQ(5 * sizeof(RVA), writer.string().size());
607 EXPECT_EQ(1 * sizeof(RVA), RVAAtIndex(writer.string(), 0));
608 EXPECT_EQ(0 * sizeof(RVA), RVAAtIndex(writer.string(), 1));
609 EXPECT_EQ(1 * sizeof(RVA), RVAAtIndex(writer.string(), 2));
610 EXPECT_EQ(1 * sizeof(RVA), RVAAtIndex(writer.string(), 3));
611 EXPECT_EQ(1 * sizeof(RVA), RVAAtIndex(writer.string(), 4));
612 parent.Verify();
613 }
614 }
615
616 class TestLocationDescriptorMinidumpWritable final
617 : public BaseTestMinidumpWritable {
618 public:
619 TestLocationDescriptorMinidumpWritable()
620 : BaseTestMinidumpWritable(), location_descriptor_(), string_() {}
621
622 ~TestLocationDescriptorMinidumpWritable() {}
623
624 void SetLocationDescriptor(MinidumpWritable* other) {
625 other->RegisterLocationDescriptor(&location_descriptor_);
626 }
627
628 void SetString(const std::string& string) { string_ = string; }
629
630 protected:
631 virtual size_t SizeOfObject() override {
632 EXPECT_GE(state(), kStateFrozen);
633 // NUL-terminate.
634 return sizeof(location_descriptor_) + string_.size() + 1;
635 }
636
637 virtual bool WriteObject(FileWriterInterface* file_writer) override {
638 BaseTestMinidumpWritable::WriteObject(file_writer);
639 WritableIoVec iov;
640 iov.iov_base = &location_descriptor_;
641 iov.iov_len = sizeof(location_descriptor_);
642 std::vector<WritableIoVec> iovecs(1, iov);
643 // NUL-terminate.
644 iov.iov_base = &string_[0];
645 iov.iov_len = string_.size() + 1;
646 iovecs.push_back(iov);
647 EXPECT_TRUE(file_writer->WriteIoVec(&iovecs));
648 return true;
649 }
650
651 private:
652 MINIDUMP_LOCATION_DESCRIPTOR location_descriptor_;
653 std::string string_;
654
655 DISALLOW_COPY_AND_ASSIGN(TestLocationDescriptorMinidumpWritable);
656 };
657
658 struct LocationDescriptorAndData {
659 MINIDUMP_LOCATION_DESCRIPTOR location_descriptor;
660 char string[1];
661 };
662
663 const LocationDescriptorAndData* LDDAtIndex(const std::string& string,
664 size_t index) {
665 return reinterpret_cast<const LocationDescriptorAndData*>(&string[index]);
666 }
667
668 TEST(MinidumpWritable, LocationDescriptor) {
669 StringFileWriter writer;
670
671 {
672 SCOPED_TRACE("unset");
673 writer.Reset();
674 TestLocationDescriptorMinidumpWritable location_descriptor_writable;
675 EXPECT_TRUE(location_descriptor_writable.WriteEverything(&writer));
676
677 ASSERT_EQ(9u, writer.string().size());
678 const LocationDescriptorAndData* ldd = LDDAtIndex(writer.string(), 0);
679 EXPECT_EQ(0u, ldd->location_descriptor.DataSize);
680 EXPECT_EQ(0u, ldd->location_descriptor.Rva);
681 location_descriptor_writable.Verify();
682 }
683
684 {
685 SCOPED_TRACE("self");
686 writer.Reset();
687 TestLocationDescriptorMinidumpWritable location_descriptor_writable;
688 location_descriptor_writable.SetLocationDescriptor(
689 &location_descriptor_writable);
690 EXPECT_TRUE(location_descriptor_writable.WriteEverything(&writer));
691
692 ASSERT_EQ(9u, writer.string().size());
693 const LocationDescriptorAndData* ldd = LDDAtIndex(writer.string(), 0);
694 EXPECT_EQ(9u, ldd->location_descriptor.DataSize);
695 EXPECT_EQ(0u, ldd->location_descriptor.Rva);
696 location_descriptor_writable.Verify();
697 }
698
699 {
700 SCOPED_TRACE("self with data");
701 writer.Reset();
702 TestLocationDescriptorMinidumpWritable location_descriptor_writable;
703 location_descriptor_writable.SetLocationDescriptor(
704 &location_descriptor_writable);
705 location_descriptor_writable.SetString("zz");
706 EXPECT_TRUE(location_descriptor_writable.WriteEverything(&writer));
707
708 ASSERT_EQ(11u, writer.string().size());
709 const LocationDescriptorAndData* ldd = LDDAtIndex(writer.string(), 0);
710 EXPECT_EQ(11u, ldd->location_descriptor.DataSize);
711 EXPECT_EQ(0u, ldd->location_descriptor.Rva);
712 EXPECT_STREQ("zz", ldd->string);
713 location_descriptor_writable.Verify();
714 }
715
716 {
717 SCOPED_TRACE("parent-child self");
718 writer.Reset();
719 TestLocationDescriptorMinidumpWritable parent;
720 parent.SetLocationDescriptor(&parent);
721 parent.SetString("yy");
722 TestLocationDescriptorMinidumpWritable child;
723 child.SetLocationDescriptor(&child);
724 child.SetString("x");
725 parent.AddChild(&child);
726 EXPECT_TRUE(parent.WriteEverything(&writer));
727
728 ASSERT_EQ(22u, writer.string().size());
729 const LocationDescriptorAndData* ldd = LDDAtIndex(writer.string(), 0);
730 EXPECT_EQ(11u, ldd->location_descriptor.DataSize);
731 EXPECT_EQ(0u, ldd->location_descriptor.Rva);
732 EXPECT_STREQ("yy", ldd->string);
733 ldd = LDDAtIndex(writer.string(), 12);
734 EXPECT_EQ(10u, ldd->location_descriptor.DataSize);
735 EXPECT_EQ(12u, ldd->location_descriptor.Rva);
736 EXPECT_STREQ("x", ldd->string);
737 parent.Verify();
738 }
739
740 {
741 SCOPED_TRACE("parent-child only");
742 writer.Reset();
743 TestLocationDescriptorMinidumpWritable parent;
744 TestLocationDescriptorMinidumpWritable child;
745 parent.SetLocationDescriptor(&child);
746 parent.SetString("www");
747 child.SetString("vv");
748 parent.AddChild(&child);
749 EXPECT_TRUE(parent.WriteEverything(&writer));
750
751 ASSERT_EQ(23u, writer.string().size());
752 const LocationDescriptorAndData* ldd = LDDAtIndex(writer.string(), 0);
753 EXPECT_EQ(11u, ldd->location_descriptor.DataSize);
754 EXPECT_EQ(12u, ldd->location_descriptor.Rva);
755 EXPECT_STREQ("www", ldd->string);
756 ldd = LDDAtIndex(writer.string(), 12);
757 EXPECT_EQ(0u, ldd->location_descriptor.DataSize);
758 EXPECT_EQ(0u, ldd->location_descriptor.Rva);
759 EXPECT_STREQ("vv", ldd->string);
760 parent.Verify();
761 }
762
763 {
764 SCOPED_TRACE("parent-child circular");
765 writer.Reset();
766 TestLocationDescriptorMinidumpWritable parent;
767 TestLocationDescriptorMinidumpWritable child;
768 parent.SetLocationDescriptor(&child);
769 parent.SetString("uuuu");
770 child.SetLocationDescriptor(&parent);
771 child.SetString("tttt");
772 parent.AddChild(&child);
773 EXPECT_TRUE(parent.WriteEverything(&writer));
774
775 ASSERT_EQ(29u, writer.string().size());
776 const LocationDescriptorAndData* ldd = LDDAtIndex(writer.string(), 0);
777 EXPECT_EQ(13u, ldd->location_descriptor.DataSize);
778 EXPECT_EQ(16u, ldd->location_descriptor.Rva);
779 EXPECT_STREQ("uuuu", ldd->string);
780 ldd = LDDAtIndex(writer.string(), 16);
781 EXPECT_EQ(13u, ldd->location_descriptor.DataSize);
782 EXPECT_EQ(0u, ldd->location_descriptor.Rva);
783 EXPECT_STREQ("tttt", ldd->string);
784 parent.Verify();
785 }
786
787 {
788 SCOPED_TRACE("grandchildren");
789 writer.Reset();
790 TestLocationDescriptorMinidumpWritable parent;
791 TestLocationDescriptorMinidumpWritable child;
792 parent.SetLocationDescriptor(&child);
793 parent.SetString("s");
794 parent.AddChild(&child);
795 child.SetString("r");
796 TestLocationDescriptorMinidumpWritable grandchild_0;
797 grandchild_0.SetLocationDescriptor(&child);
798 grandchild_0.SetString("q");
799 child.AddChild(&grandchild_0);
800 TestLocationDescriptorMinidumpWritable grandchild_1;
801 grandchild_1.SetLocationDescriptor(&child);
802 grandchild_1.SetString("p");
803 child.AddChild(&grandchild_1);
804 TestLocationDescriptorMinidumpWritable grandchild_2;
805 grandchild_2.SetLocationDescriptor(&child);
806 grandchild_2.SetString("o");
807 child.AddChild(&grandchild_2);
808 EXPECT_TRUE(parent.WriteEverything(&writer));
809
810 ASSERT_EQ(58u, writer.string().size());
811 const LocationDescriptorAndData* ldd = LDDAtIndex(writer.string(), 0);
812 EXPECT_EQ(10u, ldd->location_descriptor.DataSize);
813 EXPECT_EQ(12u, ldd->location_descriptor.Rva);
814 EXPECT_STREQ("s", ldd->string);
815 ldd = LDDAtIndex(writer.string(), 12);
816 EXPECT_EQ(0u, ldd->location_descriptor.DataSize);
817 EXPECT_EQ(0u, ldd->location_descriptor.Rva);
818 EXPECT_STREQ("r", ldd->string);
819 ldd = LDDAtIndex(writer.string(), 24);
820 EXPECT_EQ(10u, ldd->location_descriptor.DataSize);
821 EXPECT_EQ(12u, ldd->location_descriptor.Rva);
822 EXPECT_STREQ("q", ldd->string);
823 ldd = LDDAtIndex(writer.string(), 36);
824 EXPECT_EQ(10u, ldd->location_descriptor.DataSize);
825 EXPECT_EQ(12u, ldd->location_descriptor.Rva);
826 EXPECT_STREQ("p", ldd->string);
827 ldd = LDDAtIndex(writer.string(), 48);
828 EXPECT_EQ(10u, ldd->location_descriptor.DataSize);
829 EXPECT_EQ(12u, ldd->location_descriptor.Rva);
830 EXPECT_STREQ("o", ldd->string);
831 parent.Verify();
832 }
833 }
834
835 } // namespace
OLDNEW
« no previous file with comments | « minidump/minidump_writable.cc ('k') | util/file/fd_io.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698