1/* 2 * Copyright (C) 2022 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 17// The file format generated by cmd_report_sample.proto is as below: 18// char magic[10] = "SIMPLEPERF"; 19// LittleEndian16(version) = 1; 20// LittleEndian32(record_size_0) 21// message Record(record_0) (having record_size_0 bytes) 22// LittleEndian32(record_size_1) 23// message Record(record_1) (having record_size_1 bytes) 24// ... 25// LittleEndian32(record_size_N) 26// message Record(record_N) (having record_size_N bytes) 27// LittleEndian32(0) 28 29syntax = "proto2"; 30option optimize_for = LITE_RUNTIME; 31package simpleperf_report_proto; 32option java_package = "com.android.tools.profiler.proto"; 33option java_outer_classname = "SimpleperfReport"; 34 35message Sample { 36 // Monotonic clock time in nanoseconds. On kernel < 4.1, it's perf clock instead. 37 optional uint64 time = 1; 38 optional int32 thread_id = 2; 39 40 message CallChainEntry { 41 // virtual address of the instruction in elf file 42 optional uint64 vaddr_in_file = 1; 43 44 // index of the elf file containing the instruction 45 optional uint32 file_id = 2; 46 47 // symbol_id refers to the name of the function containing the instruction. 48 // If the function name is found, it is a valid index in the symbol table 49 // of File with 'id' field being file_id, otherwise it is -1. 50 optional int32 symbol_id = 3; 51 52 enum ExecutionType { 53 // methods belong to native libraries, AOT compiled JVM code and ART methods not used near 54 // JVM methods 55 NATIVE_METHOD = 0; 56 INTERPRETED_JVM_METHOD = 1; 57 JIT_JVM_METHOD = 2; 58 // ART methods used near JVM methods. It's shown only when --show-art-frames is used. 59 ART_METHOD = 3; 60 } 61 optional ExecutionType execution_type = 4 [default = NATIVE_METHOD]; 62 } 63 64 repeated CallChainEntry callchain = 3; 65 66 // Simpleperf generates one sample whenever a specified amount of events happen 67 // while running a monitored thread. So each sample belongs to one event type. 68 // Event type can be cpu-cycles, cpu-clock, sched:sched_switch or other types. 69 // By using '-e' option, we can ask simpleperf to record samples for one or more 70 // event types. 71 // Each event type generates samples independently. But recording more event types 72 // will cost more cpu time generating samples, which may affect the monitored threads 73 // and sample lost rate. 74 // event_count field shows the count of the events (belong to the sample's event type) 75 // that have happened since last sample (belong to the sample's event type) for the 76 // same thread. However, if there are lost samples between current sample and previous 77 // sample, the event_count is the count of events from the last lost sample. 78 optional uint64 event_count = 4; 79 80 // An index in meta_info.event_type, shows which event type current sample belongs to. 81 optional uint32 event_type_id = 5; 82 83 message UnwindingResult { 84 // error code provided by libunwindstack, in 85 // https://cs.android.com/android/platform/superproject/+/master:system/unwinding/libunwindstack/include/unwindstack/Error.h 86 optional uint32 raw_error_code = 1; 87 // error addr provided by libunwindstack 88 optional uint64 error_addr = 2; 89 90 // error code interpreted by simpleperf 91 enum ErrorCode { 92 ERROR_NONE = 0; // No error 93 ERROR_UNKNOWN = 1; // Error not interpreted by simpleperf, see raw_error_code 94 ERROR_NOT_ENOUGH_STACK = 2; // Simpleperf doesn't record enough stack data 95 ERROR_MEMORY_INVALID = 3; // Memory read failed 96 ERROR_UNWIND_INFO = 4; // No debug info in binary to support unwinding 97 ERROR_INVALID_MAP = 5; // Unwind in an invalid map 98 ERROR_MAX_FRAME_EXCEEDED = 6; // Stopped at MAX_UNWINDING_FRAMES, which is 512. 99 ERROR_REPEATED_FRAME = 7; // The last frame has the same pc/sp as the next. 100 ERROR_INVALID_ELF = 8; // Unwind in an invalid elf file 101 } 102 optional ErrorCode error_code = 3; 103 } 104 105 // Unwinding result is provided for samples without a complete callchain, when recorded with 106 // --keep-failed-unwinding-result or --keep-failed-unwinding-debug-info. 107 optional UnwindingResult unwinding_result = 6; 108} 109 110message LostSituation { 111 optional uint64 sample_count = 1; 112 optional uint64 lost_count = 2; 113} 114 115message File { 116 // unique id for each file, starting from 0, and add 1 each time. 117 optional uint32 id = 1; 118 119 // file path, like /system/lib/libc.so. 120 optional string path = 2; 121 122 // symbol table of the file. 123 repeated string symbol = 3; 124 125 // mangled symbol table of the file. 126 repeated string mangled_symbol = 4; 127} 128 129message Thread { 130 optional uint32 thread_id = 1; 131 optional uint32 process_id = 2; 132 optional string thread_name = 3; 133} 134 135message MetaInfo { 136 repeated string event_type = 1; 137 optional string app_package_name = 2; 138 optional string app_type = 3; // debuggable, profileable or non_profileable 139 optional string android_sdk_version = 4; 140 optional string android_build_type = 5; // user, userdebug or eng 141 142 // True if the profile is recorded with --trace-offcpu option. 143 optional bool trace_offcpu = 6; 144} 145 146// Thread context switch info. It is available when MetaInfo.trace_offcpu = true. 147message ContextSwitch { 148 // If true, the thread is scheduled on cpu, otherwise it is scheduled off cpu. 149 optional bool switch_on = 1; 150 151 // Monotonic clock time in nanoseconds. On kernel < 4.1, it's perf clock instead. 152 optional uint64 time = 2; 153 optional uint32 thread_id = 3; 154} 155 156message Record { 157 oneof record_data { 158 Sample sample = 1; 159 LostSituation lost = 2; 160 File file = 3; 161 Thread thread = 4; 162 MetaInfo meta_info = 5; 163 ContextSwitch context_switch = 6; 164 } 165}