Commit 91bd62ba authored by Primiano Tucci's avatar Primiano Tucci Committed by Commit Bot

memory-infra: don't pass mojo callback to MDM from client process

Passing these callbacks from the client process code means that MDM begins
owning the callback. However, these callbacks *must* be run before
destruction. While this is not a problem with MDM per-se as MDM is a
leaky singleton, MDM ocassionally passes ownership of this callback to
a thread loop.

On destruction of the thread loop with the callback posted, the callback
could be destroyed without being run which can cause problems.

To solve this, instead of passing the callback into a situation where
it could be destroyed, we instead store the callback inside the client
process itself. As the client is also a leaky singleton, the destructor
of these callbacks will no longer be run so we do not have the above problem.

Bug: 788658
Change-Id: I9dd65fe7748e0afaedd1bf5a3d25ac9cadfe9853
Reviewed-on: https://chromium-review.googlesource.com/790591Reviewed-by: default avatarPrimiano Tucci <primiano@chromium.org>
Commit-Queue: Primiano Tucci <primiano@chromium.org>
Cr-Commit-Position: refs/heads/master@{#519517}
parent a8ae8ef4
...@@ -75,18 +75,26 @@ void ClientProcessImpl::RequestChromeMemoryDump( ...@@ -75,18 +75,26 @@ void ClientProcessImpl::RequestChromeMemoryDump(
const base::trace_event::MemoryDumpRequestArgs& args, const base::trace_event::MemoryDumpRequestArgs& args,
const RequestChromeMemoryDumpCallback& callback) { const RequestChromeMemoryDumpCallback& callback) {
DCHECK(!callback.is_null()); DCHECK(!callback.is_null());
auto it_and_inserted =
pending_chrome_callbacks_.emplace(args.dump_guid, std::move(callback));
DCHECK(it_and_inserted.second) << "Duplicated request id " << args.dump_guid;
base::trace_event::MemoryDumpManager::GetInstance()->CreateProcessDump( base::trace_event::MemoryDumpManager::GetInstance()->CreateProcessDump(
args, base::Bind(&ClientProcessImpl::OnChromeMemoryDumpDone, args, base::Bind(&ClientProcessImpl::OnChromeMemoryDumpDone,
base::Unretained(this), callback, args)); base::Unretained(this)));
} }
void ClientProcessImpl::OnChromeMemoryDumpDone( void ClientProcessImpl::OnChromeMemoryDumpDone(
const RequestChromeMemoryDumpCallback& callback,
const base::trace_event::MemoryDumpRequestArgs& req_args,
bool success, bool success,
uint64_t dump_guid, uint64_t dump_guid,
std::unique_ptr<base::trace_event::ProcessMemoryDump> process_memory_dump) { std::unique_ptr<base::trace_event::ProcessMemoryDump> process_memory_dump) {
DCHECK(success || !process_memory_dump); DCHECK(success || !process_memory_dump);
auto callback_it = pending_chrome_callbacks_.find(dump_guid);
DCHECK(callback_it != pending_chrome_callbacks_.end());
auto callback = std::move(callback_it->second);
pending_chrome_callbacks_.erase(callback_it);
if (!process_memory_dump) { if (!process_memory_dump) {
callback.Run(false, dump_guid, nullptr); callback.Run(false, dump_guid, nullptr);
return; return;
......
...@@ -72,8 +72,6 @@ class SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT ClientProcessImpl ...@@ -72,8 +72,6 @@ class SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT ClientProcessImpl
// Callback passed to base::MemoryDumpManager::CreateProcessDump(). // Callback passed to base::MemoryDumpManager::CreateProcessDump().
void OnChromeMemoryDumpDone( void OnChromeMemoryDumpDone(
const RequestChromeMemoryDumpCallback&,
const base::trace_event::MemoryDumpRequestArgs& req_args,
bool success, bool success,
uint64_t dump_guid, uint64_t dump_guid,
std::unique_ptr<base::trace_event::ProcessMemoryDump>); std::unique_ptr<base::trace_event::ProcessMemoryDump>);
...@@ -89,6 +87,9 @@ class SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT ClientProcessImpl ...@@ -89,6 +87,9 @@ class SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT ClientProcessImpl
const mojom::ProcessType process_type_; const mojom::ProcessType process_type_;
scoped_refptr<base::SingleThreadTaskRunner> task_runner_; scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
// Map containing pending chrome memory callbacks indexed by dump guid.
std::map<uint64_t, RequestChromeMemoryDumpCallback> pending_chrome_callbacks_;
// TODO(ssid): This should be moved to coordinator instead of clients once we // TODO(ssid): This should be moved to coordinator instead of clients once we
// have the whole chrome dumps sent via mojo, crbug.com/728199. // have the whole chrome dumps sent via mojo, crbug.com/728199.
std::unique_ptr<TracingObserver> tracing_observer_; std::unique_ptr<TracingObserver> tracing_observer_;
......
...@@ -55,7 +55,6 @@ const char* kBackgroundButNotSummaryWhitelistedMDPName = ...@@ -55,7 +55,6 @@ const char* kBackgroundButNotSummaryWhitelistedMDPName =
"BackgroundButNotSummaryWhitelistedTestDumpProvider"; "BackgroundButNotSummaryWhitelistedTestDumpProvider";
const char* const kTestMDPWhitelist[] = { const char* const kTestMDPWhitelist[] = {
kWhitelistedMDPName, kBackgroundButNotSummaryWhitelistedMDPName, nullptr}; kWhitelistedMDPName, kBackgroundButNotSummaryWhitelistedMDPName, nullptr};
const uint64_t kTestGuid = 0;
// GTest matchers for MemoryDumpRequestArgs arguments. // GTest matchers for MemoryDumpRequestArgs arguments.
MATCHER(IsDetailedDump, "") { MATCHER(IsDetailedDump, "") {
...@@ -166,20 +165,21 @@ class MemoryTracingIntegrationTest : public testing::Test { ...@@ -166,20 +165,21 @@ class MemoryTracingIntegrationTest : public testing::Test {
std::unique_ptr<base::trace_event::ProcessMemoryDump>* result = nullptr) { std::unique_ptr<base::trace_event::ProcessMemoryDump>* result = nullptr) {
base::RunLoop run_loop; base::RunLoop run_loop;
bool success = false; bool success = false;
MemoryDumpRequestArgs request_args{kTestGuid, dump_type, level_of_detail}; uint64_t req_guid = ++guid_counter_;
MemoryDumpRequestArgs request_args{req_guid, dump_type, level_of_detail};
ClientProcessImpl::RequestChromeMemoryDumpCallback callback = base::Bind( ClientProcessImpl::RequestChromeMemoryDumpCallback callback = base::Bind(
[](bool* curried_success, base::Closure curried_quit_closure, [](bool* curried_success, base::Closure curried_quit_closure,
std::unique_ptr<base::trace_event::ProcessMemoryDump>* std::unique_ptr<base::trace_event::ProcessMemoryDump>*
curried_result, curried_result,
bool success, uint64_t dump_guid, uint64_t curried_expected_guid, bool success, uint64_t dump_guid,
std::unique_ptr<base::trace_event::ProcessMemoryDump> result) { std::unique_ptr<base::trace_event::ProcessMemoryDump> result) {
EXPECT_EQ(kTestGuid, dump_guid); EXPECT_EQ(curried_expected_guid, dump_guid);
*curried_success = success; *curried_success = success;
if (curried_result) if (curried_result)
*curried_result = std::move(result); *curried_result = std::move(result);
curried_quit_closure.Run(); curried_quit_closure.Run();
}, },
&success, run_loop.QuitClosure(), result); &success, run_loop.QuitClosure(), result, req_guid);
client_process_->RequestChromeMemoryDump(request_args, callback); client_process_->RequestChromeMemoryDump(request_args, callback);
run_loop.Run(); run_loop.Run();
return success; return success;
...@@ -187,7 +187,8 @@ class MemoryTracingIntegrationTest : public testing::Test { ...@@ -187,7 +187,8 @@ class MemoryTracingIntegrationTest : public testing::Test {
void RequestChromeDump(MemoryDumpType dump_type, void RequestChromeDump(MemoryDumpType dump_type,
MemoryDumpLevelOfDetail level_of_detail) { MemoryDumpLevelOfDetail level_of_detail) {
MemoryDumpRequestArgs request_args{kTestGuid, dump_type, level_of_detail}; uint64_t req_guid = ++guid_counter_;
MemoryDumpRequestArgs request_args{req_guid, dump_type, level_of_detail};
ClientProcessImpl::RequestChromeMemoryDumpCallback callback = base::Bind( ClientProcessImpl::RequestChromeMemoryDumpCallback callback = base::Bind(
[](bool success, uint64_t dump_guid, [](bool success, uint64_t dump_guid,
std::unique_ptr<base::trace_event::ProcessMemoryDump> result) {}); std::unique_ptr<base::trace_event::ProcessMemoryDump> result) {});
...@@ -235,6 +236,7 @@ class MemoryTracingIntegrationTest : public testing::Test { ...@@ -235,6 +236,7 @@ class MemoryTracingIntegrationTest : public testing::Test {
std::unique_ptr<base::MessageLoop> message_loop_; std::unique_ptr<base::MessageLoop> message_loop_;
std::unique_ptr<MockCoordinator> coordinator_; std::unique_ptr<MockCoordinator> coordinator_;
std::unique_ptr<ClientProcessImpl> client_process_; std::unique_ptr<ClientProcessImpl> client_process_;
uint64_t guid_counter_ = 0;
}; };
void MockCoordinator::RequestGlobalMemoryDump( void MockCoordinator::RequestGlobalMemoryDump(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment