| 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/memory_dump_manager.h" | 5 #include "base/trace_event/memory_dump_manager.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <memory> | 9 #include <memory> |
| 10 #include <utility> | 10 #include <utility> |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 109 base::WaitableEvent event(WaitableEvent::ResetPolicy::MANUAL, | 109 base::WaitableEvent event(WaitableEvent::ResetPolicy::MANUAL, |
| 110 WaitableEvent::InitialState::NOT_SIGNALED); | 110 WaitableEvent::InitialState::NOT_SIGNALED); |
| 111 task_runner->PostTask(from_here, std::move(task)); | 111 task_runner->PostTask(from_here, std::move(task)); |
| 112 task_runner->PostTask(FROM_HERE, base::BindOnce(&WaitableEvent::Signal, | 112 task_runner->PostTask(FROM_HERE, base::BindOnce(&WaitableEvent::Signal, |
| 113 base::Unretained(&event))); | 113 base::Unretained(&event))); |
| 114 // The SequencedTaskRunner guarantees that |event| will only be signaled after | 114 // The SequencedTaskRunner guarantees that |event| will only be signaled after |
| 115 // |task| is executed. | 115 // |task| is executed. |
| 116 event.Wait(); | 116 event.Wait(); |
| 117 } | 117 } |
| 118 | 118 |
| 119 // Adapts a ProcessMemoryDumpCallback into a GlobalMemoryDumpCallback by |
| 120 // trimming off the result argument and calling the global callback. |
| 121 // TODO (fmeawad): we should keep the results for verification, but currently |
| 122 // all results are empty. |
| 123 void ProcessDumpCallbackAdapter( |
| 124 GlobalMemoryDumpCallback callback, |
| 125 uint64_t dump_guid, |
| 126 bool success, |
| 127 const base::Optional<base::trace_event::MemoryDumpCallbackResult>&) { |
| 128 callback.Run(dump_guid, success); |
| 129 } |
| 130 |
| 119 // Testing MemoryDumpManagerDelegate which, by default, short-circuits dump | 131 // Testing MemoryDumpManagerDelegate which, by default, short-circuits dump |
| 120 // requests locally to the MemoryDumpManager instead of performing IPC dances. | 132 // requests locally to the MemoryDumpManager instead of performing IPC dances. |
| 121 class MemoryDumpManagerDelegateForTesting : public MemoryDumpManagerDelegate { | 133 class MemoryDumpManagerDelegateForTesting : public MemoryDumpManagerDelegate { |
| 122 public: | 134 public: |
| 123 MemoryDumpManagerDelegateForTesting(bool is_coordinator) | 135 MemoryDumpManagerDelegateForTesting(bool is_coordinator) |
| 124 : is_coordinator_(is_coordinator) { | 136 : is_coordinator_(is_coordinator) { |
| 125 ON_CALL(*this, RequestGlobalMemoryDump(_, _)) | 137 ON_CALL(*this, RequestGlobalMemoryDump(_, _)) |
| 126 .WillByDefault(Invoke( | 138 .WillByDefault(Invoke([this](const MemoryDumpRequestArgs& args, |
| 127 this, &MemoryDumpManagerDelegateForTesting::CreateProcessDump)); | 139 const GlobalMemoryDumpCallback& callback) { |
| 140 ProcessMemoryDumpCallback process_callback = |
| 141 Bind(&ProcessDumpCallbackAdapter, callback); |
| 142 CreateProcessDump(args, process_callback); |
| 143 })); |
| 128 } | 144 } |
| 129 | 145 |
| 130 MOCK_METHOD2(RequestGlobalMemoryDump, | 146 MOCK_METHOD2(RequestGlobalMemoryDump, |
| 131 void(const MemoryDumpRequestArgs& args, | 147 void(const MemoryDumpRequestArgs& args, |
| 132 const MemoryDumpCallback& callback)); | 148 const GlobalMemoryDumpCallback& callback)); |
| 133 | 149 |
| 134 bool IsCoordinator() const override { return is_coordinator_; } | 150 bool IsCoordinator() const override { return is_coordinator_; } |
| 135 | 151 |
| 136 // Promote the CreateProcessDump to public so it can be used by test fixtures. | 152 // Promote the CreateProcessDump to public so it can be used by test fixtures. |
| 137 using MemoryDumpManagerDelegate::CreateProcessDump; | 153 using MemoryDumpManagerDelegate::CreateProcessDump; |
| 138 | 154 |
| 139 private: | 155 private: |
| 140 bool is_coordinator_; | 156 bool is_coordinator_; |
| 141 }; | 157 }; |
| 142 | 158 |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 227 } | 243 } |
| 228 | 244 |
| 229 void TearDown() override { | 245 void TearDown() override { |
| 230 MemoryDumpManager::SetInstanceForTesting(nullptr); | 246 MemoryDumpManager::SetInstanceForTesting(nullptr); |
| 231 delegate_ = nullptr; | 247 delegate_ = nullptr; |
| 232 mdm_.reset(); | 248 mdm_.reset(); |
| 233 message_loop_.reset(); | 249 message_loop_.reset(); |
| 234 TraceLog::DeleteForTesting(); | 250 TraceLog::DeleteForTesting(); |
| 235 } | 251 } |
| 236 | 252 |
| 237 // Turns a Closure into a MemoryDumpCallback, keeping track of the callback | 253 // Turns a Closure into a GlobalMemoryDumpCallback, keeping track of the |
| 238 // result and taking care of posting the closure on the correct task runner. | 254 // callback result and taking care of posting the closure on the correct task |
| 239 void DumpCallbackAdapter(scoped_refptr<SingleThreadTaskRunner> task_runner, | 255 // runner. |
| 240 Closure closure, | 256 void GlobalDumpCallbackAdapter( |
| 241 uint64_t dump_guid, | 257 scoped_refptr<SingleThreadTaskRunner> task_runner, |
| 242 bool success) { | 258 Closure closure, |
| 259 uint64_t dump_guid, |
| 260 bool success) { |
| 243 last_callback_success_ = success; | 261 last_callback_success_ = success; |
| 244 task_runner->PostTask(FROM_HERE, closure); | 262 task_runner->PostTask(FROM_HERE, closure); |
| 245 } | 263 } |
| 246 | 264 |
| 247 protected: | 265 protected: |
| 248 void InitializeMemoryDumpManager(bool is_coordinator) { | 266 void InitializeMemoryDumpManager(bool is_coordinator) { |
| 249 mdm_->set_dumper_registrations_ignored_for_testing(true); | 267 mdm_->set_dumper_registrations_ignored_for_testing(true); |
| 250 delegate_ = new MemoryDumpManagerDelegateForTesting(is_coordinator); | 268 delegate_ = new MemoryDumpManagerDelegateForTesting(is_coordinator); |
| 251 mdm_->Initialize(base::WrapUnique(delegate_)); | 269 mdm_->Initialize(base::WrapUnique(delegate_)); |
| 252 } | 270 } |
| 253 | 271 |
| 254 void RequestGlobalDumpAndWait(MemoryDumpType dump_type, | 272 void RequestGlobalDumpAndWait(MemoryDumpType dump_type, |
| 255 MemoryDumpLevelOfDetail level_of_detail) { | 273 MemoryDumpLevelOfDetail level_of_detail) { |
| 256 RunLoop run_loop; | 274 RunLoop run_loop; |
| 257 MemoryDumpCallback callback = | 275 GlobalMemoryDumpCallback callback = Bind( |
| 258 Bind(&MemoryDumpManagerTest::DumpCallbackAdapter, Unretained(this), | 276 &MemoryDumpManagerTest::GlobalDumpCallbackAdapter, Unretained(this), |
| 259 ThreadTaskRunnerHandle::Get(), run_loop.QuitClosure()); | 277 ThreadTaskRunnerHandle::Get(), run_loop.QuitClosure()); |
| 260 mdm_->RequestGlobalDump(dump_type, level_of_detail, callback); | 278 mdm_->RequestGlobalDump(dump_type, level_of_detail, callback); |
| 261 run_loop.Run(); | 279 run_loop.Run(); |
| 262 } | 280 } |
| 263 | 281 |
| 264 void EnableTracingWithLegacyCategories(const char* category) { | 282 void EnableTracingWithLegacyCategories(const char* category) { |
| 265 TraceLog::GetInstance()->SetEnabled(TraceConfig(category, ""), | 283 TraceLog::GetInstance()->SetEnabled(TraceConfig(category, ""), |
| 266 TraceLog::RECORDING_MODE); | 284 TraceLog::RECORDING_MODE); |
| 267 } | 285 } |
| 268 | 286 |
| 269 void EnableTracingWithTraceConfig(const std::string& trace_config) { | 287 void EnableTracingWithTraceConfig(const std::string& trace_config) { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 306 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0); | 324 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0); |
| 307 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, | 325 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 308 MemoryDumpLevelOfDetail::DETAILED); | 326 MemoryDumpLevelOfDetail::DETAILED); |
| 309 DisableTracing(); | 327 DisableTracing(); |
| 310 | 328 |
| 311 // Now repeat enabling the memory category and check that the dumper is | 329 // Now repeat enabling the memory category and check that the dumper is |
| 312 // invoked this time. | 330 // invoked this time. |
| 313 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); | 331 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
| 314 EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)).Times(3); | 332 EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)).Times(3); |
| 315 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(3).WillRepeatedly(Return(true)); | 333 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(3).WillRepeatedly(Return(true)); |
| 316 for (int i = 0; i < 3; ++i) | 334 for (int i = 0; i < 3; ++i) { |
| 317 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, | 335 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 318 MemoryDumpLevelOfDetail::DETAILED); | 336 MemoryDumpLevelOfDetail::DETAILED); |
| 337 } |
| 319 DisableTracing(); | 338 DisableTracing(); |
| 320 | 339 |
| 321 mdm_->UnregisterDumpProvider(&mdp); | 340 mdm_->UnregisterDumpProvider(&mdp); |
| 322 | 341 |
| 323 // Finally check the unregister logic: the delegate will be invoked but not | 342 // Finally check the unregister logic: the delegate will be invoked but not |
| 324 // the dump provider, as it has been unregistered. | 343 // the dump provider, as it has been unregistered. |
| 325 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); | 344 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
| 326 EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)).Times(3); | 345 EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)).Times(3); |
| 327 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0); | 346 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0); |
| 328 | 347 |
| (...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 973 const int kHeavyDumpPeriodMs = kHeavyDumpRate * kLightDumpPeriodMs; | 992 const int kHeavyDumpPeriodMs = kHeavyDumpRate * kLightDumpPeriodMs; |
| 974 // The expected sequence with light=1ms, heavy=5ms is H,L,L,L,L,H,... | 993 // The expected sequence with light=1ms, heavy=5ms is H,L,L,L,L,H,... |
| 975 testing::InSequence sequence; | 994 testing::InSequence sequence; |
| 976 EXPECT_CALL(delegate, RequestGlobalMemoryDump(IsDetailedDump(), _)); | 995 EXPECT_CALL(delegate, RequestGlobalMemoryDump(IsDetailedDump(), _)); |
| 977 EXPECT_CALL(delegate, RequestGlobalMemoryDump(IsLightDump(), _)) | 996 EXPECT_CALL(delegate, RequestGlobalMemoryDump(IsLightDump(), _)) |
| 978 .Times(kHeavyDumpRate - 1); | 997 .Times(kHeavyDumpRate - 1); |
| 979 EXPECT_CALL(delegate, RequestGlobalMemoryDump(IsDetailedDump(), _)); | 998 EXPECT_CALL(delegate, RequestGlobalMemoryDump(IsDetailedDump(), _)); |
| 980 EXPECT_CALL(delegate, RequestGlobalMemoryDump(IsLightDump(), _)) | 999 EXPECT_CALL(delegate, RequestGlobalMemoryDump(IsLightDump(), _)) |
| 981 .Times(kHeavyDumpRate - 2); | 1000 .Times(kHeavyDumpRate - 2); |
| 982 EXPECT_CALL(delegate, RequestGlobalMemoryDump(IsLightDump(), _)) | 1001 EXPECT_CALL(delegate, RequestGlobalMemoryDump(IsLightDump(), _)) |
| 983 .WillOnce(Invoke( | 1002 .WillOnce(Invoke([test_task_runner, quit_closure]( |
| 984 [test_task_runner, quit_closure](const MemoryDumpRequestArgs& args, | 1003 const MemoryDumpRequestArgs& args, |
| 985 const MemoryDumpCallback& callback) { | 1004 const GlobalMemoryDumpCallback& callback) { |
| 986 test_task_runner->PostTask(FROM_HERE, quit_closure); | 1005 test_task_runner->PostTask(FROM_HERE, quit_closure); |
| 987 })); | 1006 })); |
| 988 | 1007 |
| 989 // Swallow all the final spurious calls until tracing gets disabled. | 1008 // Swallow all the final spurious calls until tracing gets disabled. |
| 990 EXPECT_CALL(delegate, RequestGlobalMemoryDump(_, _)).Times(AnyNumber()); | 1009 EXPECT_CALL(delegate, RequestGlobalMemoryDump(_, _)).Times(AnyNumber()); |
| 991 | 1010 |
| 992 EnableTracingWithTraceConfig( | 1011 EnableTracingWithTraceConfig( |
| 993 TraceConfigMemoryTestUtil::GetTraceConfig_PeriodicTriggers( | 1012 TraceConfigMemoryTestUtil::GetTraceConfig_PeriodicTriggers( |
| 994 kLightDumpPeriodMs, kHeavyDumpPeriodMs)); | 1013 kLightDumpPeriodMs, kHeavyDumpPeriodMs)); |
| 995 run_loop.Run(); | 1014 run_loop.Run(); |
| 996 DisableTracing(); | 1015 DisableTracing(); |
| 997 } | 1016 } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1035 // MemoryDumpManager.dump_thread_ has been shut down. | 1054 // MemoryDumpManager.dump_thread_ has been shut down. |
| 1036 return true; | 1055 return true; |
| 1037 })); | 1056 })); |
| 1038 | 1057 |
| 1039 // |unbound_mdp| should never be invoked because the thread for unbound dump | 1058 // |unbound_mdp| should never be invoked because the thread for unbound dump |
| 1040 // providers has been shutdown in the meanwhile. | 1059 // providers has been shutdown in the meanwhile. |
| 1041 EXPECT_CALL(unbound_mdp, OnMemoryDump(_, _)).Times(0); | 1060 EXPECT_CALL(unbound_mdp, OnMemoryDump(_, _)).Times(0); |
| 1042 | 1061 |
| 1043 last_callback_success_ = true; | 1062 last_callback_success_ = true; |
| 1044 RunLoop run_loop; | 1063 RunLoop run_loop; |
| 1045 MemoryDumpCallback callback = | 1064 GlobalMemoryDumpCallback callback = |
| 1046 Bind(&MemoryDumpManagerTest::DumpCallbackAdapter, Unretained(this), | 1065 Bind(&MemoryDumpManagerTest::GlobalDumpCallbackAdapter, Unretained(this), |
| 1047 ThreadTaskRunnerHandle::Get(), run_loop.QuitClosure()); | 1066 ThreadTaskRunnerHandle::Get(), run_loop.QuitClosure()); |
| 1048 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | 1067 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 1049 MemoryDumpLevelOfDetail::DETAILED, callback); | 1068 MemoryDumpLevelOfDetail::DETAILED, callback); |
| 1050 DisableTracing(); | 1069 DisableTracing(); |
| 1051 tracing_disabled_event.Signal(); | 1070 tracing_disabled_event.Signal(); |
| 1052 run_loop.Run(); | 1071 run_loop.Run(); |
| 1053 | 1072 |
| 1054 EXPECT_FALSE(last_callback_success_); | 1073 EXPECT_FALSE(last_callback_success_); |
| 1055 } | 1074 } |
| 1056 | 1075 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1067 | 1086 |
| 1068 // Create both same-thread MDP and another MDP with dedicated thread | 1087 // Create both same-thread MDP and another MDP with dedicated thread |
| 1069 MockMemoryDumpProvider mdp1; | 1088 MockMemoryDumpProvider mdp1; |
| 1070 RegisterDumpProvider(&mdp1, nullptr); | 1089 RegisterDumpProvider(&mdp1, nullptr); |
| 1071 MockMemoryDumpProvider mdp2; | 1090 MockMemoryDumpProvider mdp2; |
| 1072 RegisterDumpProvider(&mdp2, mdp_thread->task_runner(), kDefaultOptions); | 1091 RegisterDumpProvider(&mdp2, mdp_thread->task_runner(), kDefaultOptions); |
| 1073 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); | 1092 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
| 1074 | 1093 |
| 1075 EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)) | 1094 EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)) |
| 1076 .WillOnce(Invoke([this](const MemoryDumpRequestArgs& args, | 1095 .WillOnce(Invoke([this](const MemoryDumpRequestArgs& args, |
| 1077 const MemoryDumpCallback& callback) { | 1096 const GlobalMemoryDumpCallback& callback) { |
| 1078 DisableTracing(); | 1097 DisableTracing(); |
| 1079 delegate_->CreateProcessDump(args, callback); | 1098 ProcessMemoryDumpCallback process_callback = |
| 1099 Bind(&ProcessDumpCallbackAdapter, callback); |
| 1100 delegate_->CreateProcessDump(args, process_callback); |
| 1080 })); | 1101 })); |
| 1081 | 1102 |
| 1082 // If tracing is disabled for current session CreateProcessDump() should NOT | 1103 // If tracing is disabled for current session CreateProcessDump() should NOT |
| 1083 // request dumps from providers. Real-world regression: crbug.com/600570 . | 1104 // request dumps from providers. Real-world regression: crbug.com/600570 . |
| 1084 EXPECT_CALL(mdp1, OnMemoryDump(_, _)).Times(0); | 1105 EXPECT_CALL(mdp1, OnMemoryDump(_, _)).Times(0); |
| 1085 EXPECT_CALL(mdp2, OnMemoryDump(_, _)).Times(0); | 1106 EXPECT_CALL(mdp2, OnMemoryDump(_, _)).Times(0); |
| 1086 | 1107 |
| 1087 last_callback_success_ = true; | 1108 last_callback_success_ = true; |
| 1088 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, | 1109 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 1089 MemoryDumpLevelOfDetail::DETAILED); | 1110 MemoryDumpLevelOfDetail::DETAILED); |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1237 InitializeMemoryDumpManager(true /* is_coordinator */); | 1258 InitializeMemoryDumpManager(true /* is_coordinator */); |
| 1238 | 1259 |
| 1239 RunLoop run_loop; | 1260 RunLoop run_loop; |
| 1240 auto test_task_runner = ThreadTaskRunnerHandle::Get(); | 1261 auto test_task_runner = ThreadTaskRunnerHandle::Get(); |
| 1241 auto quit_closure = run_loop.QuitClosure(); | 1262 auto quit_closure = run_loop.QuitClosure(); |
| 1242 | 1263 |
| 1243 testing::InSequence sequence; | 1264 testing::InSequence sequence; |
| 1244 EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(IsBackgroundDump(), _)) | 1265 EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(IsBackgroundDump(), _)) |
| 1245 .Times(5); | 1266 .Times(5); |
| 1246 EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(IsBackgroundDump(), _)) | 1267 EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(IsBackgroundDump(), _)) |
| 1247 .WillOnce(Invoke( | 1268 .WillOnce(Invoke([test_task_runner, quit_closure]( |
| 1248 [test_task_runner, quit_closure](const MemoryDumpRequestArgs& args, | 1269 const MemoryDumpRequestArgs& args, |
| 1249 const MemoryDumpCallback& callback) { | 1270 const GlobalMemoryDumpCallback& callback) { |
| 1250 test_task_runner->PostTask(FROM_HERE, quit_closure); | 1271 test_task_runner->PostTask(FROM_HERE, quit_closure); |
| 1251 })); | 1272 })); |
| 1252 EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)).Times(AnyNumber()); | 1273 EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)).Times(AnyNumber()); |
| 1253 | 1274 |
| 1254 EnableTracingWithTraceConfig( | 1275 EnableTracingWithTraceConfig( |
| 1255 TraceConfigMemoryTestUtil::GetTraceConfig_BackgroundTrigger( | 1276 TraceConfigMemoryTestUtil::GetTraceConfig_BackgroundTrigger( |
| 1256 1 /* period_ms */)); | 1277 1 /* period_ms */)); |
| 1257 | 1278 |
| 1258 // Only background mode dumps should be allowed with the trace config. | 1279 // Only background mode dumps should be allowed with the trace config. |
| 1259 last_callback_success_ = false; | 1280 last_callback_success_ = false; |
| 1260 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, | 1281 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 1261 MemoryDumpLevelOfDetail::LIGHT); | 1282 MemoryDumpLevelOfDetail::LIGHT); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1282 thread.Start(); | 1303 thread.Start(); |
| 1283 RegisterDumpProvider(&mdp1, thread.task_runner(), kDefaultOptions, | 1304 RegisterDumpProvider(&mdp1, thread.task_runner(), kDefaultOptions, |
| 1284 "BlacklistTestDumpProvider"); | 1305 "BlacklistTestDumpProvider"); |
| 1285 // Unregistering on wrong thread should not crash. | 1306 // Unregistering on wrong thread should not crash. |
| 1286 mdm_->UnregisterDumpProvider(&mdp1); | 1307 mdm_->UnregisterDumpProvider(&mdp1); |
| 1287 thread.Stop(); | 1308 thread.Stop(); |
| 1288 } | 1309 } |
| 1289 | 1310 |
| 1290 } // namespace trace_event | 1311 } // namespace trace_event |
| 1291 } // namespace base | 1312 } // namespace base |
| OLD | NEW |