1 /* 2 * Copyright (c) 2016, Google Inc. 3 * All rights reserved. 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef PERFTOOLS_PERF_DATA_HANDLER_H_ 9 #define PERFTOOLS_PERF_DATA_HANDLER_H_ 10 11 #include <vector> 12 13 #include "int_compat.h" 14 #include "string_compat.h" 15 #include "quipper/perf_data.pb.h" 16 17 namespace perftools { 18 19 // PerfDataHandler defines an interface for processing PerfDataProto 20 // with normalized sample fields (i.e., materializing mappings, 21 // filenames, and build-ids). 22 // 23 // To use, subclass PerfDataHandler and implement the required 24 // methods, then call Process() and handler will be called for every 25 // SAMPLE event. 26 // 27 // Context events' pointers to Mappings will be constant for the lifetime of a 28 // process, so subclasses may use the pointer values as a key to various caches 29 // they may want to maintain as part of the output data creation. 30 class PerfDataHandler { 31 public: 32 struct Mapping { 33 public: MappingMapping34 Mapping(const string* filename, const string* build_id, uint64 start, 35 uint64 limit, uint64 file_offset, uint64 filename_md5_prefix) 36 : filename(filename), 37 build_id(build_id), 38 start(start), 39 limit(limit), 40 file_offset(file_offset), 41 filename_md5_prefix(filename_md5_prefix) {} 42 43 // filename and build_id are pointers into the provided 44 // PerfDataProto and may be nullptr. 45 const string* filename; 46 const string* build_id; 47 uint64 start; 48 uint64 limit; // limit=ceiling. 49 uint64 file_offset; 50 uint64 filename_md5_prefix; 51 52 private: MappingMapping53 Mapping() {} 54 }; 55 56 struct Location { LocationLocation57 Location() : ip(0), mapping(nullptr) {} 58 59 uint64 ip; 60 const Mapping* mapping; 61 }; 62 63 struct BranchStackPair { BranchStackPairBranchStackPair64 BranchStackPair() : mispredicted(false) {} 65 66 Location from; 67 Location to; 68 bool mispredicted; 69 }; 70 71 struct SampleContext { SampleContextSampleContext72 SampleContext(const quipper::PerfDataProto::EventHeader &h, 73 const quipper::PerfDataProto::SampleEvent &s) 74 : header(h), 75 sample(s), 76 main_mapping(nullptr), 77 sample_mapping(nullptr), 78 file_attrs_index(-1) {} 79 80 // The event's header. 81 const quipper::PerfDataProto::EventHeader &header; 82 // An event. 83 const quipper::PerfDataProto::SampleEvent &sample; 84 // The mapping for the main binary for this program. 85 const Mapping* main_mapping; 86 // The mapping in which event.ip is found. 87 const Mapping* sample_mapping; 88 // Locations corresponding to event.callchain. 89 std::vector<Location> callchain; 90 // Locations corresponding to entries in event.branch_stack. 91 std::vector<BranchStackPair> branch_stack; 92 // An index into PerfDataProto.file_attrs or -1 if 93 // unavailable. 94 int64 file_attrs_index; 95 }; 96 97 struct CommContext { 98 // A comm event. 99 const quipper::PerfDataProto::CommEvent* comm; 100 }; 101 102 struct MMapContext { 103 // A memory mapping to be passed to the subclass. Should be the same mapping 104 // that gets added to pid_to_mmaps_. 105 const PerfDataHandler::Mapping* mapping; 106 // The process id used as a key to pid_to_mmaps_. 107 uint32 pid; 108 }; 109 110 PerfDataHandler(const PerfDataHandler&) = delete; 111 PerfDataHandler& operator=(const PerfDataHandler&) = delete; 112 113 // Process initiates processing of perf_proto. handler.Sample will 114 // be called for every event in the profile. 115 static void Process(const quipper::PerfDataProto& perf_data, 116 PerfDataHandler* handler); 117 ~PerfDataHandler()118 virtual ~PerfDataHandler() {} 119 120 // Implement these callbacks: 121 // Called for every sample. 122 virtual void Sample(const SampleContext& sample) = 0; 123 // When comm.pid()==comm.tid() it indicates an exec() happened. 124 virtual void Comm(const CommContext& comm) = 0; 125 // Called for every mmap event. 126 virtual void MMap(const MMapContext& mmap) = 0; 127 128 protected: 129 PerfDataHandler(); 130 }; 131 132 } // namespace perftools 133 134 #endif // PERFTOOLS_PERF_DATA_HANDLER_H_ 135