// Copyright 2022 The Crashpad Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include "snapshot/ios/memory_snapshot_ios_intermediate_dump.h" #include #include #include "gtest/gtest.h" namespace crashpad { namespace test { namespace { using internal::MemorySnapshotIOSIntermediateDump; const vm_address_t kDefaultAddress = 0x1000; class ReadToString : public crashpad::MemorySnapshot::Delegate { public: const std::string& result() { return result_; } private: // MemorySnapshot::Delegate: bool MemorySnapshotDelegateRead(void* data, size_t size) override { result_ = std::string(reinterpret_cast(data), size); return true; } std::string result_; }; std::unique_ptr CreateMemorySnapshot( vm_address_t address, std::vector& data) { auto memory = std::make_unique(); memory->Initialize( address, reinterpret_cast(data.data()), data.size()); return memory; } TEST(MemorySnapshotIOSIntermediateDumpTest, MergeSame) { std::vector data(10, 'a'); auto memory = CreateMemorySnapshot(kDefaultAddress, data); std::unique_ptr merged( memory->MergeWithOtherSnapshot(memory.get())); EXPECT_EQ(merged->Address(), kDefaultAddress); EXPECT_EQ(merged->Size(), data.size()); ReadToString delegate; merged->Read(&delegate); EXPECT_EQ(delegate.result(), "aaaaaaaaaa"); } TEST(MemorySnapshotIOSIntermediateDumpTest, MergeNoOverlap) { std::vector data1(10, 'a'); auto memory1 = CreateMemorySnapshot(kDefaultAddress, data1); std::vector data2(10, 'b'); auto memory2 = CreateMemorySnapshot(kDefaultAddress + 10, data2); std::unique_ptr merged( memory1->MergeWithOtherSnapshot(memory2.get())); EXPECT_EQ(merged->Address(), kDefaultAddress); EXPECT_EQ(merged->Size(), 20u); ReadToString delegate; merged->Read(&delegate); EXPECT_EQ(delegate.result(), "aaaaaaaaaabbbbbbbbbb"); } TEST(MemorySnapshotIOSIntermediateDumpTest, MergePartial) { std::vector data1(10, 'a'); auto memory1 = CreateMemorySnapshot(kDefaultAddress, data1); std::vector data2(10, 'b'); auto memory2 = CreateMemorySnapshot(kDefaultAddress + 5, data2); std::unique_ptr merged( memory1->MergeWithOtherSnapshot(memory2.get())); EXPECT_EQ(merged->Address(), kDefaultAddress); EXPECT_EQ(merged->Size(), 15u); ReadToString delegate; merged->Read(&delegate); EXPECT_EQ(delegate.result(), "aaaaabbbbbbbbbb"); } TEST(MemorySnapshotIOSIntermediateDumpTest, NoMerge) { std::vector data1(10, 'a'); auto memory1 = CreateMemorySnapshot(kDefaultAddress, data1); std::vector data2(10, 'b'); auto memory2 = CreateMemorySnapshot(kDefaultAddress + 20, data2); std::unique_ptr merged( memory1->MergeWithOtherSnapshot(memory2.get())); EXPECT_EQ(merged.get(), nullptr); } TEST(MemorySnapshotIOSIntermediateDumpTest, EnvelopeBiggerFirst) { std::vector data1(30, 'a'); auto memory1 = CreateMemorySnapshot(kDefaultAddress, data1); std::vector data2(10, 'b'); auto memory2 = CreateMemorySnapshot(kDefaultAddress + 15, data2); std::unique_ptr merged( memory1->MergeWithOtherSnapshot(memory2.get())); EXPECT_EQ(merged->Address(), kDefaultAddress); EXPECT_EQ(merged->Size(), data1.size()); ReadToString delegate; merged->Read(&delegate); EXPECT_EQ(delegate.result(), "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); } TEST(MemorySnapshotIOSIntermediateDumpTest, EnvelopeBiggerSecond) { std::vector data1(10, 'a'); auto memory1 = CreateMemorySnapshot(kDefaultAddress, data1); std::vector data2(20, 'b'); auto memory2 = CreateMemorySnapshot(kDefaultAddress, data2); std::unique_ptr merged( memory1->MergeWithOtherSnapshot(memory2.get())); EXPECT_EQ(merged->Address(), kDefaultAddress); EXPECT_EQ(merged->Size(), data2.size()); ReadToString delegate; merged->Read(&delegate); EXPECT_EQ(delegate.result(), "bbbbbbbbbbbbbbbbbbbb"); } TEST(MemorySnapshotIOSIntermediateDumpTest, SmallerAddressSecond) { std::vector data1(10, 'a'); auto memory1 = CreateMemorySnapshot(kDefaultAddress, data1); std::vector data2(20, 'b'); auto memory2 = CreateMemorySnapshot(kDefaultAddress - 10, data2); std::unique_ptr merged( memory1->MergeWithOtherSnapshot(memory2.get())); EXPECT_EQ(merged->Address(), kDefaultAddress - 10); EXPECT_EQ(merged->Size(), data2.size()); ReadToString delegate; merged->Read(&delegate); EXPECT_EQ(delegate.result(), "bbbbbbbbbbbbbbbbbbbb"); } } // namespace } // namespace test } // namespace crashpad