OLD | NEW |
---|---|
1 // Copyright 2012 Google Inc. All Rights Reserved. | 1 // Copyright 2012 Google Inc. 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, |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
310 // An overflowing range is always inaccessible. | 310 // An overflowing range is always inaccessible. |
311 EXPECT_EQ(test_array + 3, test_shadow.FindFirstPoisonedByte( | 311 EXPECT_EQ(test_array + 3, test_shadow.FindFirstPoisonedByte( |
312 test_array + 3, static_cast<size_t>(-3))); | 312 test_array + 3, static_cast<size_t>(-3))); |
313 | 313 |
314 for (size_t i = 0; i < size; ++i) { | 314 for (size_t i = 0; i < size; ++i) { |
315 // Try valid ranges at every starting position inside the unpoisoned | 315 // Try valid ranges at every starting position inside the unpoisoned |
316 // range. | 316 // range. |
317 EXPECT_EQ(nullptr, | 317 EXPECT_EQ(nullptr, |
318 test_shadow.FindFirstPoisonedByte(test_array + i, size - i)); | 318 test_shadow.FindFirstPoisonedByte(test_array + i, size - i)); |
319 | 319 |
320 // Try valid ranges ending at every poisition inside the unpoisoned range. | 320 // Try valid ranges ending at every position inside the unpoisoned range. |
321 EXPECT_EQ(nullptr, | 321 EXPECT_EQ(nullptr, |
322 test_shadow.FindFirstPoisonedByte(test_array, size - i)); | 322 test_shadow.FindFirstPoisonedByte(test_array, size - i)); |
323 } | 323 } |
324 | 324 |
325 for (size_t i = 1; i < kShadowRatio; ++i) { | 325 for (size_t i = 1; i < kShadowRatio; ++i) { |
326 // Try invalid ranges at starting positions outside the unpoisoned range. | 326 // Try invalid ranges at starting positions outside the unpoisoned range. |
327 EXPECT_EQ(test_array - i, | 327 EXPECT_EQ(test_array - i, |
328 test_shadow.FindFirstPoisonedByte(test_array - i, size)); | 328 test_shadow.FindFirstPoisonedByte(test_array - i, size)); |
329 | 329 |
330 // Try invalid ranges at ending positions outside the unpoisoned range. | 330 // Try invalid ranges at ending positions outside the unpoisoned range. |
331 EXPECT_EQ(test_array + size, | 331 EXPECT_EQ(test_array + size, |
332 test_shadow.FindFirstPoisonedByte(test_array, size + i)); | 332 test_shadow.FindFirstPoisonedByte(test_array, size + i)); |
333 } | 333 } |
334 } | 334 } |
335 test_shadow.Unpoison(aligned_test_array, aligned_array_length); | 335 test_shadow.Unpoison(aligned_test_array, aligned_array_length); |
336 } | 336 } |
337 | 337 |
338 TEST_F(ShadowTest, MarkAsFreed) { | 338 TEST_F(ShadowTest, MarkAsFreed) { |
339 BlockLayout l0 = {}, l1 = {}; | 339 BlockLayout l0 = {}, l1 = {}; |
340 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, 16, 30, 30, &l1)); | 340 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, 16, 30, 30, &l1)); |
341 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, | 341 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, |
342 l1.block_size + 2 * kShadowRatio, 30, 30, &l0)); | 342 l1.block_size + 2 * kShadowRatio, 30, 30, &l0)); |
343 | 343 |
344 uint8_t* data = new uint8_t[l0.block_size]; | 344 uint8_t* data = new uint8_t[l0.block_size]; |
345 | 345 |
346 uint8_t* d0 = data; | 346 uint8_t* d0 = data; |
347 BlockInfo i0 = {}; | 347 BlockInfo i0 = {}; |
348 BlockInitialize(l0, d0, false, &i0); | 348 BlockInitialize(l0, d0, &i0); |
349 test_shadow.PoisonAllocatedBlock(i0); | 349 test_shadow.PoisonAllocatedBlock(i0); |
350 | 350 |
351 uint8_t* d1 = i0.RawBody() + kShadowRatio; | 351 uint8_t* d1 = i0.RawBody() + kShadowRatio; |
352 BlockInfo i1 = {}; | 352 BlockInfo i1 = {}; |
353 BlockInitialize(l1, d1, true, &i1); | 353 BlockInitialize(l1, d1, &i1); |
354 test_shadow.PoisonAllocatedBlock(i1); | 354 test_shadow.PoisonAllocatedBlock(i1); |
355 | 355 |
356 test_shadow.MarkAsFreed(i0.body, i0.body_size); | 356 test_shadow.MarkAsFreed(i0.body, i0.body_size); |
357 for (uint8_t* p = i0.RawBlock(); p < i0.RawBlock() + i0.block_size; ++p) { | 357 for (uint8_t* p = i0.RawBlock(); p < i0.RawBlock() + i0.block_size; ++p) { |
358 if (p >= i0.RawBlock() && p < i0.RawBody()) { | 358 if (p >= i0.RawBlock() && p < i0.RawBody()) { |
359 EXPECT_TRUE(test_shadow.IsLeftRedzone(p)); | 359 EXPECT_TRUE(test_shadow.IsLeftRedzone(p)); |
360 } else if (p >= i0.RawBody() && | 360 } else if (p >= i0.RawBody() && |
361 p < i0.RawTrailerPadding()) { | 361 p < i0.RawTrailerPadding()) { |
362 if (p >= i1.RawBlock() && p < i1.RawBody()) { | 362 if (p >= i1.RawBlock() && p < i1.RawBody()) { |
363 EXPECT_TRUE(test_shadow.IsLeftRedzone(p)); | 363 EXPECT_TRUE(test_shadow.IsLeftRedzone(p)); |
(...skipping 16 matching lines...) Expand all Loading... | |
380 test_shadow.Unpoison(data, l0.block_size); | 380 test_shadow.Unpoison(data, l0.block_size); |
381 delete [] data; | 381 delete [] data; |
382 } | 382 } |
383 | 383 |
384 TEST_F(ShadowTest, PoisonAllocatedBlock) { | 384 TEST_F(ShadowTest, PoisonAllocatedBlock) { |
385 BlockLayout layout = {}; | 385 BlockLayout layout = {}; |
386 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, 15, 22, 0, &layout)); | 386 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, 15, 22, 0, &layout)); |
387 | 387 |
388 uint8_t* data = new uint8_t[layout.block_size]; | 388 uint8_t* data = new uint8_t[layout.block_size]; |
389 BlockInfo info = {}; | 389 BlockInfo info = {}; |
390 BlockInitialize(layout, data, false, &info); | 390 BlockInitialize(layout, data, &info); |
391 | 391 |
392 test_shadow.PoisonAllocatedBlock(info); | 392 test_shadow.PoisonAllocatedBlock(info); |
393 EXPECT_EQ(test_shadow.GetShadowMarkerForAddress(data + 0 * 8), | 393 EXPECT_EQ(test_shadow.GetShadowMarkerForAddress(data + 0 * 8), |
394 kHeapBlockStartMarker0 | 7); | 394 kHeapBlockStartMarker0 | 7); |
395 EXPECT_EQ(test_shadow.GetShadowMarkerForAddress(data + 1 * 8), | 395 EXPECT_EQ(test_shadow.GetShadowMarkerForAddress(data + 1 * 8), |
396 kHeapLeftPaddingMarker); | 396 kHeapLeftPaddingMarker); |
397 EXPECT_EQ(test_shadow.GetShadowMarkerForAddress(data + 2 * 8), | 397 EXPECT_EQ(test_shadow.GetShadowMarkerForAddress(data + 2 * 8), |
398 kHeapLeftPaddingMarker); | 398 kHeapLeftPaddingMarker); |
399 EXPECT_EQ(test_shadow.GetShadowMarkerForAddress(data + 3 * 8), | 399 EXPECT_EQ(test_shadow.GetShadowMarkerForAddress(data + 3 * 8), |
400 0); | 400 0); |
(...skipping 22 matching lines...) Expand all Loading... | |
423 EXPECT_FALSE(test_shadow.IsAccessible(cursor)); | 423 EXPECT_FALSE(test_shadow.IsAccessible(cursor)); |
424 test_shadow.Unpoison(info.RawBlock(), info.block_size); | 424 test_shadow.Unpoison(info.RawBlock(), info.block_size); |
425 | 425 |
426 delete [] data; | 426 delete [] data; |
427 } | 427 } |
428 | 428 |
429 TEST_F(ShadowTest, ScanLeftAndRight) { | 429 TEST_F(ShadowTest, ScanLeftAndRight) { |
430 size_t offset = test_shadow.length() / 2; | 430 size_t offset = test_shadow.length() / 2; |
431 size_t l = 0; | 431 size_t l = 0; |
432 test_shadow.shadow_[offset + 0] = kHeapBlockStartMarker0; | 432 test_shadow.shadow_[offset + 0] = kHeapBlockStartMarker0; |
433 test_shadow.shadow_[offset + 1] = kHeapNestedBlockStartMarker0; | 433 test_shadow.shadow_[offset + 1] = kHeapAddressableMarker; |
434 test_shadow.shadow_[offset + 2] = kHeapAddressableMarker; | 434 test_shadow.shadow_[offset + 2] = kHeapBlockEndMarker; |
435 test_shadow.shadow_[offset + 3] = kHeapNestedBlockEndMarker; | |
436 test_shadow.shadow_[offset + 4] = kHeapBlockEndMarker; | |
437 | 435 |
438 EXPECT_TRUE(test_shadow.ScanLeftForBracketingBlockStart(0, offset + 0, &l)); | 436 EXPECT_TRUE(test_shadow.ScanLeftForBracketingBlockStart(offset + 0, &l)); |
439 EXPECT_EQ(offset, l); | 437 EXPECT_EQ(offset, l); |
440 EXPECT_TRUE(test_shadow.ScanLeftForBracketingBlockStart(0, offset + 1, &l)); | 438 EXPECT_TRUE(test_shadow.ScanLeftForBracketingBlockStart(offset + 1, &l)); |
441 EXPECT_EQ(offset + 1, l); | 439 EXPECT_EQ(offset, l); |
442 EXPECT_TRUE(test_shadow.ScanLeftForBracketingBlockStart(0, offset + 2, &l)); | 440 EXPECT_TRUE(test_shadow.ScanLeftForBracketingBlockStart(offset + 2, &l)); |
443 EXPECT_EQ(offset + 1, l); | |
444 EXPECT_TRUE(test_shadow.ScanLeftForBracketingBlockStart(0, offset + 3, &l)); | |
445 EXPECT_EQ(offset + 1, l); | |
446 EXPECT_TRUE(test_shadow.ScanLeftForBracketingBlockStart(0, offset + 4, &l)); | |
447 EXPECT_EQ(offset, l); | 441 EXPECT_EQ(offset, l); |
448 | 442 |
449 EXPECT_FALSE(test_shadow.ScanLeftForBracketingBlockStart(1, offset + 0, &l)); | 443 EXPECT_TRUE(test_shadow.ScanRightForBracketingBlockEnd(offset + 0, &l)); |
450 EXPECT_TRUE(test_shadow.ScanLeftForBracketingBlockStart(1, offset + 1, &l)); | 444 EXPECT_EQ(offset + 2, l); |
451 EXPECT_EQ(offset, l); | 445 EXPECT_TRUE(test_shadow.ScanRightForBracketingBlockEnd(offset + 1, &l)); |
452 EXPECT_TRUE(test_shadow.ScanLeftForBracketingBlockStart(1, offset + 2, &l)); | 446 EXPECT_EQ(offset + 2, l); |
453 EXPECT_EQ(offset, l); | 447 EXPECT_TRUE(test_shadow.ScanRightForBracketingBlockEnd(offset + 2, &l)); |
454 EXPECT_TRUE(test_shadow.ScanLeftForBracketingBlockStart(1, offset + 3, &l)); | 448 EXPECT_EQ(offset + 2, l); |
455 EXPECT_EQ(offset, l); | |
456 EXPECT_FALSE(test_shadow.ScanLeftForBracketingBlockStart(1, offset + 4, &l)); | |
457 | |
458 EXPECT_FALSE(test_shadow.ScanLeftForBracketingBlockStart(2, offset + 0, &l)); | |
459 EXPECT_FALSE(test_shadow.ScanLeftForBracketingBlockStart(2, offset + 1, &l)); | |
460 EXPECT_FALSE(test_shadow.ScanLeftForBracketingBlockStart(2, offset + 2, &l)); | |
461 EXPECT_FALSE(test_shadow.ScanLeftForBracketingBlockStart(2, offset + 3, &l)); | |
462 EXPECT_FALSE(test_shadow.ScanLeftForBracketingBlockStart(2, offset + 4, &l)); | |
463 | |
464 EXPECT_TRUE(test_shadow.ScanRightForBracketingBlockEnd(0, offset + 0, &l)); | |
465 EXPECT_EQ(offset + 4, l); | |
466 EXPECT_TRUE(test_shadow.ScanRightForBracketingBlockEnd(0, offset + 1, &l)); | |
467 EXPECT_EQ(offset + 3, l); | |
468 EXPECT_TRUE(test_shadow.ScanRightForBracketingBlockEnd(0, offset + 2, &l)); | |
469 EXPECT_EQ(offset + 3, l); | |
470 EXPECT_TRUE(test_shadow.ScanRightForBracketingBlockEnd(0, offset + 3, &l)); | |
471 EXPECT_EQ(offset + 3, l); | |
472 EXPECT_TRUE(test_shadow.ScanRightForBracketingBlockEnd(0, offset + 4, &l)); | |
473 EXPECT_EQ(offset + 4, l); | |
474 | |
475 EXPECT_FALSE(test_shadow.ScanRightForBracketingBlockEnd(1, offset + 0, &l)); | |
476 EXPECT_TRUE(test_shadow.ScanRightForBracketingBlockEnd(1, offset + 1, &l)); | |
477 EXPECT_EQ(offset + 4, l); | |
478 EXPECT_TRUE(test_shadow.ScanRightForBracketingBlockEnd(1, offset + 2, &l)); | |
479 EXPECT_EQ(offset + 4, l); | |
480 EXPECT_TRUE(test_shadow.ScanRightForBracketingBlockEnd(1, offset + 3, &l)); | |
481 EXPECT_EQ(offset + 4, l); | |
482 EXPECT_FALSE(test_shadow.ScanRightForBracketingBlockEnd(1, offset + 4, &l)); | |
483 | |
484 EXPECT_FALSE(test_shadow.ScanRightForBracketingBlockEnd(2, offset + 0, &l)); | |
485 EXPECT_FALSE(test_shadow.ScanRightForBracketingBlockEnd(2, offset + 1, &l)); | |
486 EXPECT_FALSE(test_shadow.ScanRightForBracketingBlockEnd(2, offset + 2, &l)); | |
487 EXPECT_FALSE(test_shadow.ScanRightForBracketingBlockEnd(2, offset + 3, &l)); | |
488 EXPECT_FALSE(test_shadow.ScanRightForBracketingBlockEnd(2, offset + 4, &l)); | |
489 | 449 |
490 ::memset(test_shadow.shadow_ + offset, 0, 5); | 450 ::memset(test_shadow.shadow_ + offset, 0, 5); |
491 } | 451 } |
492 | 452 |
493 TEST_F(ShadowTest, ScanRightPerfTest) { | 453 TEST_F(ShadowTest, ScanRightPerfTest) { |
494 size_t offset = test_shadow.length() / 2; | 454 size_t offset = test_shadow.length() / 2; |
495 size_t length = 1 * 1024 * 1024; | 455 size_t length = 1 * 1024 * 1024; |
496 | 456 |
497 ::memset(test_shadow.shadow_ + offset, 0, length); | 457 ::memset(test_shadow.shadow_ + offset, 0, length); |
498 | 458 |
499 test_shadow.shadow_[offset + 0] = kHeapBlockStartMarker0; | 459 test_shadow.shadow_[offset + 0] = kHeapBlockStartMarker0; |
500 // A nested block with freed contents. | |
501 test_shadow.shadow_[offset + 50] = kHeapNestedBlockStartMarker0; | |
502 ::memset(test_shadow.shadow_ + offset + 51, kHeapFreedMarker, 8); | |
503 test_shadow.shadow_[offset + 60] = kHeapNestedBlockEndMarker; | |
504 // A nested block with a nested block. | |
505 test_shadow.shadow_[offset + 100000] = kHeapNestedBlockStartMarker0; | |
506 test_shadow.shadow_[offset + 100100] = kHeapNestedBlockStartMarker0; | |
507 test_shadow.shadow_[offset + 100400] = kHeapNestedBlockEndMarker; | |
508 test_shadow.shadow_[offset + 200000] = kHeapNestedBlockEndMarker; | |
509 // The end of the outer block. | 460 // The end of the outer block. |
510 test_shadow.shadow_[offset + length - 1] = kHeapBlockEndMarker; | 461 test_shadow.shadow_[offset + length - 1] = kHeapBlockEndMarker; |
511 | 462 |
512 uint64_t tnet = 0; | 463 uint64_t tnet = 0; |
513 for (size_t i = 0; i < 100; ++i) { | 464 for (size_t i = 0; i < 100; ++i) { |
514 size_t l = 0; | 465 size_t l = 0; |
515 uint64_t t0 = ::__rdtsc(); | 466 uint64_t t0 = ::__rdtsc(); |
516 test_shadow.ScanRightForBracketingBlockEnd(0, offset + 1, &l); | 467 test_shadow.ScanRightForBracketingBlockEnd(offset + 1, &l); |
517 uint64_t t1 = ::__rdtsc(); | 468 uint64_t t1 = ::__rdtsc(); |
518 tnet += t1 - t0; | 469 tnet += t1 - t0; |
519 } | 470 } |
520 testing::EmitMetric("Syzygy.Asan.Shadow.ScanRightForBracketingBlockEnd", | 471 testing::EmitMetric("Syzygy.Asan.Shadow.ScanRightForBracketingBlockEnd", |
521 tnet); | 472 tnet); |
522 | 473 |
523 // Reset the shadow memory. | 474 // Reset the shadow memory. |
524 ::memset(test_shadow.shadow_ + offset, 0, length); | 475 ::memset(test_shadow.shadow_ + offset, 0, length); |
525 } | 476 } |
526 | 477 |
527 TEST_F(ShadowTest, IsLeftOrRightRedzone) { | 478 TEST_F(ShadowTest, IsLeftOrRightRedzone) { |
528 BlockLayout layout = {}; | 479 BlockLayout layout = {}; |
529 const size_t kAllocSize = 15; | 480 const size_t kAllocSize = 15; |
530 ASSERT_NE(0U, kAllocSize % kShadowRatio); | 481 ASSERT_NE(0U, kAllocSize % kShadowRatio); |
531 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, kAllocSize, 0, 0, | 482 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, kAllocSize, 0, 0, |
532 &layout)); | 483 &layout)); |
533 | 484 |
534 std::unique_ptr<uint8_t[]> data(new uint8_t[layout.block_size]); | 485 std::unique_ptr<uint8_t[]> data(new uint8_t[layout.block_size]); |
535 BlockInfo info = {}; | 486 BlockInfo info = {}; |
536 BlockInitialize(layout, data.get(), false, &info); | 487 BlockInitialize(layout, data.get(), &info); |
537 | 488 |
538 test_shadow.PoisonAllocatedBlock(info); | 489 test_shadow.PoisonAllocatedBlock(info); |
539 uint8_t* block = reinterpret_cast<uint8_t*>(info.header); | 490 uint8_t* block = reinterpret_cast<uint8_t*>(info.header); |
540 uint8_t* cursor = block; | 491 uint8_t* cursor = block; |
541 | 492 |
542 for (; cursor < info.RawBody(); ++cursor) { | 493 for (; cursor < info.RawBody(); ++cursor) { |
543 EXPECT_TRUE(test_shadow.IsLeftRedzone(cursor)); | 494 EXPECT_TRUE(test_shadow.IsLeftRedzone(cursor)); |
544 EXPECT_FALSE(test_shadow.IsRightRedzone(cursor)); | 495 EXPECT_FALSE(test_shadow.IsRightRedzone(cursor)); |
545 } | 496 } |
546 for (; cursor < info.RawBody() + info.body_size; ++cursor) { | 497 for (; cursor < info.RawBody() + info.body_size; ++cursor) { |
547 EXPECT_FALSE(test_shadow.IsLeftRedzone(cursor)); | 498 EXPECT_FALSE(test_shadow.IsLeftRedzone(cursor)); |
548 EXPECT_FALSE(test_shadow.IsRightRedzone(cursor)); | 499 EXPECT_FALSE(test_shadow.IsRightRedzone(cursor)); |
549 } | 500 } |
550 for (; cursor < block + info.block_size; ++cursor) { | 501 for (; cursor < block + info.block_size; ++cursor) { |
551 EXPECT_FALSE(test_shadow.IsLeftRedzone(cursor)); | 502 EXPECT_FALSE(test_shadow.IsLeftRedzone(cursor)); |
552 EXPECT_TRUE(test_shadow.IsRightRedzone(cursor)); | 503 EXPECT_TRUE(test_shadow.IsRightRedzone(cursor)); |
553 } | 504 } |
554 | 505 |
555 test_shadow.Unpoison(block, info.block_size); | 506 test_shadow.Unpoison(block, info.block_size); |
556 } | 507 } |
557 | 508 |
558 namespace { | 509 namespace { |
559 | 510 |
560 void TestBlockInfoFromShadow(Shadow* shadow, | 511 void TestBlockInfoFromShadow(Shadow* shadow, const BlockLayout& outer) { |
Sigurður Ásgeirsson
2016/11/22 19:15:37
nit: rename outer to something more descriptive?
Sébastien Marchand
2016/11/22 22:12:23
Done.
| |
561 const BlockLayout& outer, | |
562 const BlockLayout& nested) { | |
563 ASSERT_TRUE(shadow != nullptr); | 512 ASSERT_TRUE(shadow != nullptr); |
564 ASSERT_LE(nested.block_size, outer.body_size); | |
565 | 513 |
566 uint8_t* data = new uint8_t[outer.block_size]; | 514 uint8_t* data = new uint8_t[outer.block_size]; |
567 | 515 |
568 // Try recovering the block from every position within it when no nested | |
569 // block exists. Expect finding a nested block to fail. | |
570 BlockInfo info = {}; | 516 BlockInfo info = {}; |
571 BlockInitialize(outer, data, false, &info); | 517 BlockInitialize(outer, data, &info); |
572 shadow->PoisonAllocatedBlock(info); | 518 shadow->PoisonAllocatedBlock(info); |
573 BlockInfo info_recovered = {}; | 519 BlockInfo info_recovered = {}; |
574 for (size_t i = 0; i < info.block_size; ++i) { | 520 for (size_t i = 0; i < info.block_size; ++i) { |
575 EXPECT_TRUE(shadow->BlockInfoFromShadow( | 521 EXPECT_TRUE(shadow->BlockInfoFromShadow( |
576 info.RawBlock() + i, &info_recovered)); | 522 info.RawBlock() + i, &info_recovered)); |
577 EXPECT_EQ(0, ::memcmp(&info, &info_recovered, sizeof(info))); | 523 EXPECT_EQ(0, ::memcmp(&info, &info_recovered, sizeof(info))); |
578 | |
579 // This block should have no parent block as its not nested. | |
580 EXPECT_FALSE(shadow->ParentBlockInfoFromShadow( | |
581 info, &info_recovered)); | |
582 } | 524 } |
583 | 525 |
584 // Place a nested block and try the recovery from every position again. | |
585 size_t padding = ::common::AlignDown(info.body_size - nested.block_size, | |
586 kShadowRatio * 2); | |
587 uint8_t* nested_begin = info.RawBody() + padding / 2; | |
588 uint8_t* nested_end = nested_begin + nested.block_size; | |
589 BlockInfo nested_info = {}; | |
590 BlockInitialize(nested, nested_begin, true, &nested_info); | |
591 nested_info.header->is_nested = true; | |
592 shadow->PoisonAllocatedBlock(nested_info); | |
593 for (size_t i = 0; i < info.block_size; ++i) { | |
594 uint8_t* pos = info.RawBlock() + i; | |
595 EXPECT_TRUE(shadow->BlockInfoFromShadow(pos, &info_recovered)); | |
596 | |
597 BlockInfo parent_info = {}; | |
598 bool found_parent = shadow->ParentBlockInfoFromShadow( | |
599 info_recovered, &parent_info); | |
600 | |
601 if (pos >= nested_begin && pos < nested_end) { | |
602 EXPECT_EQ(0, ::memcmp(&nested_info, &info_recovered, | |
603 sizeof(nested_info))); | |
604 EXPECT_TRUE(found_parent); | |
605 EXPECT_EQ(0, ::memcmp(&info, &parent_info, sizeof(info))); | |
606 } else { | |
607 EXPECT_EQ(0, ::memcmp(&info, &info_recovered, sizeof(info))); | |
608 EXPECT_FALSE(found_parent); | |
609 } | |
610 } | |
611 shadow->Unpoison(info.header, info.block_size); | |
612 | |
613 delete [] data; | 526 delete [] data; |
614 } | 527 } |
615 | 528 |
616 } // namespace | 529 } // namespace |
617 | 530 |
618 TEST_F(ShadowTest, BlockInfoFromShadow) { | 531 TEST_F(ShadowTest, BlockInfoFromShadow) { |
619 // This is a simple layout that will be nested inside of another block. | |
620 BlockLayout layout0 = {}; | 532 BlockLayout layout0 = {}; |
621 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, 6, 0, 0, &layout0)); | 533 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, 6, 0, 0, &layout0)); |
622 | 534 |
623 // Plan two layouts, one with padding and another with none. The first has | 535 uint8_t* data = new uint8_t[layout0.block_size]; |
624 // exactly enough space for the nested block, while the second has room to | |
625 // spare. | |
626 BlockLayout layout1 = {}; | |
627 BlockLayout layout2 = {}; | |
628 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, | |
629 static_cast<uint32_t>( | |
630 ::common::AlignUp(layout0.block_size, kShadowRatio) + 4), 0, 0, | |
631 &layout1)); | |
632 ASSERT_EQ(0u, layout1.header_padding_size); | |
633 ASSERT_EQ(0u, layout1.trailer_padding_size); | |
634 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, | |
635 layout0.block_size + 2 * kShadowRatio, 32, 13, &layout2)); | |
636 ASSERT_LT(0u, layout2.header_padding_size); | |
637 ASSERT_LT(0u, layout2.trailer_padding_size); | |
638 | 536 |
639 EXPECT_NO_FATAL_FAILURE(TestBlockInfoFromShadow( | 537 BlockInfo info = {}; |
640 &test_shadow, layout1, layout0)); | 538 BlockInitialize(layout0, data, &info); |
641 EXPECT_NO_FATAL_FAILURE(TestBlockInfoFromShadow( | 539 test_shadow.PoisonAllocatedBlock(info); |
642 &test_shadow, layout2, layout0)); | 540 BlockInfo info_recovered = {}; |
541 for (size_t i = 0; i < info.block_size; ++i) { | |
542 EXPECT_TRUE( | |
543 test_shadow.BlockInfoFromShadow(info.RawBlock() + i, &info_recovered)); | |
544 EXPECT_EQ(0, ::memcmp(&info, &info_recovered, sizeof(info))); | |
545 } | |
546 delete[] data; | |
643 } | 547 } |
644 | 548 |
645 TEST_F(ShadowTest, IsBeginningOfBlockBody) { | 549 TEST_F(ShadowTest, IsBeginningOfBlockBody) { |
646 BlockLayout l = {}; | 550 BlockLayout l = {}; |
647 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, 7, 0, 0, &l)); | 551 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, 7, 0, 0, &l)); |
648 | 552 |
649 size_t data_size = l.block_size; | 553 size_t data_size = l.block_size; |
650 std::unique_ptr<uint8_t[]> data(new uint8_t[data_size]); | 554 std::unique_ptr<uint8_t[]> data(new uint8_t[data_size]); |
651 | 555 |
652 BlockInfo block_info = {}; | 556 BlockInfo block_info = {}; |
653 BlockInitialize(l, data.get(), false, &block_info); | 557 BlockInitialize(l, data.get(), &block_info); |
654 | 558 |
655 test_shadow.PoisonAllocatedBlock(block_info); | 559 test_shadow.PoisonAllocatedBlock(block_info); |
656 | 560 |
657 EXPECT_TRUE(test_shadow.IsBeginningOfBlockBody(block_info.body)); | 561 EXPECT_TRUE(test_shadow.IsBeginningOfBlockBody(block_info.body)); |
658 EXPECT_FALSE(test_shadow.IsBeginningOfBlockBody(data.get())); | 562 EXPECT_FALSE(test_shadow.IsBeginningOfBlockBody(data.get())); |
659 | 563 |
660 block_info.header->state = QUARANTINED_BLOCK; | 564 block_info.header->state = QUARANTINED_BLOCK; |
661 test_shadow.MarkAsFreed(block_info.body, block_info.body_size); | 565 test_shadow.MarkAsFreed(block_info.body, block_info.body_size); |
662 | 566 |
663 EXPECT_TRUE(test_shadow.IsBeginningOfBlockBody(block_info.body)); | 567 EXPECT_TRUE(test_shadow.IsBeginningOfBlockBody(block_info.body)); |
664 EXPECT_FALSE(test_shadow.IsBeginningOfBlockBody(data.get())); | 568 EXPECT_FALSE(test_shadow.IsBeginningOfBlockBody(data.get())); |
665 | 569 |
666 test_shadow.Unpoison(data.get(), data_size); | 570 test_shadow.Unpoison(data.get(), data_size); |
667 } | 571 } |
668 | 572 |
669 TEST_F(ShadowTest, IsBeginningOfBlockBodyForBlockOfSizeZero) { | 573 TEST_F(ShadowTest, IsBeginningOfBlockBodyForBlockOfSizeZero) { |
670 BlockLayout l = {}; | 574 BlockLayout l = {}; |
671 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, 0, 0, 0, &l)); | 575 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, 0, 0, 0, &l)); |
672 | 576 |
673 size_t data_size = l.block_size; | 577 size_t data_size = l.block_size; |
674 std::unique_ptr<uint8_t[]> data(new uint8_t[data_size]); | 578 std::unique_ptr<uint8_t[]> data(new uint8_t[data_size]); |
675 | 579 |
676 BlockInfo block_info = {}; | 580 BlockInfo block_info = {}; |
677 BlockInitialize(l, data.get(), false, &block_info); | 581 BlockInitialize(l, data.get(), &block_info); |
678 | 582 |
679 test_shadow.PoisonAllocatedBlock(block_info); | 583 test_shadow.PoisonAllocatedBlock(block_info); |
680 | 584 |
681 EXPECT_TRUE(test_shadow.IsBeginningOfBlockBody(block_info.body)); | 585 EXPECT_TRUE(test_shadow.IsBeginningOfBlockBody(block_info.body)); |
682 EXPECT_FALSE(test_shadow.IsBeginningOfBlockBody(data.get())); | 586 EXPECT_FALSE(test_shadow.IsBeginningOfBlockBody(data.get())); |
683 | 587 |
684 block_info.header->state = QUARANTINED_FLOODED_BLOCK; | 588 block_info.header->state = QUARANTINED_FLOODED_BLOCK; |
685 test_shadow.MarkAsFreed(block_info.body, block_info.body_size); | 589 test_shadow.MarkAsFreed(block_info.body, block_info.body_size); |
686 | 590 |
687 EXPECT_TRUE(test_shadow.IsBeginningOfBlockBody(block_info.body)); | 591 EXPECT_TRUE(test_shadow.IsBeginningOfBlockBody(block_info.body)); |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
751 | 655 |
752 // A fixture for shadow walker tests. | 656 // A fixture for shadow walker tests. |
753 class ShadowWalkerTest : public testing::Test { | 657 class ShadowWalkerTest : public testing::Test { |
754 public: | 658 public: |
755 TestShadow test_shadow; | 659 TestShadow test_shadow; |
756 }; | 660 }; |
757 | 661 |
758 } // namespace | 662 } // namespace |
759 | 663 |
760 TEST_F(ShadowWalkerTest, WalkEmptyRange) { | 664 TEST_F(ShadowWalkerTest, WalkEmptyRange) { |
761 ShadowWalker w(&test_shadow, true, &test_shadow, &test_shadow); | 665 ShadowWalker w(&test_shadow, &test_shadow, &test_shadow); |
762 BlockInfo i = {}; | 666 BlockInfo i = {}; |
763 EXPECT_FALSE(w.Next(&i)); | 667 EXPECT_FALSE(w.Next(&i)); |
764 } | 668 } |
765 | 669 |
766 TEST_F(ShadowWalkerTest, WalkRangeAtEndOfAddressSpace) { | 670 TEST_F(ShadowWalkerTest, WalkRangeAtEndOfAddressSpace) { |
767 TestShadow ts1(4, 30); // 4GB. | 671 TestShadow ts1(4, 30); // 4GB. |
768 ShadowWalker w( | 672 ShadowWalker w(&ts1, reinterpret_cast<const void*>(ts1.memory_size() - 100), |
769 &ts1, true, | 673 reinterpret_cast<const void*>(ts1.memory_size())); |
770 reinterpret_cast<const void*>(ts1.memory_size() - 100), | |
771 reinterpret_cast<const void*>(ts1.memory_size())); | |
772 BlockInfo i = {}; | 674 BlockInfo i = {}; |
773 EXPECT_FALSE(w.Next(&i)); | 675 EXPECT_FALSE(w.Next(&i)); |
774 } | 676 } |
775 | 677 |
776 TEST_F(ShadowWalkerTest, WalksNonNestedBlocks) { | 678 TEST_F(ShadowWalkerTest, WalksBlocks) { |
777 BlockLayout l = {}; | 679 BlockLayout l = {}; |
778 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, 7, 0, 0, &l)); | 680 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, 7, 0, 0, &l)); |
779 | 681 |
780 size_t data_size = l.block_size * 3 + kShadowRatio; | 682 size_t data_size = l.block_size * 3 + kShadowRatio; |
781 uint8_t* data = new uint8_t[data_size]; | 683 uint8_t* data = new uint8_t[data_size]; |
782 uint8_t* data0 = data; | 684 uint8_t* data0 = data; |
783 uint8_t* data1 = data0 + l.block_size + kShadowRatio; | 685 uint8_t* data1 = data0 + l.block_size + kShadowRatio; |
784 uint8_t* data2 = data1 + l.block_size; | 686 uint8_t* data2 = data1 + l.block_size; |
785 | 687 |
786 BlockInfo i0 = {}, i1 = {}, i2 = {}; | 688 BlockInfo i0 = {}, i1 = {}, i2 = {}; |
787 BlockInitialize(l, data0, false, &i0); | 689 BlockInitialize(l, data0, &i0); |
788 BlockInitialize(l, data1, false, &i1); | 690 BlockInitialize(l, data1, &i1); |
789 BlockInitialize(l, data2, false, &i2); | 691 BlockInitialize(l, data2, &i2); |
790 | 692 |
791 test_shadow.PoisonAllocatedBlock(i0); | 693 test_shadow.PoisonAllocatedBlock(i0); |
792 test_shadow.PoisonAllocatedBlock(i1); | 694 test_shadow.PoisonAllocatedBlock(i1); |
793 test_shadow.PoisonAllocatedBlock(i2); | 695 test_shadow.PoisonAllocatedBlock(i2); |
794 | 696 |
795 i2.header->state = QUARANTINED_BLOCK; | 697 i2.header->state = QUARANTINED_BLOCK; |
796 test_shadow.MarkAsFreed(i2.body, i2.body_size); | 698 test_shadow.MarkAsFreed(i2.body, i2.body_size); |
797 | 699 |
798 // Do a non-recursive walk through the shadow. | 700 // Do a non-recursive walk through the shadow. |
799 BlockInfo i = {}; | 701 BlockInfo i = {}; |
800 ShadowWalker w0(&test_shadow, false, data, data + data_size); | 702 ShadowWalker w0(&test_shadow, data, data + data_size); |
801 EXPECT_EQ(-1, w0.nesting_depth()); | |
802 EXPECT_TRUE(w0.Next(&i)); | 703 EXPECT_TRUE(w0.Next(&i)); |
803 EXPECT_EQ(0, w0.nesting_depth()); | |
804 EXPECT_TRUE(w0.Next(&i)); | 704 EXPECT_TRUE(w0.Next(&i)); |
805 EXPECT_EQ(0, w0.nesting_depth()); | |
806 EXPECT_TRUE(w0.Next(&i)); | 705 EXPECT_TRUE(w0.Next(&i)); |
807 EXPECT_EQ(0, w0.nesting_depth()); | |
808 EXPECT_FALSE(w0.Next(&i)); | 706 EXPECT_FALSE(w0.Next(&i)); |
809 EXPECT_EQ(-1, w0.nesting_depth()); | |
810 | |
811 // Walk recursively through the shadow and expect the same results. | |
812 ShadowWalker w1(&test_shadow, true, data, data + data_size); | |
813 EXPECT_EQ(-1, w1.nesting_depth()); | |
814 EXPECT_TRUE(w1.Next(&i)); | |
815 EXPECT_EQ(0, w1.nesting_depth()); | |
816 EXPECT_EQ(0, ::memcmp(&i, &i0, sizeof(i))); | |
817 EXPECT_TRUE(w1.Next(&i)); | |
818 EXPECT_EQ(0, w1.nesting_depth()); | |
819 EXPECT_EQ(0, ::memcmp(&i, &i1, sizeof(i))); | |
820 EXPECT_TRUE(w1.Next(&i)); | |
821 EXPECT_EQ(0, w1.nesting_depth()); | |
822 EXPECT_EQ(0, ::memcmp(&i, &i2, sizeof(i))); | |
823 EXPECT_FALSE(w1.Next(&i)); | |
824 EXPECT_EQ(-1, w1.nesting_depth()); | |
825 | 707 |
826 test_shadow.Unpoison(data, data_size); | 708 test_shadow.Unpoison(data, data_size); |
827 delete [] data; | 709 delete [] data; |
828 } | |
829 | |
830 TEST_F(ShadowWalkerTest, WalksNestedBlocks) { | |
831 BlockLayout b0 = {}, b1 = {}, b2 = {}, b00 = {}, b01 = {}, b10 = {}, | |
832 b100 = {}; | |
833 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, 15, 30, 30, &b00)); | |
834 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, 7, 0, 0, &b01)); | |
835 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, | |
836 b00.block_size + b01.block_size + kShadowRatio, 0, 0, &b0)); | |
837 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, 7, 0, 0, &b100)); | |
838 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, b100.block_size, 0, 0, | |
839 &b10)); | |
840 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, b10.block_size, 0, 0, | |
841 &b1)); | |
842 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, 100, 0, 0, &b2)); | |
843 | |
844 size_t data_size = b0.block_size + b1.block_size + kShadowRatio + | |
845 b2.block_size; | |
846 uint8_t* data = new uint8_t[data_size]; | |
847 | |
848 // Initialize the depth 0 blocks. | |
849 uint8_t* d0 = data; | |
850 uint8_t* d1 = d0 + b0.block_size; | |
851 uint8_t* d2 = d1 + b1.block_size + kShadowRatio; | |
852 BlockInfo i0 = {}, i1 = {}, i2 = {}; | |
853 BlockInitialize(b0, d0, false, &i0); | |
854 BlockInitialize(b1, d1, false, &i1); | |
855 BlockInitialize(b2, d2, false, &i2); | |
856 test_shadow.PoisonAllocatedBlock(i0); | |
857 test_shadow.PoisonAllocatedBlock(i1); | |
858 test_shadow.PoisonAllocatedBlock(i2); | |
859 | |
860 // Initialize depth 1 blocks. | |
861 uint8_t* d00 = i0.RawBody(); | |
862 uint8_t* d01 = d00 + b00.block_size + kShadowRatio; | |
863 uint8_t* d10 = i1.RawBody(); | |
864 BlockInfo i00 = {}, i01 = {}, i10 = {}; | |
865 BlockInitialize(b00, d00, true, &i00); | |
866 BlockInitialize(b01, d01, true, &i01); | |
867 BlockInitialize(b10, d10, true, &i10); | |
868 test_shadow.PoisonAllocatedBlock(i00); | |
869 test_shadow.PoisonAllocatedBlock(i01); | |
870 test_shadow.PoisonAllocatedBlock(i10); | |
871 | |
872 // Initialize depth 2 blocks. | |
873 uint8_t* d100 = i10.RawBody(); | |
874 BlockInfo i100 = {}; | |
875 BlockInitialize(b100, d100, true, &i100); | |
876 test_shadow.PoisonAllocatedBlock(i100); | |
877 i100.header->state = QUARANTINED_FLOODED_BLOCK; | |
878 test_shadow.MarkAsFreed(i100.body, i100.body_size); | |
879 | |
880 // Do a non-recursive walk through the shadow. | |
881 BlockInfo i = {}; | |
882 ShadowWalker w0(&test_shadow, false, data, data + data_size); | |
883 EXPECT_EQ(-1, w0.nesting_depth()); | |
884 EXPECT_TRUE(w0.Next(&i)); | |
885 EXPECT_EQ(0, w0.nesting_depth()); | |
886 EXPECT_EQ(0, ::memcmp(&i, &i0, sizeof(i))); | |
887 EXPECT_TRUE(w0.Next(&i)); | |
888 EXPECT_EQ(0, w0.nesting_depth()); | |
889 EXPECT_EQ(0, ::memcmp(&i, &i1, sizeof(i))); | |
890 EXPECT_TRUE(w0.Next(&i)); | |
891 EXPECT_EQ(0, w0.nesting_depth()); | |
892 EXPECT_EQ(0, ::memcmp(&i, &i2, sizeof(i))); | |
893 EXPECT_FALSE(w0.Next(&i)); | |
894 EXPECT_EQ(-1, w0.nesting_depth()); | |
895 | |
896 // Walk recursively through the shadow. | |
897 ShadowWalker w1(&test_shadow, true, data, data + data_size); | |
898 EXPECT_EQ(-1, w1.nesting_depth()); | |
899 EXPECT_TRUE(w1.Next(&i)); | |
900 EXPECT_EQ(0, w1.nesting_depth()); | |
901 EXPECT_EQ(0, ::memcmp(&i, &i0, sizeof(i))); | |
902 EXPECT_TRUE(w1.Next(&i)); | |
903 EXPECT_EQ(1, w1.nesting_depth()); | |
904 EXPECT_EQ(0, ::memcmp(&i, &i00, sizeof(i))); | |
905 EXPECT_TRUE(w1.Next(&i)); | |
906 EXPECT_EQ(1, w1.nesting_depth()); | |
907 EXPECT_EQ(0, ::memcmp(&i, &i01, sizeof(i))); | |
908 EXPECT_TRUE(w1.Next(&i)); | |
909 EXPECT_EQ(0, w1.nesting_depth()); | |
910 EXPECT_EQ(0, ::memcmp(&i, &i1, sizeof(i))); | |
911 EXPECT_TRUE(w1.Next(&i)); | |
912 EXPECT_EQ(1, w1.nesting_depth()); | |
913 EXPECT_EQ(0, ::memcmp(&i, &i10, sizeof(i))); | |
914 EXPECT_TRUE(w1.Next(&i)); | |
915 EXPECT_EQ(2, w1.nesting_depth()); | |
916 EXPECT_EQ(0, ::memcmp(&i, &i100, sizeof(i))); | |
917 EXPECT_TRUE(w1.Next(&i)); | |
918 EXPECT_EQ(0, w1.nesting_depth()); | |
919 EXPECT_EQ(0, ::memcmp(&i, &i2, sizeof(i))); | |
920 EXPECT_FALSE(w1.Next(&i)); | |
921 EXPECT_EQ(-1, w1.nesting_depth()); | |
922 | |
923 test_shadow.Unpoison(data, data_size); | |
924 delete [] data; | |
925 } | 710 } |
926 | 711 |
927 TEST_F(ShadowWalkerTest, WalkShadowWithUncommittedRanges) { | 712 TEST_F(ShadowWalkerTest, WalkShadowWithUncommittedRanges) { |
928 // Create a 512k memory block. | 713 // Create a 512k memory block. |
929 const size_t kMemorySize = 512 * 1024; | 714 const size_t kMemorySize = 512 * 1024; |
930 uint8_t memory_block[kMemorySize]; | 715 uint8_t memory_block[kMemorySize]; |
931 const size_t shadow_size = Shadow::RequiredLength(); | 716 const size_t shadow_size = Shadow::RequiredLength(); |
932 | 717 |
933 // Allocate the shadow memory, only reserve the memory. | 718 // Allocate the shadow memory, only reserve the memory. |
934 uint8_t* shadow_memory = static_cast<uint8_t*>( | 719 uint8_t* shadow_memory = static_cast<uint8_t*>( |
(...skipping 25 matching lines...) Expand all Loading... | |
960 ::common::AlignDown(shadow_address, GetPageSize()); | 745 ::common::AlignDown(shadow_address, GetPageSize()); |
961 // Commit the shadow memory for this block. | 746 // Commit the shadow memory for this block. |
962 EXPECT_EQ(static_cast<void*>(shadow_address_page_begin), | 747 EXPECT_EQ(static_cast<void*>(shadow_address_page_begin), |
963 ::VirtualAlloc(shadow_address, GetPageSize(), MEM_COMMIT, | 748 ::VirtualAlloc(shadow_address, GetPageSize(), MEM_COMMIT, |
964 PAGE_READWRITE)); | 749 PAGE_READWRITE)); |
965 | 750 |
966 // Address of the memory for this block. | 751 // Address of the memory for this block. |
967 uint8_t* page_address = ::common::AlignUp( | 752 uint8_t* page_address = ::common::AlignUp( |
968 memory_block + i * GetPageSize() * kShadowRatio, kShadowRatio); | 753 memory_block + i * GetPageSize() * kShadowRatio, kShadowRatio); |
969 BlockInfo block_info = {}; | 754 BlockInfo block_info = {}; |
970 BlockInitialize(l, page_address, false, &block_info); | 755 BlockInitialize(l, page_address, &block_info); |
971 block_info_vec.push_back(block_info); | 756 block_info_vec.push_back(block_info); |
972 | 757 |
973 // Poison the block. | 758 // Poison the block. |
974 ts1.PoisonAllocatedBlock(block_info); | 759 ts1.PoisonAllocatedBlock(block_info); |
975 } | 760 } |
976 | 761 |
977 size_t block_count = 0; | 762 size_t block_count = 0; |
978 ShadowWalker w(&ts1, true, memory_block, memory_block + kMemorySize); | 763 ShadowWalker w(&ts1, memory_block, memory_block + kMemorySize); |
979 BlockInfo i = {}; | 764 BlockInfo i = {}; |
980 while (w.Next(&i)) { | 765 while (w.Next(&i)) { |
981 EXPECT_LT(block_count, block_info_vec.size()); | 766 EXPECT_LT(block_count, block_info_vec.size()); |
982 EXPECT_EQ(block_info_vec[block_count].header, i.header); | 767 EXPECT_EQ(block_info_vec[block_count].header, i.header); |
983 EXPECT_EQ(block_info_vec[block_count].body, i.body); | 768 EXPECT_EQ(block_info_vec[block_count].body, i.body); |
984 EXPECT_EQ(block_info_vec[block_count].trailer, i.trailer); | 769 EXPECT_EQ(block_info_vec[block_count].trailer, i.trailer); |
985 block_count++; | 770 block_count++; |
986 } | 771 } |
987 EXPECT_EQ(block_info_vec.size(), block_count); | 772 EXPECT_EQ(block_info_vec.size(), block_count); |
988 EXPECT_FALSE(w.Next(&i)); | 773 EXPECT_FALSE(w.Next(&i)); |
989 | 774 |
990 EXPECT_GT(::VirtualFree(shadow_memory, 0, MEM_RELEASE), 0U); | 775 EXPECT_GT(::VirtualFree(shadow_memory, 0, MEM_RELEASE), 0U); |
991 } | 776 } |
992 | 777 |
993 } // namespace asan | 778 } // namespace asan |
994 } // namespace agent | 779 } // namespace agent |
OLD | NEW |