Home | History | Annotate | Download | only in simpleperf
      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