1 /* 2 SPDX-FileCopyrightText: 2015-2020 Milian Wolff <mail@milianw.de> 3 4 SPDX-License-Identifier: LGPL-2.1-or-later 5 */ 6 7 #ifndef ACCUMULATEDTRACEDATA_H 8 #define ACCUMULATEDTRACEDATA_H 9 10 #include <iosfwd> 11 #include <tuple> 12 #include <vector> 13 14 #include <fstream> 15 16 #include <boost/iostreams/filtering_stream.hpp> 17 18 #include "allocationdata.h" 19 #include "filterparameters.h" 20 #include "util/indices.h" 21 22 struct Frame 23 { 24 FunctionIndex functionIndex; 25 FileIndex fileIndex; 26 int line = 0; 27 28 bool operator==(const Frame& rhs) const 29 { 30 return functionIndex == rhs.functionIndex && 31 fileIndex == rhs.fileIndex && 32 line == rhs.line; 33 } 34 35 bool operator<(const Frame& rhs) const 36 { 37 return std::tie(functionIndex, fileIndex, line) < std::tie(rhs.functionIndex, rhs.fileIndex, rhs.line); 38 } 39 }; 40 41 struct InstructionPointer 42 { 43 uint64_t instructionPointer = 0; 44 ModuleIndex moduleIndex; 45 Frame frame; 46 std::vector<Frame> inlined; 47 compareWithoutAddressInstructionPointer48 bool compareWithoutAddress(const InstructionPointer& other) const 49 { 50 return std::tie(moduleIndex, frame) < std::tie(other.moduleIndex, other.frame); 51 } 52 equalWithoutAddressInstructionPointer53 bool equalWithoutAddress(const InstructionPointer& other) const 54 { 55 return moduleIndex == other.moduleIndex && frame == other.frame; 56 } 57 }; 58 59 struct TraceNode 60 { 61 IpIndex ipIndex; 62 TraceIndex parentIndex; 63 }; 64 65 struct Allocation : public AllocationData 66 { 67 // backtrace entry point 68 TraceIndex traceIndex; 69 }; 70 71 /** 72 * Information for a single call to an allocation function. 73 */ 74 struct AllocationInfo 75 { 76 uint64_t size = 0; 77 // index into AccumulatedTraceData::allocations 78 AllocationIndex allocationIndex; 79 bool operator==(const AllocationInfo& rhs) const 80 { 81 return rhs.allocationIndex == allocationIndex && rhs.size == size; 82 } 83 }; 84 85 struct Suppression; 86 87 struct AccumulatedTraceData 88 { 89 AccumulatedTraceData(); 90 virtual ~AccumulatedTraceData(); 91 92 enum ParsePass 93 { 94 // find time of total peak cost 95 FirstPass, 96 // parse individual allocations 97 SecondPass, 98 // GUI only: graph-building 99 ThirdPass 100 }; 101 102 virtual void handleTimeStamp(int64_t oldStamp, int64_t newStamp, bool isFinalTimeStamp, const ParsePass pass) = 0; 103 virtual void handleAllocation(const AllocationInfo& info, const AllocationInfoIndex index) = 0; 104 virtual void handleDebuggee(const char* command) = 0; 105 106 const std::string& stringify(const StringIndex stringId) const; 107 108 std::string prettyFunction(const std::string& function) const; 109 110 bool read(const std::string& inputFile, bool isReparsing); 111 bool read(const std::string& inputFile, const ParsePass pass, bool isReparsing); 112 bool read(boost::iostreams::filtering_istream& in, const ParsePass pass, bool isReparsing); 113 114 void diff(const AccumulatedTraceData& base); 115 116 bool shortenTemplates = false; 117 bool fromAttached = false; 118 FilterParameters filterParameters; 119 120 std::vector<Allocation> allocations; 121 AllocationData totalCost; 122 int64_t totalTime = 0; 123 int64_t peakTime = 0; 124 int64_t peakRSS = 0; 125 126 struct SystemInfo 127 { 128 int64_t pages = 0; 129 int64_t pageSize = 0; 130 }; 131 SystemInfo systemInfo; 132 133 // our indices are sequentially increasing thus a new allocation can only ever 134 // occur with an index larger than any other we encountered so far 135 // this can be used to our advantage in speeding up the mapToAllocationIndex calls. 136 TraceIndex m_maxAllocationTraceIndex; 137 AllocationIndex m_maxAllocationIndex; 138 // we don't want to shuffle allocations around, so instead keep a secondary 139 // vector around for efficient index lookup 140 std::vector<std::pair<TraceIndex, AllocationIndex>> traceIndexToAllocationIndex; 141 142 /// find and return the index into the @c allocations vector for the given trace index. 143 /// if the trace index wasn't mapped before, an empty Allocation will be added 144 /// and its index returned. 145 AllocationIndex mapToAllocationIndex(const TraceIndex traceIndex); 146 147 const InstructionPointer& findIp(const IpIndex ipIndex) const; 148 149 TraceNode findTrace(const TraceIndex traceIndex) const; 150 151 bool isStopIndex(const StringIndex index) const; 152 153 // indices of functions that should stop the backtrace, e.g. main or static 154 // initialization 155 std::vector<StringIndex> stopIndices; 156 std::vector<InstructionPointer> instructionPointers; 157 std::vector<TraceNode> traces; 158 std::vector<std::string> strings; 159 std::vector<IpIndex> opNewIpIndices; 160 161 std::vector<AllocationInfo> allocationInfos; 162 163 struct ParsingState 164 { 165 int64_t fileSize = 0; // bytes 166 int64_t readCompressedByte = 0; 167 int64_t readUncompressedByte = 0; 168 int64_t timestamp = 0; // ms 169 ParsePass pass = ParsePass::FirstPass; 170 bool reparsing = false; 171 }; 172 173 ParsingState parsingState; 174 175 void applyLeakSuppressions(); 176 std::vector<Suppression> suppressions; 177 int64_t totalLeakedSuppressed = 0; 178 }; 179 180 #endif // ACCUMULATEDTRACEDATA_H 181