blob: 2782e8776c53e8663c4b098738fc13c11e649394 [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
module memory_instrumentation.mojom;
import "mojo/public/mojom/base/process_id.mojom";
// Common structs:
enum DumpType {
PERIODIC_INTERVAL,
EXPLICITLY_TRIGGERED,
SUMMARY_ONLY
};
enum LevelOfDetail {
BACKGROUND,
LIGHT,
DETAILED
};
enum ProcessType {
OTHER,
BROWSER,
RENDERER,
GPU,
UTILITY,
PLUGIN
};
enum MemoryMapOption {
// Do not fetch any information about mapped regions in the virtual address
// space.
NONE,
// Only fetch information on code modules, e.g. Chrome Binary, system
// libraries.
MODULES,
// Fetch information for every single mapped region.
FULL
};
// These structs are internal only (only for the communication between
// the service and the ClientProcess library).
// See corresponding types in //base/trace_event for comments.
struct RequestArgs {
uint64 dump_guid;
DumpType dump_type;
LevelOfDetail level_of_detail;
};
struct RawAllocatorDumpEdge {
uint64 source_id;
uint64 target_id;
int64 importance;
bool overridable;
};
union RawAllocatorDumpEntryValue {
uint64 value_uint64;
string value_string;
};
struct RawAllocatorDumpEntry {
string name;
string units;
RawAllocatorDumpEntryValue value;
};
struct RawAllocatorDump {
uint64 id;
string absolute_name;
bool weak;
LevelOfDetail level_of_detail;
array<RawAllocatorDumpEntry> entries;
};
struct RawProcessMemoryDump {
LevelOfDetail level_of_detail;
array<RawAllocatorDumpEdge> allocator_dump_edges;
array<RawAllocatorDump> allocator_dumps;
};
struct VmRegion {
const uint32 kProtectionFlagsRead = 4;
const uint32 kProtectionFlagsWrite = 2;
const uint32 kProtectionFlagsExec = 1;
const uint32 kProtectionFlagsMayshare = 128;
uint64 start_address;
uint64 size_in_bytes;
uint64 module_timestamp;
// Unique module debug identifier to retrieve debug information.
string module_debugid;
string module_debug_path;
uint32 protection_flags;
string mapped_file;
// private_dirty_resident + private_clean_resident + shared_dirty_resident +
// shared_clean_resident = resident set size.
uint64 byte_stats_private_dirty_resident;
uint64 byte_stats_private_clean_resident;
uint64 byte_stats_shared_dirty_resident;
uint64 byte_stats_shared_clean_resident;
uint64 byte_stats_swapped;
// For multiprocess accounting.
uint64 byte_stats_proportional_resident;
};
// Platform-specific data that will be used to compute the
// PrivateMemoryFootprint.
struct PlatformPrivateFootprint {
uint64 phys_footprint_bytes = 0;
// macOS 10.12+
uint64 internal_bytes = 0;
// macOS [all versions]
uint64 compressed_bytes = 0;
uint64 rss_anon_bytes = 0;
// Linux, Android, ChromeOS
uint64 vm_swap_bytes = 0;
// On Windows,
uint64 private_bytes = 0;
// On iOS,
// TBD: https://crbug.com/714961
};
struct RawOSMemDump {
uint32 resident_set_kb = 0;
PlatformPrivateFootprint platform_private_footprint;
array<VmRegion> memory_maps;
};
// These structs are public:
struct OSMemDump {
uint32 resident_set_kb = 0;
// This is roughly private, anonymous, non-discardable, resident or swapped
// memory in kilobytes. For more details, see https://goo.gl/3kPb9S.
uint32 private_footprint_kb = 0;
// This is roughly non-private, anonymous, non-discardable, resident memory
// in kilobytes. For more details, see https://goo.gl/3kPb9S.
uint32 shared_footprint_kb = 0;
// This is private swapped memory in kilobytes reported on Linux and Android
// only.
[EnableIf=private_swap_info]
uint32 private_footprint_swap_kb = 0;
};
// This struct contains information about a particular allocator dump
// (e.g. cc/resource_memory).
struct AllocatorMemDump {
// The entries for the allocator which are of scalar types (i.e. not strings).
// Examples include: effective_size, size, object_count.
map<string, uint64> numeric_entries;
};
// This struct is used for the public-facing API
// Coordinator::RequestGlobalMemoryDump().
struct ProcessMemoryDump {
ProcessType process_type;
OSMemDump os_dump;
// The chrome allocator dumps specified by the input args.
// (See GlobalRequestArgs.allocator_dump_names).
map<string, AllocatorMemDump> chrome_allocator_dumps;
// |pid| is necessary to correlate a ProcessMemoryDump with the URLs for the
// process, which is obtained from the ResourceCoordinator service. In a
// future world where both ResourceCoordinator and MemoryInstrumentation are
// less in flux, they will probably be merged into a single service, and this
// parameter can be removed.
mojo_base.mojom.ProcessId pid;
};
// This struct is returned by the public-facing API
// Coordinator::RequestGlobalMemoryDump().
struct GlobalMemoryDump {
array<ProcessMemoryDump> process_dumps;
};
// This is the interface implemented by the per-process client library. This
// allows a process to contribute to memory-infra dumps. There should be at
// most one instance of this per hosting process.
interface ClientProcess {
// When |success| == true the dump is appended in the process-local trace
// buffer of the target process and an ACK. A summary of the dump is also
// returned in case of success.
RequestChromeMemoryDump(RequestArgs args) =>
(bool success, uint64 dump_id, RawProcessMemoryDump? raw_process_memory_dump);
// Requests an OSMemDump for each pid in |pids|.
// The Memory-infra service deals with two kinds of information:
// 1) Chrome's view of its own memory use (recorded as
// |chrome_allocator_dumps|)
// 2) The OS's view of Chrome's memory use (recorded as OSMemDumps)
// Both of these are collected per process. On most platforms each process
// can make the system calls to collect its own OSMemDump however on some
// platforms *cough* Linux *cough* due to sandboxing only the browser
// process can collect OSMemDumps. This API allows for these two cases.
// On most platforms we send this message to each ClientProcess with
// with one pid - kNullProcessId - meaning return just your own OSMemDump.
// On Linux we call this once on the browser process ClientProcess passing
// the pids for all processes.
// See crbug.com/461788
RequestOSMemoryDump(MemoryMapOption option, array<mojo_base.mojom.ProcessId> pids) =>
(bool success, map<mojo_base.mojom.ProcessId, RawOSMemDump> dumps);
};
struct SharedBufferWithSize {
handle<shared_buffer> buffer;
uint32 size;
mojo_base.mojom.ProcessId pid;
};
// HeapProfilers expose a single interface to memory_instrumentation, allowing
// the latter to query for heap dumps when necessary.
//
// This interface is NOT implemented in resource_coordinator but by the
// profiling service in chrome/profiler. The profiling service registers itself
// with the Coordinator (see RegisterHeapProfiler) and is invoked when a memory
// dump is requested (via Coordinator::RequestGlobalMemoryDump).
interface HeapProfiler {
// Dumps the memory log of all profiled processes into shared buffers. The
// contents of each shared buffer is a JSON string compatible with
// TRACE_EVENT* macros. Processes that fail to dump will be omitted from
// |buffers|. When |strip_path_from_mapped_files| is true, only the base name
// of mapped files is emitted. This prevents usernames from sneaking into the
// trace.
// |strip_path_from_mapped_files| should only be true for traces that will be
// uploaded to the crash servers - this strips potential PII, but prevents
// symbolization of local builds.
DumpProcessesForTracing(bool strip_path_from_mapped_files) =>
(array<SharedBufferWithSize> buffers);
};
// Implemented by resource_coordinator to provide additional information needed
// by the HeapProfiler.
interface HeapProfilerHelper {
// Broadcasts a RequestOSMemoryDump-only request for all registered client
// processes and retrieves only their memory maps.
GetVmRegionsForHeapProfiler(array<mojo_base.mojom.ProcessId> pids) =>
(map<mojo_base.mojom.ProcessId, array<VmRegion>> vm_regions);
};
// The memory-infra service implements this interface. There is one instance for
// the whole system. The coordinator maintains a list of registered client
// processes and polls them whenever a global dump is required.
interface Coordinator {
// Registers a client process.
RegisterClientProcess(ClientProcess client_process, ProcessType process_type);
// Broadcasts a dump request to all registered client processes and returns a
// global dump which includes allocator dumps specified in |allocator_dump_names|.
// For example, given an allocator dump name such as "malloc" or "cc/resource_memory",
// this method returns all information corresponding to this name including numeric
// entries which contain fields such as "size" and "effective_size".
RequestGlobalMemoryDump(DumpType dump_type,
LevelOfDetail level_of_detail,
array<string> allocator_dump_names) =>
(bool success, GlobalMemoryDump? global_memory_dump);
// Sends a dump request to the client process given by the specified pid and
// returns a summarized dump back or null if there was a failure.
RequestGlobalMemoryDumpForPid(mojo_base.mojom.ProcessId pid,
array<string> allocator_dump_names) =>
(bool success, GlobalMemoryDump? global_memory_dump);
// Broadcasts a dump request to all registered client processes and injects the
// dump in the trace buffer (if tracing is enabled).
RequestGlobalMemoryDumpAndAppendToTrace(DumpType dump_type,
LevelOfDetail level_of_detail) =>
(bool success, uint64 dump_id);
// When a heap profiler is registered, heap dumps will be added to the trace
// any time RequestGlobalMemoryDumpAndAppendToTrace is called.
// This is cleaner than having the memory_instrumentation service talk
// directly to the HeapProfiler, since that will spawn the HeapProfiler in a
// new process if it isn't already running.
RegisterHeapProfiler(HeapProfiler heap_profiler);
};