1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/services/heap_profiling/heap_profiling_service.h"
#include <memory>
#include <utility>
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/memory/weak_ptr.h"
#include "base/task/thread_pool.h"
#include "components/services/heap_profiling/connection_manager.h"
#include "components/services/heap_profiling/public/mojom/heap_profiling_client.mojom.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
#include "mojo/public/cpp/system/platform_handle.h"
#include "services/resource_coordinator/public/mojom/memory_instrumentation/memory_instrumentation.mojom.h"
namespace heap_profiling {
namespace {
class ProfilingServiceImpl;
class ProfilingServiceImpl
: public mojom::ProfilingService,
public memory_instrumentation::mojom::HeapProfiler {
public:
ProfilingServiceImpl(
mojo::PendingReceiver<memory_instrumentation::mojom::HeapProfiler>
profiler_receiver,
mojo::PendingRemote<memory_instrumentation::mojom::HeapProfilerHelper>
helper)
: heap_profiler_receiver_(this, std::move(profiler_receiver)),
helper_(std::move(helper)) {}
ProfilingServiceImpl(const ProfilingServiceImpl&) = delete;
ProfilingServiceImpl& operator=(const ProfilingServiceImpl&) = delete;
~ProfilingServiceImpl() override = default;
// mojom::ProfilingService implementation:
void AddProfilingClient(base::ProcessId pid,
mojo::PendingRemote<mojom::ProfilingClient> client,
mojom::ProcessType process_type,
mojom::ProfilingParamsPtr params,
mojom::ProfilingService::AddProfilingClientCallback
started_profiling_closure) override {
if (params->sampling_rate == 0)
params->sampling_rate = 1;
connection_manager_.OnNewConnection(pid, std::move(client), process_type,
std::move(params),
std::move(started_profiling_closure));
}
void GetProfiledPids(GetProfiledPidsCallback callback) override {
std::move(callback).Run(connection_manager_.GetConnectionPids());
}
// memory_instrumentation::mojom::HeapProfiler implementation:
void DumpProcessesForTracing(
bool strip_path_from_mapped_files,
bool write_proto,
DumpProcessesForTracingCallback callback) override {
std::vector<base::ProcessId> pids =
connection_manager_.GetConnectionPidsThatNeedVmRegions();
if (pids.empty()) {
connection_manager_.DumpProcessesForTracing(
strip_path_from_mapped_files, write_proto, std::move(callback),
VmRegions());
return;
}
// Need a memory map to make sense of the dump. The dump will be triggered
// in the memory map global dump callback.
helper_->GetVmRegionsForHeapProfiler(
pids,
base::BindOnce(&ProfilingServiceImpl::
OnGetVmRegionsCompleteForDumpProcessesForTracing,
weak_factory_.GetWeakPtr(), strip_path_from_mapped_files,
write_proto, std::move(callback)));
}
private:
void OnGetVmRegionsCompleteForDumpProcessesForTracing(
bool strip_path_from_mapped_files,
bool write_proto,
DumpProcessesForTracingCallback callback,
VmRegions vm_regions) {
connection_manager_.DumpProcessesForTracing(
strip_path_from_mapped_files, write_proto, std::move(callback),
std::move(vm_regions));
}
mojo::Receiver<memory_instrumentation::mojom::HeapProfiler>
heap_profiler_receiver_{this};
mojo::Remote<memory_instrumentation::mojom::HeapProfilerHelper> helper_;
ConnectionManager connection_manager_;
base::WeakPtrFactory<ProfilingServiceImpl> weak_factory_{this};
};
void RunHeapProfilingService(
mojo::PendingReceiver<mojom::ProfilingService> receiver,
mojo::PendingReceiver<memory_instrumentation::mojom::HeapProfiler>
profiler_receiver,
mojo::PendingRemote<memory_instrumentation::mojom::HeapProfilerHelper>
helper) {
mojo::MakeSelfOwnedReceiver(
std::make_unique<ProfilingServiceImpl>(std::move(profiler_receiver),
std::move(helper)),
std::move(receiver));
}
} // namespace
mojo::PendingRemote<mojom::ProfilingService> LaunchService(
mojo::PendingReceiver<memory_instrumentation::mojom::HeapProfiler>
profiler_receiver,
mojo::PendingRemote<memory_instrumentation::mojom::HeapProfilerHelper>
helper) {
mojo::PendingRemote<mojom::ProfilingService> remote;
auto task_runner = base::ThreadPool::CreateSingleThreadTaskRunner(
{base::TaskPriority::BEST_EFFORT, base::WithBaseSyncPrimitives()},
base::SingleThreadTaskRunnerThreadMode::DEDICATED);
task_runner->PostTask(
FROM_HERE,
base::BindOnce(&RunHeapProfilingService,
remote.InitWithNewPipeAndPassReceiver(),
std::move(profiler_receiver), std::move(helper)));
return remote;
}
} // namespace heap_profiling
|