blob: cd806ef55fb847bfc3c0bf0451fbee5215f89db5 [file] [log] [blame]
// Copyright 2023 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@available(added=15)
library fuchsia.memory.heapdump.client;
using zx;
const MAX_BUILD_ID_LENGTH uint32 = 32;
alias StackTraceKey = uint64;
alias ThreadInfoKey = uint64;
/// The reason why a method failed.
type CollectorError = flexible enum {
/// The given ProcessSelector value is not supported.
PROCESS_SELECTOR_UNSUPPORTED = 1;
/// The given ProcessSelector value does not match any process.
PROCESS_SELECTOR_NO_MATCH = 2;
/// The given ProcessSelector value matches more than one process but the requested operation
/// needs a unique match.
PROCESS_SELECTOR_AMBIGUOUS = 3;
/// Failed to take a live snapshot.
LIVE_SNAPSHOT_FAILED = 4;
/// The requested StoredSnapshot does not exist.
STORED_SNAPSHOT_NOT_FOUND = 5;
};
/// Filter to restrict an operation to a subset of the available processes.
type ProcessSelector = flexible union {
/// Matches any process with the given ZX_PROP_NAME.
1: by_name string:zx.MAX_NAME_LEN;
/// Matches the process with the given koid.
2: by_koid zx.Koid;
};
/// An allocated memory block.
type Allocation = table {
/// The address of the memory block.
1: address uint64;
/// Block size, in bytes.
2: size uint64;
/// The stack trace of the allocation site.
3: stack_trace_key StackTraceKey;
/// Allocation timestamp.
4: timestamp zx.Time;
/// The allocating thread.
5: thread_info_key ThreadInfoKey;
};
/// A stack trace.
///
/// In order to avoid exceeding the channel's maximum message size, stack traces can be split in
/// multiple chunks. Receivers should be prepared to handle multiple StackTrace elements with the
/// same key and reassemble them by concatenating their program addresses.
type StackTrace = table {
/// A number that uniquely identifies this stack trace within the parent snapshot.
1: stack_trace_key StackTraceKey;
/// The program counters corresponding to stack each frame.
///
/// Entries are listed in reverse call order: the first entry refers to the leaf frame, and the
/// last entry refers to the frame at the root of the call stack.
2: program_addresses vector<uint64>:MAX;
};
/// Information on a given thread.
///
/// Note: Under some circumstances, more than one entry could exist for a given koid (e.g. if the
/// thread changed its name between different allocations).
type ThreadInfo = table {
/// A number that uniquely identifies this entry within the parent snapshot.
1: thread_info_key ThreadInfoKey;
/// The koid of the thread that this entry refers to.
2: koid zx.Koid;
/// The name of the thread that this entry refers to.
3: name string:zx.MAX_NAME_LEN;
};
/// An ELF build ID.
type BuildId = struct {
value vector<uint8>:MAX_BUILD_ID_LENGTH;
};
/// A memory region containing code loaded from an ELF file.
type ExecutableRegion = table {
/// The address of the memory region.
1: address uint64;
/// Region size, in bytes.
2: size uint64;
/// The file offset corresponding to the first byte within the region.
3: file_offset uint64;
/// The build ID of the ELF file.
4: build_id BuildId;
};
/// The contents of an allocated memory block.
///
/// In order to avoid exceeding the channel's maximum message size, bigger blocks can be split in
/// chunks. Receivers should be prepared to handle multiple BlockContents with the same address and
/// reassemble them by concatenating their payloads. Each block's reassembled size always matches
/// the size field of the corresponding Allocation.
type BlockContents = table {
/// The address of the corresponding memory block.
1: address uint64;
/// The payload.
2: contents vector<byte>:MAX;
};
/// An element that is part of a snapshot.
type SnapshotElement = flexible union {
1: allocation Allocation;
2: stack_trace StackTrace;
3: executable_region ExecutableRegion;
4: block_contents BlockContents;
5: thread_info ThreadInfo;
};
/// Protocol to transmit a snapshot as a stream of elements.
closed protocol SnapshotReceiver {
/// Delivers a batch of snapshot elements.
///
/// It will be called repeatedly until no elements are left, and then one final time with an
/// empty vector to signal the end of the stream.
strict Batch(struct {
batch vector<SnapshotElement>:MAX;
}) -> ();
/// Reports an error. No other batches or errors will follow.
strict ReportError(struct {
error CollectorError;
}) -> ();
};
/// A snapshot that is stored on the device and that can be downloaded.
///
/// Application-initiated snapshots belong to this category.
type StoredSnapshot = table {
/// A number that uniquely identifies this snapshot within a Collector.
1: snapshot_id uint32;
/// The name given to this snapshot.
2: snapshot_name string:zx.MAX_NAME_LEN;
/// The koid of the process that this snapshot refers to.
3: process_koid zx.Koid;
/// The name of the process that this snapshot refers to.
4: process_name string:zx.MAX_NAME_LEN;
};
/// Protocol to retrieve a list of StoredSnapshots.
closed protocol StoredSnapshotIterator {
/// Retrieves the next batch of StoredSnapshots elements.
///
/// An empty response signals the end of the list.
strict GetNext() -> (struct {
batch vector<StoredSnapshot>:MAX;
}) error CollectorError;
};
/// Protocol to request and retrieve memory profiles.
@discoverable
open protocol Collector {
/// Obtains a snapshot of the current live allocations in an instrumented process.
flexible TakeLiveSnapshot(resource table {
/// The instrumented process to operate on.
///
/// Required.
1: process_selector ProcessSelector;
/// Where the elements of the requested snapshot will be sent to.
///
/// Required.
2: receiver client_end:SnapshotReceiver;
/// Whether the snapshot should include the contents of each memory block.
///
/// If not set, false is assumed.
3: with_contents bool;
});
/// Retrieves the list of all the available stored snapshots.
flexible ListStoredSnapshots(resource table {
/// The server_end of the StoredSnapshotIterator that will be used to retrieve the results.
///
/// Required.
1: iterator server_end:StoredSnapshotIterator;
/// If present, only retrieve snapshots that refer to matching processes.
2: process_selector ProcessSelector;
});
/// Retrieves a stored snapshot.
flexible DownloadStoredSnapshot(resource table {
/// The identifier of the snapshot to be downloaded.
///
/// The list of the available snapshots can be retrieved with ListStoredSnapshots.
///
/// Required.
1: snapshot_id uint32;
/// Where the elements of the requested snapshot will be sent to.
///
/// Required.
2: receiver client_end:SnapshotReceiver;
});
};