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