123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- // Copyright 2015 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "base/trace_event/memory_allocator_dump.h"
- #include <stdint.h>
- #include "base/format_macros.h"
- #include "base/trace_event/memory_allocator_dump_guid.h"
- #include "base/trace_event/memory_dump_provider.h"
- #include "base/trace_event/process_memory_dump.h"
- #include "base/trace_event/traced_value.h"
- #include "base/values.h"
- #include "build/build_config.h"
- #include "testing/gmock/include/gmock/gmock.h"
- #include "testing/gtest/include/gtest/gtest.h"
- using testing::ElementsAre;
- using testing::Eq;
- using testing::ByRef;
- using testing::IsEmpty;
- namespace base {
- namespace trace_event {
- namespace {
- class FakeMemoryAllocatorDumpProvider : public MemoryDumpProvider {
- public:
- bool OnMemoryDump(const MemoryDumpArgs& args,
- ProcessMemoryDump* pmd) override {
- MemoryAllocatorDump* root_heap =
- pmd->CreateAllocatorDump("foobar_allocator");
- root_heap->AddScalar(MemoryAllocatorDump::kNameSize,
- MemoryAllocatorDump::kUnitsBytes, 4096);
- root_heap->AddScalar(MemoryAllocatorDump::kNameObjectCount,
- MemoryAllocatorDump::kUnitsObjects, 42);
- root_heap->AddScalar("attr1", "units1", 1234);
- root_heap->AddString("attr2", "units2", "string_value");
- MemoryAllocatorDump* sub_heap =
- pmd->CreateAllocatorDump("foobar_allocator/sub_heap");
- sub_heap->AddScalar(MemoryAllocatorDump::kNameSize,
- MemoryAllocatorDump::kUnitsBytes, 1);
- sub_heap->AddScalar(MemoryAllocatorDump::kNameObjectCount,
- MemoryAllocatorDump::kUnitsObjects, 3);
- pmd->CreateAllocatorDump("foobar_allocator/sub_heap/empty");
- // Leave the rest of sub heap deliberately uninitialized, to check that
- // CreateAllocatorDump returns a properly zero-initialized object.
- return true;
- }
- };
- void CheckString(const MemoryAllocatorDump* dump,
- const std::string& name,
- const char* expected_units,
- const std::string& expected_value) {
- MemoryAllocatorDump::Entry expected(name, expected_units, expected_value);
- EXPECT_THAT(dump->entries(), testing::Contains(Eq(ByRef(expected))));
- }
- void CheckScalar(const MemoryAllocatorDump* dump,
- const std::string& name,
- const char* expected_units,
- uint64_t expected_value) {
- MemoryAllocatorDump::Entry expected(name, expected_units, expected_value);
- EXPECT_THAT(dump->entries(), testing::Contains(Eq(ByRef(expected))));
- }
- } // namespace
- TEST(MemoryAllocatorDumpTest, GuidGeneration) {
- std::unique_ptr<MemoryAllocatorDump> mad(new MemoryAllocatorDump(
- "foo", MemoryDumpLevelOfDetail::FIRST, MemoryAllocatorDumpGuid(0x42u)));
- ASSERT_EQ("42", mad->guid().ToString());
- }
- TEST(MemoryAllocatorDumpTest, DumpIntoProcessMemoryDump) {
- FakeMemoryAllocatorDumpProvider fmadp;
- MemoryDumpArgs dump_args = {MemoryDumpLevelOfDetail::DETAILED};
- ProcessMemoryDump pmd(dump_args);
- fmadp.OnMemoryDump(dump_args, &pmd);
- ASSERT_EQ(3u, pmd.allocator_dumps().size());
- const MemoryAllocatorDump* root_heap =
- pmd.GetAllocatorDump("foobar_allocator");
- ASSERT_NE(nullptr, root_heap);
- EXPECT_EQ("foobar_allocator", root_heap->absolute_name());
- CheckScalar(root_heap, MemoryAllocatorDump::kNameSize,
- MemoryAllocatorDump::kUnitsBytes, 4096);
- CheckScalar(root_heap, MemoryAllocatorDump::kNameObjectCount,
- MemoryAllocatorDump::kUnitsObjects, 42);
- CheckScalar(root_heap, "attr1", "units1", 1234);
- CheckString(root_heap, "attr2", "units2", "string_value");
- const MemoryAllocatorDump* sub_heap =
- pmd.GetAllocatorDump("foobar_allocator/sub_heap");
- ASSERT_NE(nullptr, sub_heap);
- EXPECT_EQ("foobar_allocator/sub_heap", sub_heap->absolute_name());
- CheckScalar(sub_heap, MemoryAllocatorDump::kNameSize,
- MemoryAllocatorDump::kUnitsBytes, 1);
- CheckScalar(sub_heap, MemoryAllocatorDump::kNameObjectCount,
- MemoryAllocatorDump::kUnitsObjects, 3);
- const MemoryAllocatorDump* empty_sub_heap =
- pmd.GetAllocatorDump("foobar_allocator/sub_heap/empty");
- ASSERT_NE(nullptr, empty_sub_heap);
- EXPECT_EQ("foobar_allocator/sub_heap/empty", empty_sub_heap->absolute_name());
- EXPECT_THAT(empty_sub_heap->entries(), IsEmpty());
- // Check that calling serialization routines doesn't cause a crash.
- std::unique_ptr<TracedValue> traced_value(new TracedValue);
- pmd.SerializeAllocatorDumpsInto(traced_value.get());
- }
- TEST(MemoryAllocatorDumpTest, GetSize) {
- MemoryDumpArgs dump_args = {MemoryDumpLevelOfDetail::DETAILED};
- ProcessMemoryDump pmd(dump_args);
- MemoryAllocatorDump* dump = pmd.CreateAllocatorDump("allocator_for_size");
- dump->AddScalar(MemoryAllocatorDump::kNameSize,
- MemoryAllocatorDump::kUnitsBytes, 1);
- dump->AddScalar("foo", MemoryAllocatorDump::kUnitsBytes, 2);
- EXPECT_EQ(1u, dump->GetSizeInternal());
- }
- TEST(MemoryAllocatorDumpTest, ReadValues) {
- MemoryDumpArgs dump_args = {MemoryDumpLevelOfDetail::DETAILED};
- ProcessMemoryDump pmd(dump_args);
- MemoryAllocatorDump* dump = pmd.CreateAllocatorDump("allocator_for_size");
- dump->AddScalar("one", "byte", 1);
- dump->AddString("one", "object", "one");
- MemoryAllocatorDump::Entry expected_scalar("one", "byte", 1);
- MemoryAllocatorDump::Entry expected_string("one", "object", "one");
- EXPECT_THAT(dump->entries(), ElementsAre(Eq(ByRef(expected_scalar)),
- Eq(ByRef(expected_string))));
- }
- TEST(MemoryAllocatorDumpTest, MovingAnEntry) {
- MemoryAllocatorDump::Entry expected_entry("one", "byte", 1);
- MemoryAllocatorDump::Entry from_entry("one", "byte", 1);
- MemoryAllocatorDump::Entry to_entry = std::move(from_entry);
- EXPECT_EQ(expected_entry, to_entry);
- }
- // DEATH tests are not supported in Android/iOS/Fuchsia.
- #if !defined(NDEBUG) && !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) && \
- !BUILDFLAG(IS_FUCHSIA)
- TEST(MemoryAllocatorDumpTest, ForbidDuplicatesDeathTest) {
- FakeMemoryAllocatorDumpProvider fmadp;
- MemoryDumpArgs dump_args = {MemoryDumpLevelOfDetail::DETAILED};
- ProcessMemoryDump pmd(dump_args);
- pmd.CreateAllocatorDump("foo_allocator");
- pmd.CreateAllocatorDump("bar_allocator/heap");
- ASSERT_DEATH(pmd.CreateAllocatorDump("foo_allocator"), "");
- ASSERT_DEATH(pmd.CreateAllocatorDump("bar_allocator/heap"), "");
- ASSERT_DEATH(pmd.CreateAllocatorDump(""), "");
- }
- TEST(MemoryAllocatorDumpTest, ForbidStringsInBackgroundModeDeathTest) {
- MemoryDumpArgs dump_args = {MemoryDumpLevelOfDetail::BACKGROUND};
- ProcessMemoryDump pmd(dump_args);
- MemoryAllocatorDump* dump = pmd.CreateAllocatorDump("malloc");
- ASSERT_DEATH(dump->AddString("foo", "bar", "baz"), "");
- }
- #endif
- } // namespace trace_event
- } // namespace base
|