Index: lib/sanitizer_common/tests/sanitizer_allocator_test.cc =================================================================== --- lib/sanitizer_common/tests/sanitizer_allocator_test.cc +++ lib/sanitizer_common/tests/sanitizer_allocator_test.cc @@ -13,6 +13,7 @@ #include "sanitizer_common/sanitizer_allocator.h" #include "sanitizer_common/sanitizer_allocator_internal.h" #include "sanitizer_common/sanitizer_common.h" +#include "sanitizer_common/sanitizer_remote_address_space_view.h" #include "sanitizer_test_utils.h" #include "sanitizer_pthread_wrappers.h" @@ -612,6 +613,8 @@ typedef CombinedAllocator Allocator; + using AllocatorRemoteView = + typename Allocator::template ThisTASVT; Allocator *a = new Allocator; a->Init(kReleaseToOSIntervalNever); std::mt19937 r; @@ -646,7 +649,9 @@ // Test ForEachChunk(...) { + a->ForceLock(); std::set reported_chunks; + std::set reported_chunks_remote_view; auto cb = [](uptr chunk, void *arg) { auto reported_chunks_ptr = reinterpret_cast *>(arg); auto pair = @@ -655,9 +660,31 @@ ASSERT_TRUE(pair.second); }; a->ForEachChunk(cb, reinterpret_cast(&reported_chunks)); + + // Test the RemoteAddressSpaceView functionality of the allocator. + { + // Create in-process VMReadContext object. + RemoteAddressSpaceView::ScopedContext remote_view_context; + + // Make a copy of the allocator instantiated with + // `RemoteAddressSpaceView`. + AllocatorRemoteView *a_remote_view = new AllocatorRemoteView; + Allocator::CopyFromTarget(a_remote_view, a); + + // Now try to enumerate the chunks again but this time using the + // `RemoteAddressSpaceView` implementation. + a_remote_view->ForEachChunk( + cb, reinterpret_cast(&reported_chunks_remote_view)); + + delete a_remote_view; + } + for (const auto &allocated_ptr : allocated) { ASSERT_NE(reported_chunks.find(allocated_ptr), reported_chunks.end()); + ASSERT_NE(reported_chunks_remote_view.find(allocated_ptr), + reported_chunks_remote_view.end()); } + a->ForceUnlock(); } for (uptr i = 0; i < kNumAllocs; i++) { @@ -893,6 +920,8 @@ template void TestSizeClassAllocatorIteration() { + using AllocatorRemoteView = + typename Allocator::template ThisTASVT; Allocator *a = new Allocator; a->Init(kReleaseToOSIntervalNever); SizeClassAllocatorLocalCache cache; @@ -919,15 +948,35 @@ } std::set reported_chunks; + std::set reported_chunks_remote_view; a->ForceLock(); a->ForEachChunk(IterationTestCallback, &reported_chunks); - a->ForceUnlock(); + // Test the RemoteAddressSpaceView functionality of the allocator. + { + // Create in-process VMReadContext object. + RemoteAddressSpaceView::ScopedContext remote_view_context; + + // Make a copy of the allocator instantiated with + // `RemoteAddressSpaceView`. + AllocatorRemoteView *a_remote_view = new AllocatorRemoteView; + Allocator::CopyFromTarget(a_remote_view, a); + + // Now try to enumerate the chunks again but this time using the + // `RemoteAddressSpaceView` implementation. + a_remote_view->ForEachChunk(IterationTestCallback, + &reported_chunks_remote_view); + delete a_remote_view; + } for (uptr i = 0; i < allocated.size(); i++) { // Don't use EXPECT_NE. Reporting the first mismatch is enough. ASSERT_NE(reported_chunks.find(reinterpret_cast(allocated[i])), reported_chunks.end()); + ASSERT_NE( + reported_chunks_remote_view.find(reinterpret_cast(allocated[i])), + reported_chunks_remote_view.end()); } + a->ForceUnlock(); a->TestOnlyUnmap(); delete a; @@ -952,6 +1001,8 @@ TEST(SanitizerCommon, LargeMmapAllocatorIteration) { LargeMmapAllocator a; + using AllocatorRemoteView = + typename decltype(a)::template ThisTASVT; a.Init(); AllocatorStats stats; stats.Init(); @@ -964,14 +1015,37 @@ allocated[i] = (char *)a.Allocate(&stats, size, 1); std::set reported_chunks; + std::set reported_chunks_remote_view; a.ForceLock(); a.ForEachChunk(IterationTestCallback, &reported_chunks); a.ForceUnlock(); + // Test the RemoteAddressSpaceView functionality of the allocator. + { + // Create in-process VMReadContext object. + RemoteAddressSpaceView::ScopedContext remote_view_context; + + // Make a copy of the allocator instantiated with + // `RemoteAddressSpaceView`. + AllocatorRemoteView *a_remote_view = new AllocatorRemoteView; + decltype(a)::CopyFromTarget(a_remote_view, &a); + + // Now try to enumerate the chunks again but this time using the + // `RemoteAddressSpaceView` implementation. + a_remote_view->ForEachChunk( + IterationTestCallback, + reinterpret_cast(&reported_chunks_remote_view)); + + delete a_remote_view; + } + for (uptr i = 0; i < kNumAllocs; i++) { // Don't use EXPECT_NE. Reporting the first mismatch is enough. ASSERT_NE(reported_chunks.find(reinterpret_cast(allocated[i])), reported_chunks.end()); + ASSERT_NE( + reported_chunks_remote_view.find(reinterpret_cast(allocated[i])), + reported_chunks_remote_view.end()); } for (uptr i = 0; i < kNumAllocs; i++) a.Deallocate(&stats, allocated[i]);