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

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: Fixes. 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/process/process_metrics.h" 11 #include "base/process/process_metrics.h"
11 #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"
12 #include "base/trace_event/trace_event_argument.h" 14 #include "base/trace_event/trace_event_argument.h"
13 #include "testing/gtest/include/gtest/gtest.h" 15 #include "testing/gtest/include/gtest/gtest.h"
14 16
15 namespace base { 17 namespace base {
16 namespace trace_event { 18 namespace trace_event {
17 19
18 namespace { 20 namespace {
21
22 const MemoryDumpArgs kDetailedDumpArgs = {MemoryDumpLevelOfDetail::DETAILED};
23 const char* const kTestDumpNameWhitelist[] = {"WhitelistedTestName", nullptr};
Primiano Tucci (use gerrit) 2016/06/02 20:24:04 I think you should move this below, because you re
ssid 2016/06/03 01:59:46 Hm it is bad i will be setting a global g_whitelis
24
19 TracedValue* GetHeapDump(const ProcessMemoryDump& pmd, const char* name) { 25 TracedValue* GetHeapDump(const ProcessMemoryDump& pmd, const char* name) {
20 auto it = pmd.heap_dumps().find(name); 26 auto it = pmd.heap_dumps().find(name);
21 return it == pmd.heap_dumps().end() ? nullptr : it->second.get(); 27 return it == pmd.heap_dumps().end() ? nullptr : it->second.get();
22 } 28 }
29
23 } // namespace 30 } // namespace
24 31
25 TEST(ProcessMemoryDumpTest, Clear) { 32 class ProcessMemoryDumpTest : public testing::Test {
26 std::unique_ptr<ProcessMemoryDump> pmd1(new ProcessMemoryDump(nullptr)); 33 protected:
34 MemoryAllocatorDump* CreateAllocatorDumpInPMD(ProcessMemoryDump* pmd,
35 const char* name) {
36 return pmd->AddAllocatorDumpInternal(WrapUnique(
37 new MemoryAllocatorDump(name, pmd, MemoryAllocatorDumpGuid())));
38 }
39 };
40
41 TEST_F(ProcessMemoryDumpTest, Clear) {
42 std::unique_ptr<ProcessMemoryDump> pmd1(
43 new ProcessMemoryDump(nullptr, kDetailedDumpArgs));
27 pmd1->CreateAllocatorDump("mad1"); 44 pmd1->CreateAllocatorDump("mad1");
28 pmd1->CreateAllocatorDump("mad2"); 45 pmd1->CreateAllocatorDump("mad2");
29 ASSERT_FALSE(pmd1->allocator_dumps().empty()); 46 ASSERT_FALSE(pmd1->allocator_dumps().empty());
30 47
31 pmd1->process_totals()->set_resident_set_bytes(42); 48 pmd1->process_totals()->set_resident_set_bytes(42);
32 pmd1->set_has_process_totals(); 49 pmd1->set_has_process_totals();
33 50
34 pmd1->process_mmaps()->AddVMRegion(ProcessMemoryMaps::VMRegion()); 51 pmd1->process_mmaps()->AddVMRegion(ProcessMemoryMaps::VMRegion());
35 pmd1->set_has_process_mmaps(); 52 pmd1->set_has_process_mmaps();
36 53
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 ASSERT_EQ(MemoryAllocatorDump::Flags::DEFAULT, shared_mad1->flags()); 88 ASSERT_EQ(MemoryAllocatorDump::Flags::DEFAULT, shared_mad1->flags());
72 ASSERT_EQ(shared_mad2, pmd1->GetSharedGlobalAllocatorDump(shared_mad_guid2)); 89 ASSERT_EQ(shared_mad2, pmd1->GetSharedGlobalAllocatorDump(shared_mad_guid2));
73 ASSERT_EQ(MemoryAllocatorDump::Flags::WEAK, shared_mad2->flags()); 90 ASSERT_EQ(MemoryAllocatorDump::Flags::WEAK, shared_mad2->flags());
74 91
75 traced_value.reset(new TracedValue); 92 traced_value.reset(new TracedValue);
76 pmd1->AsValueInto(traced_value.get()); 93 pmd1->AsValueInto(traced_value.get());
77 94
78 pmd1.reset(); 95 pmd1.reset();
79 } 96 }
80 97
81 TEST(ProcessMemoryDumpTest, TakeAllDumpsFrom) { 98 TEST_F(ProcessMemoryDumpTest, TakeAllDumpsFrom) {
82 std::unique_ptr<TracedValue> traced_value(new TracedValue); 99 std::unique_ptr<TracedValue> traced_value(new TracedValue);
83 hash_map<AllocationContext, AllocationMetrics> metrics_by_context; 100 hash_map<AllocationContext, AllocationMetrics> metrics_by_context;
84 metrics_by_context[AllocationContext()] = { 1, 1 }; 101 metrics_by_context[AllocationContext()] = { 1, 1 };
85 TraceEventMemoryOverhead overhead; 102 TraceEventMemoryOverhead overhead;
86 103
87 std::unique_ptr<ProcessMemoryDump> pmd1( 104 std::unique_ptr<ProcessMemoryDump> pmd1(
88 new ProcessMemoryDump(new MemoryDumpSessionState())); 105 new ProcessMemoryDump(new MemoryDumpSessionState(), kDetailedDumpArgs));
89 auto mad1_1 = pmd1->CreateAllocatorDump("pmd1/mad1"); 106 auto mad1_1 = pmd1->CreateAllocatorDump("pmd1/mad1");
90 auto mad1_2 = pmd1->CreateAllocatorDump("pmd1/mad2"); 107 auto mad1_2 = pmd1->CreateAllocatorDump("pmd1/mad2");
91 pmd1->AddOwnershipEdge(mad1_1->guid(), mad1_2->guid()); 108 pmd1->AddOwnershipEdge(mad1_1->guid(), mad1_2->guid());
92 pmd1->DumpHeapUsage(metrics_by_context, overhead, "pmd1/heap_dump1"); 109 pmd1->DumpHeapUsage(metrics_by_context, overhead, "pmd1/heap_dump1");
93 pmd1->DumpHeapUsage(metrics_by_context, overhead, "pmd1/heap_dump2"); 110 pmd1->DumpHeapUsage(metrics_by_context, overhead, "pmd1/heap_dump2");
94 111
95 std::unique_ptr<ProcessMemoryDump> pmd2( 112 std::unique_ptr<ProcessMemoryDump> pmd2(
96 new ProcessMemoryDump(new MemoryDumpSessionState())); 113 new ProcessMemoryDump(new MemoryDumpSessionState(), kDetailedDumpArgs));
97 auto mad2_1 = pmd2->CreateAllocatorDump("pmd2/mad1"); 114 auto mad2_1 = pmd2->CreateAllocatorDump("pmd2/mad1");
98 auto mad2_2 = pmd2->CreateAllocatorDump("pmd2/mad2"); 115 auto mad2_2 = pmd2->CreateAllocatorDump("pmd2/mad2");
99 pmd2->AddOwnershipEdge(mad2_1->guid(), mad2_2->guid()); 116 pmd2->AddOwnershipEdge(mad2_1->guid(), mad2_2->guid());
100 pmd2->DumpHeapUsage(metrics_by_context, overhead, "pmd2/heap_dump1"); 117 pmd2->DumpHeapUsage(metrics_by_context, overhead, "pmd2/heap_dump1");
101 pmd2->DumpHeapUsage(metrics_by_context, overhead, "pmd2/heap_dump2"); 118 pmd2->DumpHeapUsage(metrics_by_context, overhead, "pmd2/heap_dump2");
102 119
103 MemoryAllocatorDumpGuid shared_mad_guid1(1); 120 MemoryAllocatorDumpGuid shared_mad_guid1(1);
104 MemoryAllocatorDumpGuid shared_mad_guid2(2); 121 MemoryAllocatorDumpGuid shared_mad_guid2(2);
105 auto shared_mad1 = pmd2->CreateSharedGlobalAllocatorDump(shared_mad_guid1); 122 auto shared_mad1 = pmd2->CreateSharedGlobalAllocatorDump(shared_mad_guid1);
106 auto shared_mad2 = 123 auto shared_mad2 =
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 ASSERT_TRUE(GetHeapDump(*pmd1, "pmd2/heap_dump1") != nullptr); 158 ASSERT_TRUE(GetHeapDump(*pmd1, "pmd2/heap_dump1") != nullptr);
142 ASSERT_TRUE(GetHeapDump(*pmd1, "pmd2/heap_dump2") != nullptr); 159 ASSERT_TRUE(GetHeapDump(*pmd1, "pmd2/heap_dump2") != nullptr);
143 160
144 // Check that calling AsValueInto() doesn't cause a crash. 161 // Check that calling AsValueInto() doesn't cause a crash.
145 traced_value.reset(new TracedValue); 162 traced_value.reset(new TracedValue);
146 pmd1->AsValueInto(traced_value.get()); 163 pmd1->AsValueInto(traced_value.get());
147 164
148 pmd1.reset(); 165 pmd1.reset();
149 } 166 }
150 167
151 TEST(ProcessMemoryDumpTest, Suballocations) { 168 TEST_F(ProcessMemoryDumpTest, Suballocations) {
152 std::unique_ptr<ProcessMemoryDump> pmd(new ProcessMemoryDump(nullptr)); 169 std::unique_ptr<ProcessMemoryDump> pmd(
170 new ProcessMemoryDump(nullptr, kDetailedDumpArgs));
153 const std::string allocator_dump_name = "fakealloc/allocated_objects"; 171 const std::string allocator_dump_name = "fakealloc/allocated_objects";
154 pmd->CreateAllocatorDump(allocator_dump_name); 172 pmd->CreateAllocatorDump(allocator_dump_name);
155 173
156 // Create one allocation with an auto-assigned guid and mark it as a 174 // Create one allocation with an auto-assigned guid and mark it as a
157 // suballocation of "fakealloc/allocated_objects". 175 // suballocation of "fakealloc/allocated_objects".
158 auto pic1_dump = pmd->CreateAllocatorDump("picturemanager/picture1"); 176 auto pic1_dump = pmd->CreateAllocatorDump("picturemanager/picture1");
159 pmd->AddSuballocation(pic1_dump->guid(), allocator_dump_name); 177 pmd->AddSuballocation(pic1_dump->guid(), allocator_dump_name);
160 178
161 // Same here, but this time create an allocation with an explicit guid. 179 // Same here, but this time create an allocation with an explicit guid.
162 auto pic2_dump = pmd->CreateAllocatorDump("picturemanager/picture2", 180 auto pic2_dump = pmd->CreateAllocatorDump("picturemanager/picture2",
(...skipping 22 matching lines...) Expand all
185 ASSERT_TRUE(found_edge[0]); 203 ASSERT_TRUE(found_edge[0]);
186 ASSERT_TRUE(found_edge[1]); 204 ASSERT_TRUE(found_edge[1]);
187 205
188 // Check that calling AsValueInto() doesn't cause a crash. 206 // Check that calling AsValueInto() doesn't cause a crash.
189 std::unique_ptr<TracedValue> traced_value(new TracedValue); 207 std::unique_ptr<TracedValue> traced_value(new TracedValue);
190 pmd->AsValueInto(traced_value.get()); 208 pmd->AsValueInto(traced_value.get());
191 209
192 pmd.reset(); 210 pmd.reset();
193 } 211 }
194 212
195 TEST(ProcessMemoryDumpTest, GlobalAllocatorDumpTest) { 213 TEST_F(ProcessMemoryDumpTest, GlobalAllocatorDumpTest) {
196 std::unique_ptr<ProcessMemoryDump> pmd(new ProcessMemoryDump(nullptr)); 214 std::unique_ptr<ProcessMemoryDump> pmd(
215 new ProcessMemoryDump(nullptr, kDetailedDumpArgs));
197 MemoryAllocatorDumpGuid shared_mad_guid(1); 216 MemoryAllocatorDumpGuid shared_mad_guid(1);
198 auto shared_mad1 = pmd->CreateWeakSharedGlobalAllocatorDump(shared_mad_guid); 217 auto shared_mad1 = pmd->CreateWeakSharedGlobalAllocatorDump(shared_mad_guid);
199 ASSERT_EQ(shared_mad_guid, shared_mad1->guid()); 218 ASSERT_EQ(shared_mad_guid, shared_mad1->guid());
200 ASSERT_EQ(MemoryAllocatorDump::Flags::WEAK, shared_mad1->flags()); 219 ASSERT_EQ(MemoryAllocatorDump::Flags::WEAK, shared_mad1->flags());
201 220
202 auto shared_mad2 = pmd->GetSharedGlobalAllocatorDump(shared_mad_guid); 221 auto shared_mad2 = pmd->GetSharedGlobalAllocatorDump(shared_mad_guid);
203 ASSERT_EQ(shared_mad1, shared_mad2); 222 ASSERT_EQ(shared_mad1, shared_mad2);
204 ASSERT_EQ(MemoryAllocatorDump::Flags::WEAK, shared_mad1->flags()); 223 ASSERT_EQ(MemoryAllocatorDump::Flags::WEAK, shared_mad1->flags());
205 224
206 auto shared_mad3 = pmd->CreateWeakSharedGlobalAllocatorDump(shared_mad_guid); 225 auto shared_mad3 = pmd->CreateWeakSharedGlobalAllocatorDump(shared_mad_guid);
207 ASSERT_EQ(shared_mad1, shared_mad3); 226 ASSERT_EQ(shared_mad1, shared_mad3);
208 ASSERT_EQ(MemoryAllocatorDump::Flags::WEAK, shared_mad1->flags()); 227 ASSERT_EQ(MemoryAllocatorDump::Flags::WEAK, shared_mad1->flags());
209 228
210 auto shared_mad4 = pmd->CreateSharedGlobalAllocatorDump(shared_mad_guid); 229 auto shared_mad4 = pmd->CreateSharedGlobalAllocatorDump(shared_mad_guid);
211 ASSERT_EQ(shared_mad1, shared_mad4); 230 ASSERT_EQ(shared_mad1, shared_mad4);
212 ASSERT_EQ(MemoryAllocatorDump::Flags::DEFAULT, shared_mad1->flags()); 231 ASSERT_EQ(MemoryAllocatorDump::Flags::DEFAULT, shared_mad1->flags());
213 232
214 auto shared_mad5 = pmd->CreateWeakSharedGlobalAllocatorDump(shared_mad_guid); 233 auto shared_mad5 = pmd->CreateWeakSharedGlobalAllocatorDump(shared_mad_guid);
215 ASSERT_EQ(shared_mad1, shared_mad5); 234 ASSERT_EQ(shared_mad1, shared_mad5);
216 ASSERT_EQ(MemoryAllocatorDump::Flags::DEFAULT, shared_mad1->flags()); 235 ASSERT_EQ(MemoryAllocatorDump::Flags::DEFAULT, shared_mad1->flags());
217 } 236 }
218 237
238 TEST_F(ProcessMemoryDumpTest, BackgroundModeTest) {
239 MemoryDumpArgs background_args = {MemoryDumpLevelOfDetail::BACKGROUND};
240 std::unique_ptr<ProcessMemoryDump> pmd(
241 new ProcessMemoryDump(nullptr, background_args));
242 SetAllocatorDumpNameWhitelistForTesting(kTestDumpNameWhitelist);
243 MemoryAllocatorDump* black_hole_mad = pmd->black_hole_mad_.get();
244
245 // Invalid dump names.
246 EXPECT_EQ(black_hole_mad,
247 CreateAllocatorDumpInPMD(pmd.get(), "NotWhitelistedTestName"));
Primiano Tucci (use gerrit) 2016/06/02 20:24:04 Isn't this going to hit all those DCHECKs? I guess
ssid 2016/06/03 01:59:46 No, I had to make the test class and call AddInter
248 EXPECT_EQ(black_hole_mad,
249 CreateAllocatorDumpInPMD(pmd.get(), "NotWhitelistedTestName"));
Primiano Tucci (use gerrit) 2016/06/02 20:24:04 I think this is identical to the above?
ssid 2016/06/03 01:59:46 fixed.
250 EXPECT_EQ(black_hole_mad, CreateAllocatorDumpInPMD(pmd.get(), "TestName"));
251 EXPECT_EQ(black_hole_mad,
252 CreateAllocatorDumpInPMD(pmd.get(), "Whitelisted/Test"));
253 EXPECT_EQ(black_hole_mad,
254 CreateAllocatorDumpInPMD(pmd.get(), "Not/Whitelisted/TestName"));
255 EXPECT_EQ(black_hole_mad,
256 CreateAllocatorDumpInPMD(pmd.get(), "Whitelisted/TestName/Google"));
257 EXPECT_EQ(black_hole_mad, CreateAllocatorDumpInPMD(
258 pmd.get(), "Whitelisted/TestName/0x1a2Google"));
259 EXPECT_EQ(black_hole_mad, CreateAllocatorDumpInPMD(
260 pmd.get(), "Whitelisted/TestName/__12/Google"));
261
262 // Global dumps.
263 MemoryAllocatorDumpGuid guid(1);
264 EXPECT_EQ(black_hole_mad, pmd->CreateSharedGlobalAllocatorDump(guid));
265 EXPECT_EQ(black_hole_mad, pmd->CreateWeakSharedGlobalAllocatorDump(guid));
266 EXPECT_EQ(black_hole_mad, pmd->GetSharedGlobalAllocatorDump(guid));
267
268 // Suballocations.
269 pmd->AddSuballocation(guid, "malloc/allocated_objects");
270 EXPECT_EQ(0u, pmd->allocator_dumps_edges_.size());
271 EXPECT_EQ(0u, pmd->allocator_dumps_.size());
272
273 // Valid dump names.
274 EXPECT_NE(black_hole_mad,
275 CreateAllocatorDumpInPMD(pmd.get(), "WhitelistedTestName"));
276 EXPECT_NE(black_hole_mad,
277 CreateAllocatorDumpInPMD(pmd.get(), "Whitelisted/TestName/0xA1b2"));
278 EXPECT_NE(black_hole_mad, CreateAllocatorDumpInPMD(
279 pmd.get(), "Whitelisted/TestName_123/0xab"));
280 EXPECT_NE(black_hole_mad, CreateAllocatorDumpInPMD(
281 pmd.get(), "Whitelisted_12/0xaB/TestName"));
282
283 // GetAllocatorDump is consistent.
284 EXPECT_EQ(black_hole_mad, pmd->GetAllocatorDump("NotWhitelistedTestName"));
285 auto mad = pmd->GetAllocatorDump("WhitelistedTestName");
286 EXPECT_NE(black_hole_mad, mad);
287 }
288
219 #if defined(COUNT_RESIDENT_BYTES_SUPPORTED) 289 #if defined(COUNT_RESIDENT_BYTES_SUPPORTED)
220 TEST(ProcessMemoryDumpTest, CountResidentBytes) { 290 TEST_F(ProcessMemoryDumpTest, CountResidentBytes) {
221 const size_t page_size = ProcessMemoryDump::GetSystemPageSize(); 291 const size_t page_size = ProcessMemoryDump::GetSystemPageSize();
222 292
223 // Allocate few page of dirty memory and check if it is resident. 293 // Allocate few page of dirty memory and check if it is resident.
224 const size_t size1 = 5 * page_size; 294 const size_t size1 = 5 * page_size;
225 std::unique_ptr<char, base::AlignedFreeDeleter> memory1( 295 std::unique_ptr<char, base::AlignedFreeDeleter> memory1(
226 static_cast<char*>(base::AlignedAlloc(size1, page_size))); 296 static_cast<char*>(base::AlignedAlloc(size1, page_size)));
227 memset(memory1.get(), 0, size1); 297 memset(memory1.get(), 0, size1);
228 size_t res1 = ProcessMemoryDump::CountResidentBytes(memory1.get(), size1); 298 size_t res1 = ProcessMemoryDump::CountResidentBytes(memory1.get(), size1);
229 ASSERT_EQ(res1, size1); 299 ASSERT_EQ(res1, size1);
230 300
231 // Allocate a large memory segment (> 8Mib). 301 // Allocate a large memory segment (> 8Mib).
232 const size_t kVeryLargeMemorySize = 15 * 1024 * 1024; 302 const size_t kVeryLargeMemorySize = 15 * 1024 * 1024;
233 std::unique_ptr<char, base::AlignedFreeDeleter> memory2( 303 std::unique_ptr<char, base::AlignedFreeDeleter> memory2(
234 static_cast<char*>(base::AlignedAlloc(kVeryLargeMemorySize, page_size))); 304 static_cast<char*>(base::AlignedAlloc(kVeryLargeMemorySize, page_size)));
235 memset(memory2.get(), 0, kVeryLargeMemorySize); 305 memset(memory2.get(), 0, kVeryLargeMemorySize);
236 size_t res2 = ProcessMemoryDump::CountResidentBytes(memory2.get(), 306 size_t res2 = ProcessMemoryDump::CountResidentBytes(memory2.get(),
237 kVeryLargeMemorySize); 307 kVeryLargeMemorySize);
238 ASSERT_EQ(res2, kVeryLargeMemorySize); 308 ASSERT_EQ(res2, kVeryLargeMemorySize);
239 } 309 }
240 #endif // defined(COUNT_RESIDENT_BYTES_SUPPORTED) 310 #endif // defined(COUNT_RESIDENT_BYTES_SUPPORTED)
241 311
242 } // namespace trace_event 312 } // namespace trace_event
243 } // namespace base 313 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698