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

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

Issue 1289793007: Allow unregistering MemoryDumpProviders during dump (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Do not (un)register with tracing enabled Created 5 years, 4 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/memory_dump_manager.h" 5 #include "base/trace_event/memory_dump_manager.h"
6 6
7 #include "base/bind_helpers.h" 7 #include "base/bind_helpers.h"
8 #include "base/memory/scoped_vector.h" 8 #include "base/memory/scoped_vector.h"
9 #include "base/message_loop/message_loop.h" 9 #include "base/message_loop/message_loop.h"
10 #include "base/run_loop.h" 10 #include "base/run_loop.h"
11 #include "base/test/test_io_thread.h"
11 #include "base/thread_task_runner_handle.h" 12 #include "base/thread_task_runner_handle.h"
12 #include "base/threading/thread.h" 13 #include "base/threading/thread.h"
13 #include "base/trace_event/memory_dump_provider.h" 14 #include "base/trace_event/memory_dump_provider.h"
14 #include "base/trace_event/process_memory_dump.h" 15 #include "base/trace_event/process_memory_dump.h"
15 #include "testing/gmock/include/gmock/gmock.h" 16 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gtest/include/gtest/gtest.h" 17 #include "testing/gtest/include/gtest/gtest.h"
17 18
18 using testing::_; 19 using testing::_;
20 using testing::AtLeast;
19 using testing::Between; 21 using testing::Between;
20 using testing::Invoke; 22 using testing::Invoke;
21 using testing::Return; 23 using testing::Return;
22 24
23 namespace base { 25 namespace base {
24 namespace trace_event { 26 namespace trace_event {
25 namespace { 27 namespace {
26 MemoryDumpArgs high_detail_args = {MemoryDumpArgs::LevelOfDetail::HIGH}; 28 MemoryDumpArgs high_detail_args = {MemoryDumpArgs::LevelOfDetail::HIGH};
27 MemoryDumpArgs low_detail_args = {MemoryDumpArgs::LevelOfDetail::LOW}; 29 MemoryDumpArgs low_detail_args = {MemoryDumpArgs::LevelOfDetail::LOW};
28 } 30 }
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 // Enable both mdp1 and mdp2. 277 // Enable both mdp1 and mdp2.
276 mdm_->RegisterDumpProvider(&mdp1); 278 mdm_->RegisterDumpProvider(&mdp1);
277 EnableTracing(kTraceCategory); 279 EnableTracing(kTraceCategory);
278 EXPECT_CALL(mdp1, OnMemoryDump(_, _)).Times(1).WillRepeatedly(Return(true)); 280 EXPECT_CALL(mdp1, OnMemoryDump(_, _)).Times(1).WillRepeatedly(Return(true));
279 EXPECT_CALL(mdp2, OnMemoryDump(_, _)).Times(1).WillRepeatedly(Return(true)); 281 EXPECT_CALL(mdp2, OnMemoryDump(_, _)).Times(1).WillRepeatedly(Return(true));
280 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, 282 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED,
281 high_detail_args); 283 high_detail_args);
282 DisableTracing(); 284 DisableTracing();
283 } 285 }
284 286
287 // Even though internally, after unregistration a dump provider is retained in
Primiano Tucci (use gerrit) 2015/08/21 09:00:31 This comment seems to describe the internal implem
Ruud van Asseldonk 2015/08/21 10:51:40 Done.
288 // the set until the next dump, this should not affect dump behavior.
289 TEST_F(MemoryDumpManagerTest, RegistrationOrder) {
290 MockDumpProvider mdp;
291 EnableTracing(kTraceCategory);
292
293 mdm_->RegisterDumpProvider(&mdp);
294
295 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(1);
296 EnableTracing(kTraceCategory);
297 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED,
298 high_detail_args);
299 DisableTracing();
300
301 mdm_->UnregisterDumpProvider(&mdp);
302
303 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0);
304 EnableTracing(kTraceCategory);
305 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED,
306 high_detail_args);
307 DisableTracing();
308
309 mdm_->RegisterDumpProvider(&mdp);
310 mdm_->UnregisterDumpProvider(&mdp);
311
312 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0);
313 EnableTracing(kTraceCategory);
314 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED,
315 high_detail_args);
316 DisableTracing();
317
318 mdm_->RegisterDumpProvider(&mdp);
319 mdm_->UnregisterDumpProvider(&mdp);
320 mdm_->RegisterDumpProvider(&mdp);
321
322 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(1);
323 EnableTracing(kTraceCategory);
324 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED,
325 high_detail_args);
326 DisableTracing();
327 }
328
285 // Checks that the MemoryDumpManager respects the thread affinity when a 329 // Checks that the MemoryDumpManager respects the thread affinity when a
286 // MemoryDumpProvider specifies a task_runner(). The test starts creating 8 330 // MemoryDumpProvider specifies a task_runner(). The test starts creating 8
287 // threads and registering a MemoryDumpProvider on each of them. At each 331 // threads and registering a MemoryDumpProvider on each of them. At each
288 // iteration, one thread is removed, to check the live unregistration logic. 332 // iteration, one thread is removed, to check the live unregistration logic.
289 TEST_F(MemoryDumpManagerTest, RespectTaskRunnerAffinity) { 333 TEST_F(MemoryDumpManagerTest, RespectTaskRunnerAffinity) {
290 const uint32 kNumInitialThreads = 8; 334 const uint32 kNumInitialThreads = 8;
291 335
292 ScopedVector<Thread> threads; 336 ScopedVector<Thread> threads;
293 ScopedVector<MockDumpProvider> mdps; 337 ScopedVector<MockDumpProvider> mdps;
294 338
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 .WillRepeatedly(Return(true)); 470 .WillRepeatedly(Return(true));
427 471
428 for (int i = 0; i < 4; i++) { 472 for (int i = 0; i < 4; i++) {
429 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, 473 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED,
430 high_detail_args); 474 high_detail_args);
431 } 475 }
432 476
433 DisableTracing(); 477 DisableTracing();
434 } 478 }
435 479
480 // Verify that the dump does not abort when unregistering a provider during dump
481 // from a different thread than the dumping thread.
482 TEST_F(MemoryDumpManagerTest, UnregisterDumperFromThreadWhileDumping) {
483 ScopedVector<TestIOThread> threads;
484 ScopedVector<MockDumpProvider> mdps;
485
486 for (int i = 0; i < 2; i++) {
487 threads.push_back(new TestIOThread(TestIOThread::kAutoStart));
488 mdps.push_back(new MockDumpProvider(threads.back()->task_runner()));
489 mdm_->RegisterDumpProvider(mdps.back(), threads.back()->task_runner());
490 }
491
492 int on_memory_dump_calls = 0;
Primiano Tucci (use gerrit) 2015/08/21 09:00:31 nit: +count (i.e. on_memory_dump_call_count)
Ruud van Asseldonk 2015/08/21 10:51:40 Done.
493 RunLoop run_loop;
494
495 // When OnMemoryDump is called on either of the dump providers, it will
496 // unregister the other one.
497 for (MockDumpProvider* mdp : mdps) {
498 int other_idx = (mdps.front() == mdp);
499 auto on_dump = [&, other_idx](const MemoryDumpArgs& args,
Primiano Tucci (use gerrit) 2015/08/21 09:00:31 nit: on_memory_dump Also, make sure you run git c
Ruud van Asseldonk 2015/08/21 10:51:40 This is how git cl format formats it.
500 ProcessMemoryDump* pmd) {
501
502 threads[other_idx]->PostTaskAndWait(
503 FROM_HERE, base::Bind(&MemoryDumpManager::UnregisterDumpProvider,
504 base::Unretained(&*mdm_), mdps[other_idx]));
505 on_memory_dump_calls++;
506 return true;
507 };
508
509 // OnMemoryDump is called once for the provider that dumps first, and zero
510 // times for the other provider.
511 EXPECT_CALL(*mdp, OnMemoryDump(_, _))
512 .Times(AtLeast(0))
Primiano Tucci (use gerrit) 2015/08/21 09:00:31 I'd probably make this AtMost(1)
Ruud van Asseldonk 2015/08/21 10:51:40 Done.
513 .WillOnce(Invoke(on_dump));
514 }
515
516 last_callback_success_ = true;
517 MemoryDumpCallback callback =
518 Bind(&MemoryDumpManagerTest::DumpCallbackAdapter, Unretained(this),
519 MessageLoop::current()->task_runner(), run_loop.QuitClosure());
520
521 EnableTracing(kTraceCategory);
522 MemoryDumpRequestArgs request_args = {0, MemoryDumpType::EXPLICITLY_TRIGGERED,
523 high_detail_args};
524 mdm_->CreateProcessDump(request_args, callback);
525
526 run_loop.Run();
527
528 ASSERT_EQ(1, on_memory_dump_calls);
529 ASSERT_EQ(true, last_callback_success_);
530
531 DisableTracing();
532
533 // Thread destructors will stop the threads.
Primiano Tucci (use gerrit) 2015/08/21 09:00:31 I'd probably remove this comment. Should be clear
Ruud van Asseldonk 2015/08/21 10:51:40 Done.
534 }
535
436 // Ensures that a NACK callback is invoked if RequestGlobalDump is called when 536 // Ensures that a NACK callback is invoked if RequestGlobalDump is called when
437 // tracing is not enabled. 537 // tracing is not enabled.
438 TEST_F(MemoryDumpManagerTest, CallbackCalledOnFailure) { 538 TEST_F(MemoryDumpManagerTest, CallbackCalledOnFailure) {
439 MockDumpProvider mdp1; 539 MockDumpProvider mdp1;
440 540
441 mdm_->RegisterDumpProvider(&mdp1); 541 mdm_->RegisterDumpProvider(&mdp1);
442 EXPECT_CALL(mdp1, OnMemoryDump(_, _)).Times(0); 542 EXPECT_CALL(mdp1, OnMemoryDump(_, _)).Times(0);
443 543
444 last_callback_success_ = true; 544 last_callback_success_ = true;
445 { 545 {
446 RunLoop run_loop; 546 RunLoop run_loop;
447 MemoryDumpCallback callback = 547 MemoryDumpCallback callback =
448 Bind(&MemoryDumpManagerTest::DumpCallbackAdapter, Unretained(this), 548 Bind(&MemoryDumpManagerTest::DumpCallbackAdapter, Unretained(this),
449 MessageLoop::current()->task_runner(), run_loop.QuitClosure()); 549 MessageLoop::current()->task_runner(), run_loop.QuitClosure());
450 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, 550 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED,
451 high_detail_args, callback); 551 high_detail_args, callback);
452 run_loop.Run(); 552 run_loop.Run();
453 } 553 }
454 EXPECT_FALSE(last_callback_success_); 554 EXPECT_FALSE(last_callback_success_);
455 } 555 }
456 556
457 } // namespace trace_event 557 } // namespace trace_event
458 } // namespace base 558 } // namespace base
OLDNEW
« base/trace_event/memory_dump_manager.cc ('K') | « base/trace_event/memory_dump_manager.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698