1 /* 2 * Copyright (C) 2015 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 #ifndef SIMPLE_PERF_RECORD_H_ 18 #define SIMPLE_PERF_RECORD_H_ 19 20 #include <string> 21 #include <vector> 22 23 #include "build_id.h" 24 #include "perf_event.h" 25 26 struct KernelMmap; 27 struct ModuleMmap; 28 struct ThreadComm; 29 struct ThreadMmap; 30 31 enum user_record_type { 32 PERF_RECORD_ATTR = 64, 33 PERF_RECORD_EVENT_TYPE, 34 PERF_RECORD_TRACING_DATA, 35 PERF_RECORD_BUILD_ID, 36 PERF_RECORD_FINISHED_ROUND, 37 }; 38 39 struct PerfSampleIpType { 40 uint64_t ip; 41 }; 42 43 struct PerfSampleTidType { 44 uint32_t pid, tid; 45 }; 46 47 struct PerfSampleTimeType { 48 uint64_t time; 49 }; 50 51 struct PerfSampleAddrType { 52 uint64_t addr; 53 }; 54 55 struct PerfSampleIdType { 56 uint64_t id; 57 }; 58 59 struct PerfSampleStreamIdType { 60 uint64_t stream_id; 61 }; 62 63 struct PerfSampleCpuType { 64 uint32_t cpu, res; 65 }; 66 67 struct PerfSamplePeriodType { 68 uint64_t period; 69 }; 70 71 // SampleId is optional at the end of a record in binary format. Its content is determined by 72 // sample_id_all and sample_type in perf_event_attr. To avoid the complexity of referring to 73 // perf_event_attr each time, we copy sample_id_all and sample_type inside the SampleId structure. 74 struct SampleId { 75 bool sample_id_all; 76 uint64_t sample_type; 77 78 PerfSampleTidType tid_data; // Valid if sample_id_all && PERF_SAMPLE_TID. 79 PerfSampleTimeType time_data; // Valid if sample_id_all && PERF_SAMPLE_TIME. 80 PerfSampleIdType id_data; // Valid if sample_id_all && PERF_SAMPLE_ID. 81 PerfSampleStreamIdType stream_id_data; // Valid if sample_id_all && PERF_SAMPLE_STREAM_ID. 82 PerfSampleCpuType cpu_data; // Valid if sample_id_all && PERF_SAMPLE_CPU. 83 84 SampleId(); 85 86 // Create the content of sample_id. It depends on the attr we use. 87 size_t CreateContent(const perf_event_attr& attr); 88 89 // Parse sample_id from binary format in the buffer pointed by p. 90 void ReadFromBinaryFormat(const perf_event_attr& attr, const char* p, const char* end); 91 92 // Write the binary format of sample_id to the buffer pointed by p. 93 void WriteToBinaryFormat(char*& p) const; 94 void Dump(size_t indent) const; 95 }; 96 97 // Usually one record contains the following three parts in order in binary format: 98 // perf_event_header (at the head of a record, containing type and size information) 99 // data depends on the record type 100 // sample_id (optional part at the end of a record) 101 // We hold the common parts (perf_event_header and sample_id) in the base class Record, and 102 // hold the type specific data part in classes derived from Record. 103 struct Record { 104 perf_event_header header; 105 SampleId sample_id; 106 107 Record(); 108 Record(const perf_event_header* pheader); 109 110 virtual ~Record() { 111 } 112 113 void Dump(size_t indent = 0) const; 114 115 protected: 116 virtual void DumpData(size_t) const { 117 } 118 }; 119 120 struct MmapRecord : public Record { 121 struct MmapRecordDataType { 122 uint32_t pid, tid; 123 uint64_t addr; 124 uint64_t len; 125 uint64_t pgoff; 126 } data; 127 std::string filename; 128 129 MmapRecord() { // For storage in std::vector. 130 } 131 132 MmapRecord(const perf_event_attr& attr, const perf_event_header* pheader); 133 std::vector<char> BinaryFormat() const; 134 135 protected: 136 void DumpData(size_t indent) const override; 137 }; 138 139 struct CommRecord : public Record { 140 struct CommRecordDataType { 141 uint32_t pid, tid; 142 } data; 143 std::string comm; 144 145 CommRecord() { 146 } 147 148 CommRecord(const perf_event_attr& attr, const perf_event_header* pheader); 149 std::vector<char> BinaryFormat() const; 150 151 protected: 152 void DumpData(size_t indent) const override; 153 }; 154 155 struct ExitRecord : public Record { 156 struct ExitRecordDataType { 157 uint32_t pid, ppid; 158 uint32_t tid, ptid; 159 uint64_t time; 160 } data; 161 162 ExitRecord(const perf_event_attr& attr, const perf_event_header* pheader); 163 164 protected: 165 void DumpData(size_t indent) const override; 166 }; 167 168 struct SampleRecord : public Record { 169 uint64_t sample_type; // sample_type is a bit mask determining which fields below are valid. 170 171 PerfSampleIpType ip_data; // Valid if PERF_SAMPLE_IP. 172 PerfSampleTidType tid_data; // Valid if PERF_SAMPLE_TID. 173 PerfSampleTimeType time_data; // Valid if PERF_SAMPLE_TIME. 174 PerfSampleAddrType addr_data; // Valid if PERF_SAMPLE_ADDR. 175 PerfSampleIdType id_data; // Valid if PERF_SAMPLE_ID. 176 PerfSampleStreamIdType stream_id_data; // Valid if PERF_SAMPLE_STREAM_ID. 177 PerfSampleCpuType cpu_data; // Valid if PERF_SAMPLE_CPU. 178 PerfSamplePeriodType period_data; // Valid if PERF_SAMPLE_PERIOD. 179 180 SampleRecord(const perf_event_attr& attr, const perf_event_header* pheader); 181 182 protected: 183 void DumpData(size_t indent) const override; 184 }; 185 186 // BuildIdRecord is defined in user-space, stored in BuildId feature section in record file. 187 struct BuildIdRecord : public Record { 188 uint32_t pid; 189 BuildId build_id; 190 std::string filename; 191 192 BuildIdRecord() { 193 } 194 195 BuildIdRecord(const perf_event_header* pheader); 196 std::vector<char> BinaryFormat() const; 197 198 protected: 199 void DumpData(size_t indent) const override; 200 }; 201 202 std::unique_ptr<const Record> ReadRecordFromBuffer(const perf_event_attr& attr, 203 const perf_event_header* pheader); 204 MmapRecord CreateMmapRecord(const perf_event_attr& attr, bool in_kernel, uint32_t pid, uint32_t tid, 205 uint64_t addr, uint64_t len, uint64_t pgoff, 206 const std::string& filename); 207 CommRecord CreateCommRecord(const perf_event_attr& attr, uint32_t pid, uint32_t tid, 208 const std::string& comm); 209 BuildIdRecord CreateBuildIdRecord(bool in_kernel, pid_t pid, const BuildId& build_id, 210 const std::string& filename); 211 #endif // SIMPLE_PERF_RECORD_H_ 212