| /* |
| * Copyright (C) 2015 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #ifndef SIMPLE_PERF_RECORD_H_ |
| #define SIMPLE_PERF_RECORD_H_ |
| |
| #include <string> |
| #include <vector> |
| |
| #include "build_id.h" |
| #include "perf_event.h" |
| |
| struct KernelMmap; |
| struct ModuleMmap; |
| struct ThreadComm; |
| struct ThreadMmap; |
| |
| enum user_record_type { |
| PERF_RECORD_ATTR = 64, |
| PERF_RECORD_EVENT_TYPE, |
| PERF_RECORD_TRACING_DATA, |
| PERF_RECORD_BUILD_ID, |
| PERF_RECORD_FINISHED_ROUND, |
| }; |
| |
| struct PerfSampleIpType { |
| uint64_t ip; |
| }; |
| |
| struct PerfSampleTidType { |
| uint32_t pid, tid; |
| }; |
| |
| struct PerfSampleTimeType { |
| uint64_t time; |
| }; |
| |
| struct PerfSampleAddrType { |
| uint64_t addr; |
| }; |
| |
| struct PerfSampleIdType { |
| uint64_t id; |
| }; |
| |
| struct PerfSampleStreamIdType { |
| uint64_t stream_id; |
| }; |
| |
| struct PerfSampleCpuType { |
| uint32_t cpu, res; |
| }; |
| |
| struct PerfSamplePeriodType { |
| uint64_t period; |
| }; |
| |
| // SampleId is optional at the end of a record in binary format. Its content is determined by |
| // sample_id_all and sample_type in perf_event_attr. To avoid the complexity of referring to |
| // perf_event_attr each time, we copy sample_id_all and sample_type inside the SampleId structure. |
| struct SampleId { |
| bool sample_id_all; |
| uint64_t sample_type; |
| |
| PerfSampleTidType tid_data; // Valid if sample_id_all && PERF_SAMPLE_TID. |
| PerfSampleTimeType time_data; // Valid if sample_id_all && PERF_SAMPLE_TIME. |
| PerfSampleIdType id_data; // Valid if sample_id_all && PERF_SAMPLE_ID. |
| PerfSampleStreamIdType stream_id_data; // Valid if sample_id_all && PERF_SAMPLE_STREAM_ID. |
| PerfSampleCpuType cpu_data; // Valid if sample_id_all && PERF_SAMPLE_CPU. |
| |
| SampleId(); |
| |
| // Create the content of sample_id. It depends on the attr we use. |
| size_t CreateContent(const perf_event_attr& attr); |
| |
| // Parse sample_id from binary format in the buffer pointed by p. |
| void ReadFromBinaryFormat(const perf_event_attr& attr, const char* p, const char* end); |
| |
| // Write the binary format of sample_id to the buffer pointed by p. |
| void WriteToBinaryFormat(char*& p) const; |
| void Dump(size_t indent) const; |
| }; |
| |
| // Usually one record contains the following three parts in order in binary format: |
| // perf_event_header (at the head of a record, containing type and size information) |
| // data depends on the record type |
| // sample_id (optional part at the end of a record) |
| // We hold the common parts (perf_event_header and sample_id) in the base class Record, and |
| // hold the type specific data part in classes derived from Record. |
| struct Record { |
| perf_event_header header; |
| SampleId sample_id; |
| |
| Record(); |
| Record(const perf_event_header* pheader); |
| |
| virtual ~Record() { |
| } |
| |
| void Dump(size_t indent = 0) const; |
| |
| protected: |
| virtual void DumpData(size_t) const { |
| } |
| }; |
| |
| struct MmapRecord : public Record { |
| struct MmapRecordDataType { |
| uint32_t pid, tid; |
| uint64_t addr; |
| uint64_t len; |
| uint64_t pgoff; |
| } data; |
| std::string filename; |
| |
| MmapRecord() { // For storage in std::vector. |
| } |
| |
| MmapRecord(const perf_event_attr& attr, const perf_event_header* pheader); |
| std::vector<char> BinaryFormat() const; |
| |
| protected: |
| void DumpData(size_t indent) const override; |
| }; |
| |
| struct CommRecord : public Record { |
| struct CommRecordDataType { |
| uint32_t pid, tid; |
| } data; |
| std::string comm; |
| |
| CommRecord() { |
| } |
| |
| CommRecord(const perf_event_attr& attr, const perf_event_header* pheader); |
| std::vector<char> BinaryFormat() const; |
| |
| protected: |
| void DumpData(size_t indent) const override; |
| }; |
| |
| struct ExitRecord : public Record { |
| struct ExitRecordDataType { |
| uint32_t pid, ppid; |
| uint32_t tid, ptid; |
| uint64_t time; |
| } data; |
| |
| ExitRecord(const perf_event_attr& attr, const perf_event_header* pheader); |
| |
| protected: |
| void DumpData(size_t indent) const override; |
| }; |
| |
| struct SampleRecord : public Record { |
| uint64_t sample_type; // sample_type is a bit mask determining which fields below are valid. |
| |
| PerfSampleIpType ip_data; // Valid if PERF_SAMPLE_IP. |
| PerfSampleTidType tid_data; // Valid if PERF_SAMPLE_TID. |
| PerfSampleTimeType time_data; // Valid if PERF_SAMPLE_TIME. |
| PerfSampleAddrType addr_data; // Valid if PERF_SAMPLE_ADDR. |
| PerfSampleIdType id_data; // Valid if PERF_SAMPLE_ID. |
| PerfSampleStreamIdType stream_id_data; // Valid if PERF_SAMPLE_STREAM_ID. |
| PerfSampleCpuType cpu_data; // Valid if PERF_SAMPLE_CPU. |
| PerfSamplePeriodType period_data; // Valid if PERF_SAMPLE_PERIOD. |
| |
| SampleRecord(const perf_event_attr& attr, const perf_event_header* pheader); |
| |
| protected: |
| void DumpData(size_t indent) const override; |
| }; |
| |
| // BuildIdRecord is defined in user-space, stored in BuildId feature section in record file. |
| struct BuildIdRecord : public Record { |
| uint32_t pid; |
| BuildId build_id; |
| std::string filename; |
| |
| BuildIdRecord() { |
| } |
| |
| BuildIdRecord(const perf_event_header* pheader); |
| std::vector<char> BinaryFormat() const; |
| |
| protected: |
| void DumpData(size_t indent) const override; |
| }; |
| |
| std::unique_ptr<const Record> ReadRecordFromBuffer(const perf_event_attr& attr, |
| const perf_event_header* pheader); |
| MmapRecord CreateMmapRecord(const perf_event_attr& attr, bool in_kernel, uint32_t pid, uint32_t tid, |
| uint64_t addr, uint64_t len, uint64_t pgoff, |
| const std::string& filename); |
| CommRecord CreateCommRecord(const perf_event_attr& attr, uint32_t pid, uint32_t tid, |
| const std::string& comm); |
| BuildIdRecord CreateBuildIdRecord(bool in_kernel, pid_t pid, const BuildId& build_id, |
| const std::string& filename); |
| #endif // SIMPLE_PERF_RECORD_H_ |