Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/trace_event/process_memory_dump.h" | 5 #include "base/trace_event/process_memory_dump.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include "base/memory/aligned_memory.h" | 9 #include "base/memory/aligned_memory.h" |
| 10 #include "base/process/process_metrics.h" | 10 #include "base/process/process_metrics.h" |
| 11 #include "base/trace_event/memory_allocator_dump_guid.h" | 11 #include "base/trace_event/memory_allocator_dump_guid.h" |
| 12 #include "base/trace_event/trace_event_argument.h" | 12 #include "base/trace_event/trace_event_argument.h" |
| 13 #include "testing/gtest/include/gtest/gtest.h" | 13 #include "testing/gtest/include/gtest/gtest.h" |
| 14 | 14 |
| 15 namespace base { | 15 namespace base { |
| 16 namespace trace_event { | 16 namespace trace_event { |
| 17 | 17 |
| 18 namespace { | |
| 19 TracedValue* GetHeapDump(const ProcessMemoryDump& pmd, const char* name) { | |
| 20 auto it = pmd.heap_dumps().find(name); | |
| 21 return (it == pmd.heap_dumps().end()) ? nullptr : it->second.get(); | |
|
petrcermak
2016/02/22 13:33:25
nit: no need for parentheses
Primiano Tucci (use gerrit)
2016/02/22 15:56:07
Done.
| |
| 22 } | |
| 23 } // namespace | |
| 24 | |
| 18 TEST(ProcessMemoryDumpTest, Clear) { | 25 TEST(ProcessMemoryDumpTest, Clear) { |
| 19 scoped_ptr<ProcessMemoryDump> pmd1(new ProcessMemoryDump(nullptr)); | 26 scoped_ptr<ProcessMemoryDump> pmd1(new ProcessMemoryDump(nullptr)); |
| 20 pmd1->CreateAllocatorDump("mad1"); | 27 pmd1->CreateAllocatorDump("mad1"); |
| 21 pmd1->CreateAllocatorDump("mad2"); | 28 pmd1->CreateAllocatorDump("mad2"); |
| 22 ASSERT_FALSE(pmd1->allocator_dumps().empty()); | 29 ASSERT_FALSE(pmd1->allocator_dumps().empty()); |
| 23 | 30 |
| 24 pmd1->process_totals()->set_resident_set_bytes(42); | 31 pmd1->process_totals()->set_resident_set_bytes(42); |
| 25 pmd1->set_has_process_totals(); | 32 pmd1->set_has_process_totals(); |
| 26 | 33 |
| 27 pmd1->process_mmaps()->AddVMRegion(ProcessMemoryMaps::VMRegion()); | 34 pmd1->process_mmaps()->AddVMRegion(ProcessMemoryMaps::VMRegion()); |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 40 ASSERT_TRUE(pmd1->allocator_dumps_edges().empty()); | 47 ASSERT_TRUE(pmd1->allocator_dumps_edges().empty()); |
| 41 ASSERT_EQ(nullptr, pmd1->GetAllocatorDump("mad1")); | 48 ASSERT_EQ(nullptr, pmd1->GetAllocatorDump("mad1")); |
| 42 ASSERT_EQ(nullptr, pmd1->GetAllocatorDump("mad2")); | 49 ASSERT_EQ(nullptr, pmd1->GetAllocatorDump("mad2")); |
| 43 ASSERT_FALSE(pmd1->has_process_totals()); | 50 ASSERT_FALSE(pmd1->has_process_totals()); |
| 44 ASSERT_FALSE(pmd1->has_process_mmaps()); | 51 ASSERT_FALSE(pmd1->has_process_mmaps()); |
| 45 ASSERT_TRUE(pmd1->process_mmaps()->vm_regions().empty()); | 52 ASSERT_TRUE(pmd1->process_mmaps()->vm_regions().empty()); |
| 46 ASSERT_EQ(nullptr, pmd1->GetSharedGlobalAllocatorDump(shared_mad_guid1)); | 53 ASSERT_EQ(nullptr, pmd1->GetSharedGlobalAllocatorDump(shared_mad_guid1)); |
| 47 ASSERT_EQ(nullptr, pmd1->GetSharedGlobalAllocatorDump(shared_mad_guid2)); | 54 ASSERT_EQ(nullptr, pmd1->GetSharedGlobalAllocatorDump(shared_mad_guid2)); |
| 48 | 55 |
| 49 // Check that calling AsValueInto() doesn't cause a crash. | 56 // Check that calling AsValueInto() doesn't cause a crash. |
| 50 scoped_refptr<TracedValue> traced_value(new TracedValue()); | 57 scoped_refptr<TracedValue> traced_value(new TracedValue); |
| 51 pmd1->AsValueInto(traced_value.get()); | 58 pmd1->AsValueInto(traced_value.get()); |
| 52 | 59 |
| 53 // Check that the pmd can be reused and behaves as expected. | 60 // Check that the pmd can be reused and behaves as expected. |
| 54 auto mad1 = pmd1->CreateAllocatorDump("mad1"); | 61 auto mad1 = pmd1->CreateAllocatorDump("mad1"); |
| 55 auto mad3 = pmd1->CreateAllocatorDump("mad3"); | 62 auto mad3 = pmd1->CreateAllocatorDump("mad3"); |
| 56 auto shared_mad1 = pmd1->CreateSharedGlobalAllocatorDump(shared_mad_guid1); | 63 auto shared_mad1 = pmd1->CreateSharedGlobalAllocatorDump(shared_mad_guid1); |
| 57 auto shared_mad2 = | 64 auto shared_mad2 = |
| 58 pmd1->CreateWeakSharedGlobalAllocatorDump(shared_mad_guid2); | 65 pmd1->CreateWeakSharedGlobalAllocatorDump(shared_mad_guid2); |
| 59 ASSERT_EQ(4u, pmd1->allocator_dumps().size()); | 66 ASSERT_EQ(4u, pmd1->allocator_dumps().size()); |
| 60 ASSERT_EQ(mad1, pmd1->GetAllocatorDump("mad1")); | 67 ASSERT_EQ(mad1, pmd1->GetAllocatorDump("mad1")); |
| 61 ASSERT_EQ(nullptr, pmd1->GetAllocatorDump("mad2")); | 68 ASSERT_EQ(nullptr, pmd1->GetAllocatorDump("mad2")); |
| 62 ASSERT_EQ(mad3, pmd1->GetAllocatorDump("mad3")); | 69 ASSERT_EQ(mad3, pmd1->GetAllocatorDump("mad3")); |
| 63 ASSERT_EQ(shared_mad1, pmd1->GetSharedGlobalAllocatorDump(shared_mad_guid1)); | 70 ASSERT_EQ(shared_mad1, pmd1->GetSharedGlobalAllocatorDump(shared_mad_guid1)); |
| 64 ASSERT_EQ(MemoryAllocatorDump::Flags::DEFAULT, shared_mad1->flags()); | 71 ASSERT_EQ(MemoryAllocatorDump::Flags::DEFAULT, shared_mad1->flags()); |
| 65 ASSERT_EQ(shared_mad2, pmd1->GetSharedGlobalAllocatorDump(shared_mad_guid2)); | 72 ASSERT_EQ(shared_mad2, pmd1->GetSharedGlobalAllocatorDump(shared_mad_guid2)); |
| 66 ASSERT_EQ(MemoryAllocatorDump::Flags::WEAK, shared_mad2->flags()); | 73 ASSERT_EQ(MemoryAllocatorDump::Flags::WEAK, shared_mad2->flags()); |
| 67 | 74 |
| 68 traced_value = new TracedValue(); | 75 traced_value = new TracedValue; |
| 69 pmd1->AsValueInto(traced_value.get()); | 76 pmd1->AsValueInto(traced_value.get()); |
| 70 | 77 |
| 71 pmd1.reset(); | 78 pmd1.reset(); |
| 72 } | 79 } |
| 73 | 80 |
| 74 TEST(ProcessMemoryDumpTest, TakeAllDumpsFrom) { | 81 TEST(ProcessMemoryDumpTest, TakeAllDumpsFrom) { |
| 75 scoped_refptr<TracedValue> traced_value(new TracedValue()); | 82 scoped_refptr<TracedValue> traced_value(new TracedValue); |
| 83 TracedValue* heap_dumps_ptr[4]; | |
| 84 scoped_refptr<TracedValue> heap_dump; | |
| 76 | 85 |
| 77 scoped_ptr<ProcessMemoryDump> pmd1(new ProcessMemoryDump(nullptr)); | 86 scoped_ptr<ProcessMemoryDump> pmd1(new ProcessMemoryDump(nullptr)); |
| 78 auto mad1_1 = pmd1->CreateAllocatorDump("pmd1/mad1"); | 87 auto mad1_1 = pmd1->CreateAllocatorDump("pmd1/mad1"); |
| 79 auto mad1_2 = pmd1->CreateAllocatorDump("pmd1/mad2"); | 88 auto mad1_2 = pmd1->CreateAllocatorDump("pmd1/mad2"); |
| 80 pmd1->AddOwnershipEdge(mad1_1->guid(), mad1_2->guid()); | 89 pmd1->AddOwnershipEdge(mad1_1->guid(), mad1_2->guid()); |
| 90 heap_dump = new TracedValue; | |
| 91 heap_dumps_ptr[0] = heap_dump.get(); | |
| 92 pmd1->AddHeapDump("pmd1/heap_dump1", std::move(heap_dump)); | |
| 93 heap_dump = new TracedValue; | |
| 94 heap_dumps_ptr[1] = heap_dump.get(); | |
| 95 pmd1->AddHeapDump("pmd1/heap_dump2", std::move(heap_dump)); | |
| 81 | 96 |
| 82 scoped_ptr<ProcessMemoryDump> pmd2(new ProcessMemoryDump(nullptr)); | 97 scoped_ptr<ProcessMemoryDump> pmd2(new ProcessMemoryDump(nullptr)); |
| 83 auto mad2_1 = pmd2->CreateAllocatorDump("pmd2/mad1"); | 98 auto mad2_1 = pmd2->CreateAllocatorDump("pmd2/mad1"); |
| 84 auto mad2_2 = pmd2->CreateAllocatorDump("pmd2/mad2"); | 99 auto mad2_2 = pmd2->CreateAllocatorDump("pmd2/mad2"); |
| 85 pmd1->AddOwnershipEdge(mad2_1->guid(), mad2_2->guid()); | 100 pmd2->AddOwnershipEdge(mad2_1->guid(), mad2_2->guid()); |
| 101 heap_dump = new TracedValue; | |
| 102 heap_dumps_ptr[2] = heap_dump.get(); | |
| 103 pmd2->AddHeapDump("pmd2/heap_dump1", std::move(heap_dump)); | |
| 104 heap_dump = new TracedValue; | |
| 105 heap_dumps_ptr[3] = heap_dump.get(); | |
| 106 pmd2->AddHeapDump("pmd2/heap_dump2", std::move(heap_dump)); | |
| 86 | 107 |
| 87 MemoryAllocatorDumpGuid shared_mad_guid1(1); | 108 MemoryAllocatorDumpGuid shared_mad_guid1(1); |
| 88 MemoryAllocatorDumpGuid shared_mad_guid2(2); | 109 MemoryAllocatorDumpGuid shared_mad_guid2(2); |
| 89 auto shared_mad1 = pmd2->CreateSharedGlobalAllocatorDump(shared_mad_guid1); | 110 auto shared_mad1 = pmd2->CreateSharedGlobalAllocatorDump(shared_mad_guid1); |
| 90 auto shared_mad2 = | 111 auto shared_mad2 = |
| 91 pmd2->CreateWeakSharedGlobalAllocatorDump(shared_mad_guid2); | 112 pmd2->CreateWeakSharedGlobalAllocatorDump(shared_mad_guid2); |
| 92 | 113 |
| 93 pmd1->TakeAllDumpsFrom(pmd2.get()); | 114 pmd1->TakeAllDumpsFrom(pmd2.get()); |
| 94 | 115 |
| 95 // Make sure that pmd2 is empty but still usable after it has been emptied. | 116 // Make sure that pmd2 is empty but still usable after it has been emptied. |
| 96 ASSERT_TRUE(pmd2->allocator_dumps().empty()); | 117 ASSERT_TRUE(pmd2->allocator_dumps().empty()); |
| 97 ASSERT_TRUE(pmd2->allocator_dumps_edges().empty()); | 118 ASSERT_TRUE(pmd2->allocator_dumps_edges().empty()); |
| 119 ASSERT_TRUE(pmd2->heap_dumps().empty()); | |
| 98 pmd2->CreateAllocatorDump("pmd2/this_mad_stays_with_pmd2"); | 120 pmd2->CreateAllocatorDump("pmd2/this_mad_stays_with_pmd2"); |
| 99 ASSERT_EQ(1u, pmd2->allocator_dumps().size()); | 121 ASSERT_EQ(1u, pmd2->allocator_dumps().size()); |
| 100 ASSERT_EQ(1u, pmd2->allocator_dumps().count("pmd2/this_mad_stays_with_pmd2")); | 122 ASSERT_EQ(1u, pmd2->allocator_dumps().count("pmd2/this_mad_stays_with_pmd2")); |
| 101 pmd2->AddOwnershipEdge(MemoryAllocatorDumpGuid(42), | 123 pmd2->AddOwnershipEdge(MemoryAllocatorDumpGuid(42), |
| 102 MemoryAllocatorDumpGuid(4242)); | 124 MemoryAllocatorDumpGuid(4242)); |
| 103 | 125 |
| 104 // Check that calling AsValueInto() doesn't cause a crash. | 126 // Check that calling AsValueInto() doesn't cause a crash. |
| 105 pmd2->AsValueInto(traced_value.get()); | 127 pmd2->AsValueInto(traced_value.get()); |
| 106 | 128 |
| 107 // Free the |pmd2| to check that the memory ownership of the two MAD(s) | 129 // Free the |pmd2| to check that the memory ownership of the two MAD(s) |
| 108 // has been transferred to |pmd1|. | 130 // has been transferred to |pmd1|. |
| 109 pmd2.reset(); | 131 pmd2.reset(); |
| 110 | 132 |
| 111 // Now check that |pmd1| has been effectively merged. | 133 // Now check that |pmd1| has been effectively merged. |
| 112 ASSERT_EQ(6u, pmd1->allocator_dumps().size()); | 134 ASSERT_EQ(6u, pmd1->allocator_dumps().size()); |
| 113 ASSERT_EQ(1u, pmd1->allocator_dumps().count("pmd1/mad1")); | 135 ASSERT_EQ(1u, pmd1->allocator_dumps().count("pmd1/mad1")); |
| 114 ASSERT_EQ(1u, pmd1->allocator_dumps().count("pmd1/mad2")); | 136 ASSERT_EQ(1u, pmd1->allocator_dumps().count("pmd1/mad2")); |
| 115 ASSERT_EQ(1u, pmd1->allocator_dumps().count("pmd2/mad1")); | 137 ASSERT_EQ(1u, pmd1->allocator_dumps().count("pmd2/mad1")); |
| 116 ASSERT_EQ(1u, pmd1->allocator_dumps().count("pmd1/mad2")); | 138 ASSERT_EQ(1u, pmd1->allocator_dumps().count("pmd1/mad2")); |
| 117 ASSERT_EQ(2u, pmd1->allocator_dumps_edges().size()); | 139 ASSERT_EQ(2u, pmd1->allocator_dumps_edges().size()); |
| 118 ASSERT_EQ(shared_mad1, pmd1->GetSharedGlobalAllocatorDump(shared_mad_guid1)); | 140 ASSERT_EQ(shared_mad1, pmd1->GetSharedGlobalAllocatorDump(shared_mad_guid1)); |
| 119 ASSERT_EQ(shared_mad2, pmd1->GetSharedGlobalAllocatorDump(shared_mad_guid2)); | 141 ASSERT_EQ(shared_mad2, pmd1->GetSharedGlobalAllocatorDump(shared_mad_guid2)); |
| 120 ASSERT_TRUE(MemoryAllocatorDump::Flags::WEAK & shared_mad2->flags()); | 142 ASSERT_TRUE(MemoryAllocatorDump::Flags::WEAK & shared_mad2->flags()); |
| 143 ASSERT_EQ(4u, pmd1->heap_dumps().size()); | |
| 144 ASSERT_EQ(heap_dumps_ptr[0], GetHeapDump(*pmd1, "pmd1/heap_dump1")); | |
| 145 ASSERT_EQ(heap_dumps_ptr[1], GetHeapDump(*pmd1, "pmd1/heap_dump2")); | |
| 146 ASSERT_EQ(heap_dumps_ptr[2], GetHeapDump(*pmd1, "pmd2/heap_dump1")); | |
| 147 ASSERT_EQ(heap_dumps_ptr[3], GetHeapDump(*pmd1, "pmd2/heap_dump2")); | |
| 121 | 148 |
| 122 // Check that calling AsValueInto() doesn't cause a crash. | 149 // Check that calling AsValueInto() doesn't cause a crash. |
| 123 traced_value = new TracedValue(); | 150 traced_value = new TracedValue; |
| 124 pmd1->AsValueInto(traced_value.get()); | 151 pmd1->AsValueInto(traced_value.get()); |
| 125 | 152 |
| 126 pmd1.reset(); | 153 pmd1.reset(); |
| 127 } | 154 } |
| 128 | 155 |
| 129 TEST(ProcessMemoryDumpTest, Suballocations) { | 156 TEST(ProcessMemoryDumpTest, Suballocations) { |
| 130 scoped_ptr<ProcessMemoryDump> pmd(new ProcessMemoryDump(nullptr)); | 157 scoped_ptr<ProcessMemoryDump> pmd(new ProcessMemoryDump(nullptr)); |
| 131 const std::string allocator_dump_name = "fakealloc/allocated_objects"; | 158 const std::string allocator_dump_name = "fakealloc/allocated_objects"; |
| 132 pmd->CreateAllocatorDump(allocator_dump_name); | 159 pmd->CreateAllocatorDump(allocator_dump_name); |
| 133 | 160 |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 157 for (const auto& e : pmd->allocator_dumps_edges()) { | 184 for (const auto& e : pmd->allocator_dumps_edges()) { |
| 158 found_edge[0] |= (e.source == pic1_dump->guid() && | 185 found_edge[0] |= (e.source == pic1_dump->guid() && |
| 159 e.target == anon_node_1_it->second->guid()); | 186 e.target == anon_node_1_it->second->guid()); |
| 160 found_edge[1] |= (e.source == pic2_dump->guid() && | 187 found_edge[1] |= (e.source == pic2_dump->guid() && |
| 161 e.target == anon_node_2_it->second->guid()); | 188 e.target == anon_node_2_it->second->guid()); |
| 162 } | 189 } |
| 163 ASSERT_TRUE(found_edge[0]); | 190 ASSERT_TRUE(found_edge[0]); |
| 164 ASSERT_TRUE(found_edge[1]); | 191 ASSERT_TRUE(found_edge[1]); |
| 165 | 192 |
| 166 // Check that calling AsValueInto() doesn't cause a crash. | 193 // Check that calling AsValueInto() doesn't cause a crash. |
| 167 scoped_refptr<TracedValue> traced_value(new TracedValue()); | 194 scoped_refptr<TracedValue> traced_value(new TracedValue); |
| 168 pmd->AsValueInto(traced_value.get()); | 195 pmd->AsValueInto(traced_value.get()); |
| 169 | 196 |
| 170 pmd.reset(); | 197 pmd.reset(); |
| 171 } | 198 } |
| 172 | 199 |
| 173 TEST(ProcessMemoryDumpTest, GlobalAllocatorDumpTest) { | 200 TEST(ProcessMemoryDumpTest, GlobalAllocatorDumpTest) { |
| 174 scoped_ptr<ProcessMemoryDump> pmd(new ProcessMemoryDump(nullptr)); | 201 scoped_ptr<ProcessMemoryDump> pmd(new ProcessMemoryDump(nullptr)); |
| 175 MemoryAllocatorDumpGuid shared_mad_guid(1); | 202 MemoryAllocatorDumpGuid shared_mad_guid(1); |
| 176 auto shared_mad1 = pmd->CreateWeakSharedGlobalAllocatorDump(shared_mad_guid); | 203 auto shared_mad1 = pmd->CreateWeakSharedGlobalAllocatorDump(shared_mad_guid); |
| 177 ASSERT_EQ(shared_mad_guid, shared_mad1->guid()); | 204 ASSERT_EQ(shared_mad_guid, shared_mad1->guid()); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 212 static_cast<char*>(base::AlignedAlloc(kVeryLargeMemorySize, page_size))); | 239 static_cast<char*>(base::AlignedAlloc(kVeryLargeMemorySize, page_size))); |
| 213 memset(memory2.get(), 0, kVeryLargeMemorySize); | 240 memset(memory2.get(), 0, kVeryLargeMemorySize); |
| 214 size_t res2 = ProcessMemoryDump::CountResidentBytes(memory2.get(), | 241 size_t res2 = ProcessMemoryDump::CountResidentBytes(memory2.get(), |
| 215 kVeryLargeMemorySize); | 242 kVeryLargeMemorySize); |
| 216 ASSERT_EQ(res2, kVeryLargeMemorySize); | 243 ASSERT_EQ(res2, kVeryLargeMemorySize); |
| 217 } | 244 } |
| 218 #endif // defined(COUNT_RESIDENT_BYTES_SUPPORTED) | 245 #endif // defined(COUNT_RESIDENT_BYTES_SUPPORTED) |
| 219 | 246 |
| 220 } // namespace trace_event | 247 } // namespace trace_event |
| 221 } // namespace base | 248 } // namespace base |
| OLD | NEW |