blob: 4c0b49594ae9b87f58440c14d35f5d4d17d5f3ab [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.
library fuchsia.memory.sampler;
using zx;
/// A build ID is a 20 bytes long sequence.
const BUILD_ID_BYTES uint32 = 20;
/// Information necessary for the symbolization of a module.
/// Represents the subset of an ELF module relevant for the purposes of
/// the profiler. The main use case for this map is the symbolization of stack traces.
type ModuleMap = table {
/// Build ID, a string which uniquely identifies a module build.
1: build_id vector<uint8>:BUILD_ID_BYTES;
/// Collection of executable segments.
2: executable_segments vector<ExecutableSegment>:MAX;
};
/// Address region that corresponds to an executable segment in an ELF module.
type ExecutableSegment = table {
/// Start of the region as mapped in memory.
1: start_address uint64;
/// Size of the range of addresses that are part of the region.
2: size uint64;
/// Offset of the region in the ELF binary before loading.
3: relative_address uint64;
};
/// A stack trace, as a collection of stack frames.
type StackTrace = table {
/// Ordered vector of frame pointers, from the narrower to the wider location.
1: stack_frames vector<uint64>:MAX;
};
/// Interface used to exfiltrate process allocation information.
@discoverable
closed protocol Sampler {
/// Record an allocation.
strict RecordAllocation(struct {
/// Address of the allocation, to uniquely identify it.
address uint64;
/// Stack frames collected at the allocation point.
///
/// A client is free to truncate their stack traces to a size below the
/// maximum size of a message that can be sent over the channel. If a
/// client sends a StackTrace that causes to exceed the maximum size of
/// the message, then the record will be dropped until RFC-0196 is
/// implemented.
stack_trace StackTrace;
/// Size (in bytes) of this allocation.
size uint64;
});
/// Record a deallocation.
strict RecordDeallocation(struct {
/// Address of the deallocation, to uniquely identify it.
address uint64;
/// Stack frames collected at the deallocation point.
///
/// A client is free to truncate their stack traces to a size below the
/// maximum size of a message that can be sent over the channel. If a
/// client sends a StackTrace that causes to exceed the maximum size of
/// the message, then the record will be dropped until RFC-0196 is
/// implemented.
stack_trace StackTrace;
});
/// Communicate relevant process information to facilitate symbolization.
///
/// If called several times, the last `process_name` prevails, but the
/// `module_map` is added to the existing map for the process. If a client
/// needs to send a `module_map` that does not fit in a single message, they
/// can split it and send it across several messages.
strict SetProcessInfo(table {
/// Name of the instrumented process.
1: process_name string:zx.MAX_NAME_LEN;
/// Current module layout, for symbolization.
2: module_map vector<ModuleMap>:MAX;
});
};