Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(19)

Side by Side Diff: base/trace_event/process_memory_dump_unittest.cc

Issue 2006943003: [tracing] Sanitize process memory dumps for background mode (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@whitelist_mdp
Patch Set: Addressing comments. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/memory/ptr_util.h" 10 #include "base/memory/ptr_util.h"
11 #include "base/process/process_metrics.h" 11 #include "base/process/process_metrics.h"
12 #include "base/trace_event/memory_allocator_dump_guid.h" 12 #include "base/trace_event/memory_allocator_dump_guid.h"
13 #include "base/trace_event/memory_infra_background_whitelist.h"
13 #include "base/trace_event/trace_event_argument.h" 14 #include "base/trace_event/trace_event_argument.h"
14 #include "testing/gtest/include/gtest/gtest.h" 15 #include "testing/gtest/include/gtest/gtest.h"
15 16
16 namespace base { 17 namespace base {
17 namespace trace_event { 18 namespace trace_event {
18 19
19 namespace { 20 namespace {
21
22 const MemoryDumpArgs kDetailedDumpArgs = {MemoryDumpLevelOfDetail::DETAILED};
23 const char* const kTestDumpNameWhitelist[] = {"WhitelistedTestName", nullptr};
24
20 TracedValue* GetHeapDump(const ProcessMemoryDump& pmd, const char* name) { 25 TracedValue* GetHeapDump(const ProcessMemoryDump& pmd, const char* name) {
21 auto it = pmd.heap_dumps().find(name); 26 auto it = pmd.heap_dumps().find(name);
22 return it == pmd.heap_dumps().end() ? nullptr : it->second.get(); 27 return it == pmd.heap_dumps().end() ? nullptr : it->second.get();
23 } 28 }
29
24 } // namespace 30 } // namespace
25 31
26 TEST(ProcessMemoryDumpTest, Clear) { 32 TEST(ProcessMemoryDumpTest, Clear) {
27 std::unique_ptr<ProcessMemoryDump> pmd1(new ProcessMemoryDump(nullptr)); 33 std::unique_ptr<ProcessMemoryDump> pmd1(
34 new ProcessMemoryDump(nullptr, kDetailedDumpArgs));
28 pmd1->CreateAllocatorDump("mad1"); 35 pmd1->CreateAllocatorDump("mad1");
29 pmd1->CreateAllocatorDump("mad2"); 36 pmd1->CreateAllocatorDump("mad2");
30 ASSERT_FALSE(pmd1->allocator_dumps().empty()); 37 ASSERT_FALSE(pmd1->allocator_dumps().empty());
31 38
32 pmd1->process_totals()->set_resident_set_bytes(42); 39 pmd1->process_totals()->set_resident_set_bytes(42);
33 pmd1->set_has_process_totals(); 40 pmd1->set_has_process_totals();
34 41
35 pmd1->process_mmaps()->AddVMRegion(ProcessMemoryMaps::VMRegion()); 42 pmd1->process_mmaps()->AddVMRegion(ProcessMemoryMaps::VMRegion());
36 pmd1->set_has_process_mmaps(); 43 pmd1->set_has_process_mmaps();
37 44
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 metrics_by_context[AllocationContext()] = { 1, 1 }; 92 metrics_by_context[AllocationContext()] = { 1, 1 };
86 TraceEventMemoryOverhead overhead; 93 TraceEventMemoryOverhead overhead;
87 94
88 scoped_refptr<MemoryDumpSessionState> session_state = 95 scoped_refptr<MemoryDumpSessionState> session_state =
89 new MemoryDumpSessionState; 96 new MemoryDumpSessionState;
90 session_state->SetStackFrameDeduplicator( 97 session_state->SetStackFrameDeduplicator(
91 WrapUnique(new StackFrameDeduplicator)); 98 WrapUnique(new StackFrameDeduplicator));
92 session_state->SetTypeNameDeduplicator( 99 session_state->SetTypeNameDeduplicator(
93 WrapUnique(new TypeNameDeduplicator)); 100 WrapUnique(new TypeNameDeduplicator));
94 std::unique_ptr<ProcessMemoryDump> pmd1( 101 std::unique_ptr<ProcessMemoryDump> pmd1(
95 new ProcessMemoryDump(session_state.get())); 102 new ProcessMemoryDump(session_state.get(), kDetailedDumpArgs));
96 auto mad1_1 = pmd1->CreateAllocatorDump("pmd1/mad1"); 103 auto mad1_1 = pmd1->CreateAllocatorDump("pmd1/mad1");
97 auto mad1_2 = pmd1->CreateAllocatorDump("pmd1/mad2"); 104 auto mad1_2 = pmd1->CreateAllocatorDump("pmd1/mad2");
98 pmd1->AddOwnershipEdge(mad1_1->guid(), mad1_2->guid()); 105 pmd1->AddOwnershipEdge(mad1_1->guid(), mad1_2->guid());
99 pmd1->DumpHeapUsage(metrics_by_context, overhead, "pmd1/heap_dump1"); 106 pmd1->DumpHeapUsage(metrics_by_context, overhead, "pmd1/heap_dump1");
100 pmd1->DumpHeapUsage(metrics_by_context, overhead, "pmd1/heap_dump2"); 107 pmd1->DumpHeapUsage(metrics_by_context, overhead, "pmd1/heap_dump2");
101 108
102 std::unique_ptr<ProcessMemoryDump> pmd2( 109 std::unique_ptr<ProcessMemoryDump> pmd2(
103 new ProcessMemoryDump(session_state.get())); 110 new ProcessMemoryDump(session_state.get(), kDetailedDumpArgs));
104 auto mad2_1 = pmd2->CreateAllocatorDump("pmd2/mad1"); 111 auto mad2_1 = pmd2->CreateAllocatorDump("pmd2/mad1");
105 auto mad2_2 = pmd2->CreateAllocatorDump("pmd2/mad2"); 112 auto mad2_2 = pmd2->CreateAllocatorDump("pmd2/mad2");
106 pmd2->AddOwnershipEdge(mad2_1->guid(), mad2_2->guid()); 113 pmd2->AddOwnershipEdge(mad2_1->guid(), mad2_2->guid());
107 pmd2->DumpHeapUsage(metrics_by_context, overhead, "pmd2/heap_dump1"); 114 pmd2->DumpHeapUsage(metrics_by_context, overhead, "pmd2/heap_dump1");
108 pmd2->DumpHeapUsage(metrics_by_context, overhead, "pmd2/heap_dump2"); 115 pmd2->DumpHeapUsage(metrics_by_context, overhead, "pmd2/heap_dump2");
109 116
110 MemoryAllocatorDumpGuid shared_mad_guid1(1); 117 MemoryAllocatorDumpGuid shared_mad_guid1(1);
111 MemoryAllocatorDumpGuid shared_mad_guid2(2); 118 MemoryAllocatorDumpGuid shared_mad_guid2(2);
112 auto shared_mad1 = pmd2->CreateSharedGlobalAllocatorDump(shared_mad_guid1); 119 auto shared_mad1 = pmd2->CreateSharedGlobalAllocatorDump(shared_mad_guid1);
113 auto shared_mad2 = 120 auto shared_mad2 =
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 ASSERT_TRUE(GetHeapDump(*pmd1, "pmd2/heap_dump2") != nullptr); 156 ASSERT_TRUE(GetHeapDump(*pmd1, "pmd2/heap_dump2") != nullptr);
150 157
151 // Check that calling AsValueInto() doesn't cause a crash. 158 // Check that calling AsValueInto() doesn't cause a crash.
152 traced_value.reset(new TracedValue); 159 traced_value.reset(new TracedValue);
153 pmd1->AsValueInto(traced_value.get()); 160 pmd1->AsValueInto(traced_value.get());
154 161
155 pmd1.reset(); 162 pmd1.reset();
156 } 163 }
157 164
158 TEST(ProcessMemoryDumpTest, Suballocations) { 165 TEST(ProcessMemoryDumpTest, Suballocations) {
159 std::unique_ptr<ProcessMemoryDump> pmd(new ProcessMemoryDump(nullptr)); 166 std::unique_ptr<ProcessMemoryDump> pmd(
167 new ProcessMemoryDump(nullptr, kDetailedDumpArgs));
160 const std::string allocator_dump_name = "fakealloc/allocated_objects"; 168 const std::string allocator_dump_name = "fakealloc/allocated_objects";
161 pmd->CreateAllocatorDump(allocator_dump_name); 169 pmd->CreateAllocatorDump(allocator_dump_name);
162 170
163 // Create one allocation with an auto-assigned guid and mark it as a 171 // Create one allocation with an auto-assigned guid and mark it as a
164 // suballocation of "fakealloc/allocated_objects". 172 // suballocation of "fakealloc/allocated_objects".
165 auto pic1_dump = pmd->CreateAllocatorDump("picturemanager/picture1"); 173 auto pic1_dump = pmd->CreateAllocatorDump("picturemanager/picture1");
166 pmd->AddSuballocation(pic1_dump->guid(), allocator_dump_name); 174 pmd->AddSuballocation(pic1_dump->guid(), allocator_dump_name);
167 175
168 // Same here, but this time create an allocation with an explicit guid. 176 // Same here, but this time create an allocation with an explicit guid.
169 auto pic2_dump = pmd->CreateAllocatorDump("picturemanager/picture2", 177 auto pic2_dump = pmd->CreateAllocatorDump("picturemanager/picture2",
(...skipping 23 matching lines...) Expand all
193 ASSERT_TRUE(found_edge[1]); 201 ASSERT_TRUE(found_edge[1]);
194 202
195 // Check that calling AsValueInto() doesn't cause a crash. 203 // Check that calling AsValueInto() doesn't cause a crash.
196 std::unique_ptr<TracedValue> traced_value(new TracedValue); 204 std::unique_ptr<TracedValue> traced_value(new TracedValue);
197 pmd->AsValueInto(traced_value.get()); 205 pmd->AsValueInto(traced_value.get());
198 206
199 pmd.reset(); 207 pmd.reset();
200 } 208 }
201 209
202 TEST(ProcessMemoryDumpTest, GlobalAllocatorDumpTest) { 210 TEST(ProcessMemoryDumpTest, GlobalAllocatorDumpTest) {
203 std::unique_ptr<ProcessMemoryDump> pmd(new ProcessMemoryDump(nullptr)); 211 std::unique_ptr<ProcessMemoryDump> pmd(
212 new ProcessMemoryDump(nullptr, kDetailedDumpArgs));
204 MemoryAllocatorDumpGuid shared_mad_guid(1); 213 MemoryAllocatorDumpGuid shared_mad_guid(1);
205 auto shared_mad1 = pmd->CreateWeakSharedGlobalAllocatorDump(shared_mad_guid); 214 auto shared_mad1 = pmd->CreateWeakSharedGlobalAllocatorDump(shared_mad_guid);
206 ASSERT_EQ(shared_mad_guid, shared_mad1->guid()); 215 ASSERT_EQ(shared_mad_guid, shared_mad1->guid());
207 ASSERT_EQ(MemoryAllocatorDump::Flags::WEAK, shared_mad1->flags()); 216 ASSERT_EQ(MemoryAllocatorDump::Flags::WEAK, shared_mad1->flags());
208 217
209 auto shared_mad2 = pmd->GetSharedGlobalAllocatorDump(shared_mad_guid); 218 auto shared_mad2 = pmd->GetSharedGlobalAllocatorDump(shared_mad_guid);
210 ASSERT_EQ(shared_mad1, shared_mad2); 219 ASSERT_EQ(shared_mad1, shared_mad2);
211 ASSERT_EQ(MemoryAllocatorDump::Flags::WEAK, shared_mad1->flags()); 220 ASSERT_EQ(MemoryAllocatorDump::Flags::WEAK, shared_mad1->flags());
212 221
213 auto shared_mad3 = pmd->CreateWeakSharedGlobalAllocatorDump(shared_mad_guid); 222 auto shared_mad3 = pmd->CreateWeakSharedGlobalAllocatorDump(shared_mad_guid);
214 ASSERT_EQ(shared_mad1, shared_mad3); 223 ASSERT_EQ(shared_mad1, shared_mad3);
215 ASSERT_EQ(MemoryAllocatorDump::Flags::WEAK, shared_mad1->flags()); 224 ASSERT_EQ(MemoryAllocatorDump::Flags::WEAK, shared_mad1->flags());
216 225
217 auto shared_mad4 = pmd->CreateSharedGlobalAllocatorDump(shared_mad_guid); 226 auto shared_mad4 = pmd->CreateSharedGlobalAllocatorDump(shared_mad_guid);
218 ASSERT_EQ(shared_mad1, shared_mad4); 227 ASSERT_EQ(shared_mad1, shared_mad4);
219 ASSERT_EQ(MemoryAllocatorDump::Flags::DEFAULT, shared_mad1->flags()); 228 ASSERT_EQ(MemoryAllocatorDump::Flags::DEFAULT, shared_mad1->flags());
220 229
221 auto shared_mad5 = pmd->CreateWeakSharedGlobalAllocatorDump(shared_mad_guid); 230 auto shared_mad5 = pmd->CreateWeakSharedGlobalAllocatorDump(shared_mad_guid);
222 ASSERT_EQ(shared_mad1, shared_mad5); 231 ASSERT_EQ(shared_mad1, shared_mad5);
223 ASSERT_EQ(MemoryAllocatorDump::Flags::DEFAULT, shared_mad1->flags()); 232 ASSERT_EQ(MemoryAllocatorDump::Flags::DEFAULT, shared_mad1->flags());
224 } 233 }
225 234
235 TEST(ProcessMemoryDumpTest, BackgroundModeTest) {
236 MemoryDumpArgs background_args = {MemoryDumpLevelOfDetail::BACKGROUND};
237 std::unique_ptr<ProcessMemoryDump> pmd(
238 new ProcessMemoryDump(nullptr, background_args));
239 ProcessMemoryDump::is_black_hole_non_fatal_for_testing_ = true;
240 SetAllocatorDumpNameWhitelistForTesting(kTestDumpNameWhitelist);
241 MemoryAllocatorDump* black_hole_mad = pmd->GetBlackHoleMad();
242
243 // Invalid dump names.
244 EXPECT_EQ(black_hole_mad, pmd->CreateAllocatorDump("NotWhitelistedTestName"));
245 EXPECT_EQ(black_hole_mad, pmd->CreateAllocatorDump("TestName"));
246 EXPECT_EQ(black_hole_mad, pmd->CreateAllocatorDump("Whitelisted/Test"));
247 EXPECT_EQ(black_hole_mad,
248 pmd->CreateAllocatorDump("Not/Whitelisted/TestName"));
249 EXPECT_EQ(black_hole_mad,
250 pmd->CreateAllocatorDump("Whitelisted/TestName/Google"));
251 EXPECT_EQ(black_hole_mad,
252 pmd->CreateAllocatorDump("Whitelisted/TestName/0x1a2Google"));
253 EXPECT_EQ(black_hole_mad,
254 pmd->CreateAllocatorDump("Whitelisted/TestName/__12/Google"));
255
256 // Global dumps.
257 MemoryAllocatorDumpGuid guid(1);
258 EXPECT_EQ(black_hole_mad, pmd->CreateSharedGlobalAllocatorDump(guid));
259 EXPECT_EQ(black_hole_mad, pmd->CreateWeakSharedGlobalAllocatorDump(guid));
260 EXPECT_EQ(black_hole_mad, pmd->GetSharedGlobalAllocatorDump(guid));
261
262 // Suballocations.
263 pmd->AddSuballocation(guid, "malloc/allocated_objects");
264 EXPECT_EQ(0u, pmd->allocator_dumps_edges_.size());
265 EXPECT_EQ(0u, pmd->allocator_dumps_.size());
266
267 // Valid dump names.
268 EXPECT_NE(black_hole_mad, pmd->CreateAllocatorDump("WhitelistedTestName"));
269 EXPECT_NE(black_hole_mad,
270 pmd->CreateAllocatorDump("Whitelisted/TestName/0xA1b2"));
Primiano Tucci (use gerrit) 2016/06/03 16:24:36 small change, By looking at this test I just reali
ssid 2016/06/04 00:26:58 There is no way to avoid awkwardness. Right now if
271 EXPECT_NE(black_hole_mad,
272 pmd->CreateAllocatorDump("Whitelisted/TestName_123/0xab"));
273 EXPECT_NE(black_hole_mad,
274 pmd->CreateAllocatorDump("Whitelisted_12/0xaB/TestName"));
275
276 // GetAllocatorDump is consistent.
277 EXPECT_EQ(black_hole_mad, pmd->GetAllocatorDump("NotWhitelistedTestName"));
278 auto mad = pmd->GetAllocatorDump("WhitelistedTestName");
279 EXPECT_NE(black_hole_mad, mad);
280 }
281
226 #if defined(COUNT_RESIDENT_BYTES_SUPPORTED) 282 #if defined(COUNT_RESIDENT_BYTES_SUPPORTED)
227 TEST(ProcessMemoryDumpTest, CountResidentBytes) { 283 TEST(ProcessMemoryDumpTest, CountResidentBytes) {
228 const size_t page_size = ProcessMemoryDump::GetSystemPageSize(); 284 const size_t page_size = ProcessMemoryDump::GetSystemPageSize();
229 285
230 // Allocate few page of dirty memory and check if it is resident. 286 // Allocate few page of dirty memory and check if it is resident.
231 const size_t size1 = 5 * page_size; 287 const size_t size1 = 5 * page_size;
232 std::unique_ptr<char, base::AlignedFreeDeleter> memory1( 288 std::unique_ptr<char, base::AlignedFreeDeleter> memory1(
233 static_cast<char*>(base::AlignedAlloc(size1, page_size))); 289 static_cast<char*>(base::AlignedAlloc(size1, page_size)));
234 memset(memory1.get(), 0, size1); 290 memset(memory1.get(), 0, size1);
235 size_t res1 = ProcessMemoryDump::CountResidentBytes(memory1.get(), size1); 291 size_t res1 = ProcessMemoryDump::CountResidentBytes(memory1.get(), size1);
236 ASSERT_EQ(res1, size1); 292 ASSERT_EQ(res1, size1);
237 293
238 // Allocate a large memory segment (> 8Mib). 294 // Allocate a large memory segment (> 8Mib).
239 const size_t kVeryLargeMemorySize = 15 * 1024 * 1024; 295 const size_t kVeryLargeMemorySize = 15 * 1024 * 1024;
240 std::unique_ptr<char, base::AlignedFreeDeleter> memory2( 296 std::unique_ptr<char, base::AlignedFreeDeleter> memory2(
241 static_cast<char*>(base::AlignedAlloc(kVeryLargeMemorySize, page_size))); 297 static_cast<char*>(base::AlignedAlloc(kVeryLargeMemorySize, page_size)));
242 memset(memory2.get(), 0, kVeryLargeMemorySize); 298 memset(memory2.get(), 0, kVeryLargeMemorySize);
243 size_t res2 = ProcessMemoryDump::CountResidentBytes(memory2.get(), 299 size_t res2 = ProcessMemoryDump::CountResidentBytes(memory2.get(),
244 kVeryLargeMemorySize); 300 kVeryLargeMemorySize);
245 ASSERT_EQ(res2, kVeryLargeMemorySize); 301 ASSERT_EQ(res2, kVeryLargeMemorySize);
246 } 302 }
247 #endif // defined(COUNT_RESIDENT_BYTES_SUPPORTED) 303 #endif // defined(COUNT_RESIDENT_BYTES_SUPPORTED)
248 304
249 } // namespace trace_event 305 } // namespace trace_event
250 } // namespace base 306 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698