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/common/perf_events.proto"; 20import "protos/perfetto/trace/profiling/profile_common.proto"; 21 22package perfetto.protos; 23 24message ProfilePacket { 25 // The following interning tables are only used in Android version Q. 26 // In newer versions, these tables are in InternedData 27 // (see protos/perfetto/trace/interned_data) and are shared across 28 // multiple ProfilePackets. 29 // For backwards compatibility, consumers need to first look up interned 30 // data in the tables within the ProfilePacket, and then, if they are empty, 31 // look up in the InternedData instead. 32 repeated InternedString strings = 1; 33 repeated Mapping mappings = 4; 34 repeated Frame frames = 2; 35 repeated Callstack callstacks = 3; 36 37 // Next ID: 9 38 message HeapSample { 39 optional uint64 callstack_id = 1; 40 // bytes allocated at this callstack. 41 optional uint64 self_allocated = 2; 42 // bytes allocated at this callstack that have been freed. 43 optional uint64 self_freed = 3; 44 // deprecated self_idle. 45 reserved 7; 46 // Bytes allocated by this callstack but not freed at the time the malloc 47 // heap usage of this process was maximal. This is only set if dump_at_max 48 // is true in HeapprofdConfig. In that case, self_allocated, self_freed and 49 // self_idle will not be set. 50 optional uint64 self_max = 8; 51 // Number of allocations that were sampled at this callstack but not freed 52 // at the time the malloc heap usage of this process was maximal. This is 53 // only set if dump_at_max is true in HeapprofdConfig. In that case, 54 // self_allocated, self_freed and self_idle will not be set. 55 optional uint64 self_max_count = 9; 56 // timestamp [opt] 57 optional uint64 timestamp = 4; 58 // Number of allocations that were sampled at this callstack. 59 optional uint64 alloc_count = 5; 60 // Number of allocations that were sampled at this callstack that have been 61 // freed. 62 optional uint64 free_count = 6; 63 } 64 65 message Histogram { 66 message Bucket { 67 // This bucket counts values from the previous bucket's (or -infinity if 68 // this is the first bucket) upper_limit (inclusive) to this upper_limit 69 // (exclusive). 70 optional uint64 upper_limit = 1; 71 // This is the highest bucket. This is set instead of the upper_limit. Any 72 // values larger or equal to the previous bucket's upper_limit are counted 73 // in this bucket. 74 optional bool max_bucket = 2; 75 // Number of values that fall into this range. 76 optional uint64 count = 3; 77 } 78 repeated Bucket buckets = 1; 79 } 80 81 message ProcessStats { 82 optional uint64 unwinding_errors = 1; 83 optional uint64 heap_samples = 2; 84 optional uint64 map_reparses = 3; 85 optional Histogram unwinding_time_us = 4; 86 optional uint64 total_unwinding_time_us = 5; 87 optional uint64 client_spinlock_blocked_us = 6; 88 } 89 90 repeated ProcessHeapSamples process_dumps = 5; 91 message ProcessHeapSamples { 92 enum ClientError { 93 CLIENT_ERROR_NONE = 0; 94 CLIENT_ERROR_HIT_TIMEOUT = 1; 95 CLIENT_ERROR_INVALID_STACK_BOUNDS = 2; 96 } 97 optional uint64 pid = 1; 98 99 // This process was profiled from startup. 100 // If false, this process was already running when profiling started. 101 optional bool from_startup = 3; 102 103 // This process was not profiled because a concurrent session was active. 104 // If this is true, samples will be empty. 105 optional bool rejected_concurrent = 4; 106 107 // This process disconnected while it was profiled. 108 // If false, the process outlived the profiling session. 109 optional bool disconnected = 6; 110 111 // If disconnected, this disconnect was caused by the client overrunning 112 // the buffer. 113 // Equivalent to client_error == CLIENT_ERROR_HIT_TIMEOUT 114 // on new S builds. 115 optional bool buffer_overran = 7; 116 117 optional ClientError client_error = 14; 118 119 // If disconnected, this disconnected was caused by the shared memory 120 // buffer being corrupted. THIS IS ALWAYS A BUG IN HEAPPROFD OR CLIENT 121 // MEMORY CORRUPTION. 122 optional bool buffer_corrupted = 8; 123 124 // If disconnected, this disconnect was caused by heapprofd exceeding 125 // guardrails during this profiling session. 126 optional bool hit_guardrail = 10; 127 128 optional string heap_name = 11; 129 optional uint64 sampling_interval_bytes = 12; 130 optional uint64 orig_sampling_interval_bytes = 13; 131 132 // Timestamp of the state of the target process that this dump represents. 133 // This can be different to the timestamp of the TracePackets for various 134 // reasons: 135 // * If disconnected is set above, this is the timestamp of last state 136 // heapprofd had of the process before it disconnected. 137 // * Otherwise, if the rate of events produced by the process is high, 138 // heapprofd might be behind. 139 // 140 // TODO(fmayer): This is MONOTONIC_COARSE. Refactor ClockSnapshot::Clock 141 // to have a type enum that we can reuse here. 142 optional uint64 timestamp = 9; 143 144 // Metadata about heapprofd. 145 optional ProcessStats stats = 5; 146 147 repeated HeapSample samples = 2; 148 } 149 150 // If this is true, the next ProfilePacket in this package_sequence_id is a 151 // continuation of this one. 152 // To get all samples for a process, accummulate its 153 // ProcessHeapSamples.samples until you see continued=false. 154 optional bool continued = 6; 155 156 // Index of this ProfilePacket on its package_sequence_id. Can be used 157 // to detect dropped data. 158 // Verify these are consecutive. 159 optional uint64 index = 7; 160} 161 162message StreamingAllocation { 163 // TODO(fmayer): Add callstack. 164 repeated uint64 address = 1; 165 repeated uint64 size = 2; 166 repeated uint64 sample_size = 3; 167 repeated uint64 clock_monotonic_coarse_timestamp = 4; 168 repeated uint32 heap_id = 5; 169 repeated uint64 sequence_number = 6; 170}; 171 172message StreamingFree { 173 // TODO(fmayer): Add callstack. 174 repeated uint64 address = 1; 175 repeated uint32 heap_id = 2; 176 repeated uint64 sequence_number = 3; 177}; 178 179// Message used to represent individual stack samples sampled at discrete 180// points in time, rather than aggregated over an interval. 181message StreamingProfilePacket { 182 // Index into InternedData.callstacks 183 repeated uint64 callstack_iid = 1; 184 // TODO(eseckler): ThreadDescriptor-based timestamps are deprecated. Replace 185 // this with ClockSnapshot-based delta encoding instead. 186 repeated int64 timestamp_delta_us = 2; 187 optional int32 process_priority = 3; 188} 189 190// Namespace for the contained enums. 191message Profiling { 192 enum CpuMode { 193 MODE_UNKNOWN = 0; 194 MODE_KERNEL = 1; 195 MODE_USER = 2; 196 // The following values aren't expected, but included for completeness: 197 MODE_HYPERVISOR = 3; 198 MODE_GUEST_KERNEL = 4; 199 MODE_GUEST_USER = 5; 200 } 201 202 // Enumeration of libunwindstack's error codes. 203 // NB: the integral representations of the two enums are different. 204 enum StackUnwindError { 205 UNWIND_ERROR_UNKNOWN = 0; 206 UNWIND_ERROR_NONE = 1; 207 UNWIND_ERROR_MEMORY_INVALID = 2; 208 UNWIND_ERROR_UNWIND_INFO = 3; 209 UNWIND_ERROR_UNSUPPORTED = 4; 210 UNWIND_ERROR_INVALID_MAP = 5; 211 UNWIND_ERROR_MAX_FRAMES_EXCEEDED = 6; 212 UNWIND_ERROR_REPEATED_FRAME = 7; 213 UNWIND_ERROR_INVALID_ELF = 8; 214 UNWIND_ERROR_SYSTEM_CALL = 9; 215 UNWIND_ERROR_THREAD_TIMEOUT = 10; 216 UNWIND_ERROR_THREAD_DOES_NOT_EXIST = 11; 217 } 218} 219 220// Individual performance sampling packet payload. Typically corresponds to a 221// stack sample on a configration-dependent counter overflow. 222// 223// Timestamps are within the root packet. This used to use the CLOCK_BOOTTIME 224// domain, but now the default is CLOCK_MONOTONIC_RAW which is compatible with 225// more event types. 226// 227// There are several distinct views of this message: 228// * completely processed sample (callstack_iid set) 229// * indication of kernel buffer data loss (kernel_records_lost set) 230// * indication of skipped samples (sample_skipped_reason set) 231// * notable event in the sampling implementation (producer_event set) 232message PerfSample { 233 optional uint32 cpu = 1; 234 optional uint32 pid = 2; 235 optional uint32 tid = 3; 236 237 // Execution state that the process was sampled at. 238 optional Profiling.CpuMode cpu_mode = 5; 239 240 // Value of the timebase counter (since the event was configured, no deltas). 241 optional uint64 timebase_count = 6; 242 243 // Unwound callstack. Might be partial, in which case a synthetic "error" 244 // frame is appended, and |unwind_error| is set accordingly. 245 optional uint64 callstack_iid = 4; 246 247 // If set, stack unwinding was incomplete due to an error. 248 // Unset values should be treated as UNWIND_ERROR_NONE. 249 oneof optional_unwind_error { Profiling.StackUnwindError unwind_error = 16; }; 250 251 // If set, indicates that this message is not a sample, but rather an 252 // indication of data loss in the ring buffer allocated for |cpu|. Such data 253 // loss occurs when the kernel has insufficient ring buffer capacity to write 254 // a record (which gets discarded). A record in this context is an individual 255 // ring buffer entry, and counts more than just sample records. 256 // 257 // The |timestamp| of the packet corresponds to the time that the producer 258 // wrote the packet for trace-sorting purposes alone, and should not be 259 // interpreted relative to the sample timestamps. This field is sufficient to 260 // detect that *some* kernel data loss happened within the trace, but not the 261 // specific time bounds of that loss (which would require tracking precedessor 262 // & successor timestamps, which is not deemed necessary at the moment). 263 optional uint64 kernel_records_lost = 17; 264 265 // If set, indicates that the profiler encountered a sample that was relevant, 266 // but was skipped. 267 enum SampleSkipReason { 268 PROFILER_SKIP_UNKNOWN = 0; 269 PROFILER_SKIP_READ_STAGE = 1; 270 PROFILER_SKIP_UNWIND_STAGE = 2; 271 PROFILER_SKIP_UNWIND_ENQUEUE = 3; 272 } 273 oneof optional_sample_skipped_reason { 274 SampleSkipReason sample_skipped_reason = 18; 275 }; 276 277 // A notable event within the sampling implementation. 278 message ProducerEvent { 279 enum DataSourceStopReason { 280 PROFILER_STOP_UNKNOWN = 0; 281 PROFILER_STOP_GUARDRAIL = 1; 282 } 283 oneof optional_source_stop_reason { 284 DataSourceStopReason source_stop_reason = 1; 285 } 286 } 287 optional ProducerEvent producer_event = 19; 288} 289 290// Submessage for TracePacketDefaults. 291message PerfSampleDefaults { 292 // The sampling timebase. Might not be identical to the data source config if 293 // the implementation decided to default/override some parameters. 294 optional PerfEvents.Timebase timebase = 1; 295}