• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17syntax = "proto2";
18
19import "protos/perfetto/trace/profiling/profile_common.proto";
20
21package perfetto.protos;
22
23message ProfilePacket {
24  // The following interning tables are only used in Android version Q.
25  // In newer versions, these tables are in InternedData
26  // (see protos/perfetto/trace/interned_data) and are shared across
27  // multiple ProfilePackets.
28  // For backwards compatibility, consumers need to first look up interned
29  // data in the tables within the ProfilePacket, and then, if they are empty,
30  // look up in the InternedData instead.
31  repeated InternedString strings = 1;
32  repeated Mapping mappings = 4;
33  repeated Frame frames = 2;
34  repeated Callstack callstacks = 3;
35
36  // Next ID: 9
37  message HeapSample {
38    optional uint64 callstack_id = 1;
39    // bytes allocated at this callstack.
40    optional uint64 self_allocated = 2;
41    // bytes allocated at this callstack that have been freed.
42    optional uint64 self_freed = 3;
43    // bytes allocated at this callstack but not used since the last
44    // dump.
45    // See documentation of idle_allocations in HeapprofdConfig for more
46    // details.
47    optional uint64 self_idle = 7;
48    // Bytes allocated by this callstack but not freed at the time the malloc
49    // heap usage of this process was maximal. This is only set if dump_at_max
50    // is true in HeapprofdConfig. In that case, self_allocated, self_freed and
51    // self_idle will not be set.
52    optional uint64 self_max = 8;
53    optional uint64 timestamp = 4;  // timestamp [opt]
54    // Number of allocations that were sampled at this callstack.
55    optional uint64 alloc_count = 5;
56    // Number of allocations that were sampled at this callstack that have been
57    // freed.
58    optional uint64 free_count = 6;
59  }
60
61  message Histogram {
62    message Bucket {
63      // This bucket counts values from the previous bucket's (or -infinity if
64      // this is the first bucket) upper_limit (inclusive) to this upper_limit
65      // (exclusive).
66      optional uint64 upper_limit = 1;
67      // This is the highest bucket. This is set instead of the upper_limit. Any
68      // values larger or equal to the previous bucket's upper_limit are counted
69      // in this bucket.
70      optional bool max_bucket = 2;
71      // Number of values that fall into this range.
72      optional uint64 count = 3;
73    }
74    repeated Bucket buckets = 1;
75  }
76
77  message ProcessStats {
78    optional uint64 unwinding_errors = 1;
79    optional uint64 heap_samples = 2;
80    optional uint64 map_reparses = 3;
81    optional Histogram unwinding_time_us = 4;
82    optional uint64 total_unwinding_time_us = 5;
83  }
84
85  repeated ProcessHeapSamples process_dumps = 5;
86  message ProcessHeapSamples {
87    optional uint64 pid = 1;
88
89    // This process was profiled from startup.
90    // If false, this process was already running when profiling started.
91    optional bool from_startup = 3;
92
93    // This process was not profiled because a concurrent session was active.
94    // If this is true, samples will be empty.
95    optional bool rejected_concurrent = 4;
96
97    // This process disconnected while it was profiled.
98    // If false, the process outlived the profiling session.
99    optional bool disconnected = 6;
100
101    // If disconnected, this disconnect was caused by the client overrunning
102    // the buffer.
103    optional bool buffer_overran = 7;
104
105    // If disconnected, this disconnected was caused by the shared memory
106    // buffer being corrupted. THIS IS ALWAYS A BUG IN HEAPPROFD OR CLIENT
107    // MEMORY CORRUPTION.
108    optional bool buffer_corrupted = 8;
109
110    // If disconnected, this disconnect was caused by heapprofd exceeding
111    // guardrails during this profiling session.
112    optional bool hit_guardrail = 10;
113
114    // Timestamp of the state of the target process that this dump represents.
115    // This can be different to the timestamp of the TracePackets for various
116    // reasons:
117    // * If disconnected is set above, this is the timestamp of last state
118    //   heapprofd had of the process before it disconnected.
119    // * Otherwise, if the rate of events produced by the process is high,
120    //   heapprofd might be behind.
121    //
122    // TODO(fmayer): This is MONOTONIC_COARSE. Refactor ClockSnapshot::Clock
123    //               to have a type enum that we can reuse here.
124    optional uint64 timestamp = 9;
125
126    // Metadata about heapprofd.
127    optional ProcessStats stats = 5;
128
129    repeated HeapSample samples = 2;
130  }
131
132  // If this is true, the next ProfilePacket in this package_sequence_id is a
133  // continuation of this one.
134  // To get all samples for a process, accummulate its
135  // ProcessHeapSamples.samples until you see continued=false.
136  optional bool continued = 6;
137
138  // Index of this ProfilePacket on its package_sequence_id. Can be used
139  // to detect dropped data.
140  // Verify these are consecutive.
141  optional uint64 index = 7;
142}
143
144// Message used to represent individual stack samples sampled at discrete
145// points in time, rather than aggregated over an interval.
146message StreamingProfilePacket {
147  repeated uint64 callstack_iid = 1;  // Index into InternedData.callstacks
148  // TODO(eseckler): ThreadDescriptor-based timestamps are deprecated. Replace
149  // this with ClockSnapshot-based delta encoding instead.
150  repeated int64 timestamp_delta_us = 2;
151  optional int32 process_priority = 3;
152}
153
154// Namespace for the contained enums.
155message Profiling {
156  enum CpuMode {
157    MODE_UNKNOWN = 0;
158    MODE_KERNEL = 1;
159    MODE_USER = 2;
160    // The following values aren't expected, but included for completeness:
161    MODE_HYPERVISOR = 3;
162    MODE_GUEST_KERNEL = 4;
163    MODE_GUEST_USER = 5;
164  }
165
166  // Enumeration of libunwindstack's error codes.
167  // NB: the integral representations of the two enums are different.
168  enum StackUnwindError {
169    UNWIND_ERROR_UNKNOWN = 0;
170    UNWIND_ERROR_NONE = 1;
171    UNWIND_ERROR_MEMORY_INVALID = 2;
172    UNWIND_ERROR_UNWIND_INFO = 3;
173    UNWIND_ERROR_UNSUPPORTED = 4;
174    UNWIND_ERROR_INVALID_MAP = 5;
175    UNWIND_ERROR_MAX_FRAMES_EXCEEDED = 6;
176    UNWIND_ERROR_REPEATED_FRAME = 7;
177    UNWIND_ERROR_INVALID_ELF = 8;
178  }
179}
180
181// Individual performance sampling packet payload. Typically corresponds to a
182// stack sample on a configration-dependent counter overflow.
183// Timestamps are within the root packet (in the CLOCK_BOOTTIME domain).
184// There are three distinct views of this message:
185// * completely processed sample (callstack_iid set)
186// * indication of kernel buffer data loss (kernel_records_lost set)
187// * indication of skipped samples (sample_skipped_reason set)
188message PerfSample {
189  optional uint32 cpu = 1;
190  optional uint32 pid = 2;
191  optional uint32 tid = 3;
192
193  // Execution state that the process was sampled at.
194  optional Profiling.CpuMode cpu_mode = 5;
195
196  // Unwound callstack. Might be partial, in which case a synthetic "error"
197  // frame is appended, and |unwind_error| is set appropriately.
198  optional uint64 callstack_iid = 4;
199
200  // If set, stack unwinding was incomplete due to an error.
201  // Unset values should be treated as UNWIND_ERROR_NONE.
202  oneof optional_unwind_error { Profiling.StackUnwindError unwind_error = 16; };
203
204  // If set, indicates that this message is not a sample, but rather an
205  // indication of data loss in the ring buffer allocated for |cpu|. Such data
206  // loss occurs when the kernel has insufficient ring buffer capacity to write
207  // a record (which gets discarded). A record in this context is an individual
208  // ring buffer entry, and counts more than just sample records.
209  //
210  // The |timestamp| of the packet corresponds to the time that the producer
211  // wrote the packet for trace-sorting purposes alone, and should not be
212  // interpreted relative to the sample timestamps. This field is sufficient to
213  // detect that *some* kernel data loss happened within the trace, but not the
214  // specific time bounds of that loss (which would require tracking precedessor
215  // & successor timestamps, which is not deemed necessary at the moment).
216  optional uint64 kernel_records_lost = 17;
217
218  // If set, indicates that the profiler encountered a sample that was relevant,
219  // but was skipped.
220  enum SampleSkipReason {
221    PROFILER_SKIP_UNKNOWN = 0;
222    PROFILER_SKIP_READ_STAGE = 1;
223    PROFILER_SKIP_UNWIND_STAGE = 2;
224    PROFILER_SKIP_UNWIND_ENQUEUE = 3;
225  }
226  oneof optional_sample_skipped_reason {
227    SampleSkipReason sample_skipped_reason = 18;
228  };
229}
230