coordinator_impl.h 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. // Copyright 2017 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef SERVICES_RESOURCE_COORDINATOR_MEMORY_INSTRUMENTATION_COORDINATOR_IMPL_H_
  5. #define SERVICES_RESOURCE_COORDINATOR_MEMORY_INSTRUMENTATION_COORDINATOR_IMPL_H_
  6. #include <list>
  7. #include <map>
  8. #include <set>
  9. #include <string>
  10. #include "base/gtest_prod_util.h"
  11. #include "base/memory/ref_counted.h"
  12. #include "base/threading/thread_checker.h"
  13. #include "base/time/time.h"
  14. #include "base/trace_event/memory_dump_request_args.h"
  15. #include "mojo/public/cpp/bindings/pending_receiver.h"
  16. #include "mojo/public/cpp/bindings/receiver.h"
  17. #include "mojo/public/cpp/bindings/receiver_set.h"
  18. #include "services/resource_coordinator/memory_instrumentation/queued_request.h"
  19. #include "services/resource_coordinator/public/cpp/memory_instrumentation/registry.h"
  20. #include "services/resource_coordinator/public/cpp/memory_instrumentation/tracing_observer.h"
  21. #include "services/resource_coordinator/public/mojom/memory_instrumentation/memory_instrumentation.mojom.h"
  22. #include "third_party/abseil-cpp/absl/types/optional.h"
  23. namespace memory_instrumentation {
  24. // Memory instrumentation service. It serves two purposes:
  25. // - Handles a registry of the processes that have a memory instrumentation
  26. // client library instance (../../public/cpp/memory).
  27. // - Provides global (i.e. for all processes) memory snapshots on demand.
  28. // Global snapshots are obtained by requesting in-process snapshots from each
  29. // registered client and aggregating them.
  30. class CoordinatorImpl : public Registry,
  31. public mojom::Coordinator,
  32. public mojom::HeapProfilerHelper {
  33. public:
  34. CoordinatorImpl();
  35. CoordinatorImpl(const CoordinatorImpl&) = delete;
  36. CoordinatorImpl& operator=(const CoordinatorImpl&) = delete;
  37. ~CoordinatorImpl() override;
  38. // The getter of the unique instance.
  39. static CoordinatorImpl* GetInstance();
  40. // Registry:
  41. void RegisterHeapProfiler(mojo::PendingRemote<mojom::HeapProfiler> profiler,
  42. mojo::PendingReceiver<mojom::HeapProfilerHelper>
  43. helper_receiver) override;
  44. void RegisterClientProcess(
  45. mojo::PendingReceiver<mojom::Coordinator> receiver,
  46. mojo::PendingRemote<mojom::ClientProcess> client_process,
  47. mojom::ProcessType process_type,
  48. base::ProcessId process_id,
  49. const absl::optional<std::string>& service_name) override;
  50. // mojom::Coordinator implementation.
  51. void RequestGlobalMemoryDump(
  52. base::trace_event::MemoryDumpType,
  53. base::trace_event::MemoryDumpLevelOfDetail,
  54. base::trace_event::MemoryDumpDeterminism,
  55. const std::vector<std::string>& allocator_dump_names,
  56. RequestGlobalMemoryDumpCallback) override;
  57. void RequestGlobalMemoryDumpForPid(
  58. base::ProcessId,
  59. const std::vector<std::string>& allocator_dump_names,
  60. RequestGlobalMemoryDumpForPidCallback) override;
  61. void RequestPrivateMemoryFootprint(
  62. base::ProcessId,
  63. RequestPrivateMemoryFootprintCallback) override;
  64. void RequestGlobalMemoryDumpAndAppendToTrace(
  65. base::trace_event::MemoryDumpType,
  66. base::trace_event::MemoryDumpLevelOfDetail,
  67. base::trace_event::MemoryDumpDeterminism,
  68. RequestGlobalMemoryDumpAndAppendToTraceCallback) override;
  69. // mojom::HeapProfilerHelper implementation.
  70. void GetVmRegionsForHeapProfiler(
  71. const std::vector<base::ProcessId>& pids,
  72. GetVmRegionsForHeapProfilerCallback) override;
  73. private:
  74. using OSMemDumpMap = base::flat_map<base::ProcessId, mojom::RawOSMemDumpPtr>;
  75. using RequestGlobalMemoryDumpInternalCallback =
  76. base::OnceCallback<void(bool, uint64_t, mojom::GlobalMemoryDumpPtr)>;
  77. friend class CoordinatorImplTest; // For testing
  78. FRIEND_TEST_ALL_PREFIXES(CoordinatorImplTest,
  79. DumpsAreAddedToTraceWhenRequested);
  80. FRIEND_TEST_ALL_PREFIXES(CoordinatorImplTest,
  81. DumpsArentAddedToTraceUnlessRequested);
  82. // Holds metadata and a client pipe connected to every client process.
  83. struct ClientInfo {
  84. ClientInfo(mojo::Remote<mojom::ClientProcess> client,
  85. mojom::ProcessType,
  86. absl::optional<std::string> service_name);
  87. ~ClientInfo();
  88. const mojo::Remote<mojom::ClientProcess> client;
  89. const mojom::ProcessType process_type;
  90. const absl::optional<std::string> service_name;
  91. };
  92. void UnregisterClientProcess(base::ProcessId);
  93. void RequestGlobalMemoryDumpInternal(
  94. const QueuedRequest::Args& args,
  95. RequestGlobalMemoryDumpInternalCallback callback);
  96. // Callback of RequestChromeMemoryDump.
  97. void OnChromeMemoryDumpResponse(
  98. base::ProcessId process_id,
  99. bool success,
  100. uint64_t dump_guid,
  101. std::unique_ptr<base::trace_event::ProcessMemoryDump> chrome_memory_dump);
  102. // Callback of RequestOSMemoryDump.
  103. void OnOSMemoryDumpResponse(uint64_t dump_guid,
  104. base::ProcessId process_id,
  105. bool success,
  106. OSMemDumpMap);
  107. // Callback of RequestOSMemoryDumpForVmRegions.
  108. void OnOSMemoryDumpForVMRegions(uint64_t dump_guid,
  109. base::ProcessId process_id,
  110. bool success,
  111. OSMemDumpMap);
  112. void FinalizeVmRegionDumpIfAllManagersReplied(uint64_t dump_guid);
  113. // Callback of DumpProcessesForTracing.
  114. void OnDumpProcessesForTracing(
  115. uint64_t dump_guid,
  116. std::vector<mojom::HeapProfileResultPtr> heap_profile_results);
  117. void RemovePendingResponse(base::ProcessId process_id,
  118. QueuedRequest::PendingResponse::Type);
  119. void OnQueuedRequestTimedOut(uint64_t dump_guid);
  120. void OnHeapDumpTimeOut(uint64_t dump_guid);
  121. void PerformNextQueuedGlobalMemoryDump();
  122. void FinalizeGlobalMemoryDumpIfAllManagersReplied();
  123. QueuedRequest* GetCurrentRequest();
  124. void set_client_process_timeout(base::TimeDelta client_process_timeout) {
  125. client_process_timeout_ = client_process_timeout;
  126. }
  127. // Map of registered client processes.
  128. std::map<base::ProcessId, std::unique_ptr<ClientInfo>> clients_;
  129. // Outstanding dump requests, enqueued via RequestGlobalMemoryDump().
  130. std::list<QueuedRequest> queued_memory_dump_requests_;
  131. // Outstanding vm region requests, enqueued via GetVmRegionsForHeapProfiler().
  132. // This is kept in a separate list from |queued_memory_dump_requests_| for two
  133. // reasons:
  134. // 1) The profiling service is queried during a memory dump request, but the
  135. // profiling service in turn needs to query for vm regions. Keeping this in
  136. // the same list as |queued_memory_dump_requests_| would require this class
  137. // to support concurrent requests.
  138. //
  139. // 2) Vm region requests are only ever requested by the profiling service,
  140. // which uses the HeapProfilerHelper interface. Keeping the requests
  141. // separate means we can avoid littering the RequestGlobalMemoryDump
  142. // interface with flags intended for HeapProfilerHelper. This was already
  143. // technically possible before, but required some additional plumbing. Now
  144. // the separation is much cleaner.
  145. //
  146. // Unlike queued_memory_dump_requests_, all requests are executed in parallel.
  147. // The key is a |dump_guid|.
  148. std::map<uint64_t, std::unique_ptr<QueuedVmRegionRequest>>
  149. in_progress_vm_region_requests_;
  150. // There may be extant callbacks in |queued_memory_dump_requests_|. These
  151. // receivers must be closed before destroying the un-run callbacks.
  152. mojo::ReceiverSet<mojom::Coordinator, base::ProcessId> coordinator_receivers_;
  153. // Dump IDs are unique across both heap dump and memory dump requests.
  154. uint64_t next_dump_id_;
  155. std::unique_ptr<TracingObserver> tracing_observer_;
  156. // Timeout for registered client processes to respond to dump requests.
  157. base::TimeDelta client_process_timeout_;
  158. // When not null, can be queried for heap dumps.
  159. mojo::Remote<mojom::HeapProfiler> heap_profiler_;
  160. mojo::Receiver<mojom::HeapProfilerHelper> heap_profiler_helper_receiver_{
  161. this};
  162. const bool use_proto_writer_;
  163. const bool write_proto_heap_profile_;
  164. THREAD_CHECKER(thread_checker_);
  165. base::WeakPtrFactory<CoordinatorImpl> weak_ptr_factory_{this};
  166. };
  167. } // namespace memory_instrumentation
  168. #endif // SERVICES_RESOURCE_COORDINATOR_MEMORY_INSTRUMENTATION_COORDINATOR_IMPL_H_