File indexing completed on 2024-05-19 09:37:13
0001 /* 0002 SPDX-FileCopyrightText: 2015-2020 Milian Wolff <mail@milianw.de> 0003 0004 SPDX-License-Identifier: LGPL-2.1-or-later 0005 */ 0006 0007 #ifndef ACCUMULATEDTRACEDATA_H 0008 #define ACCUMULATEDTRACEDATA_H 0009 0010 #include <iosfwd> 0011 #include <tuple> 0012 #include <vector> 0013 0014 #include <fstream> 0015 0016 #include <boost/iostreams/filtering_stream.hpp> 0017 0018 #include "allocationdata.h" 0019 #include "filterparameters.h" 0020 #include "util/indices.h" 0021 0022 struct Frame 0023 { 0024 FunctionIndex functionIndex; 0025 FileIndex fileIndex; 0026 int line = 0; 0027 0028 bool operator==(const Frame& rhs) const 0029 { 0030 return functionIndex == rhs.functionIndex && fileIndex == rhs.fileIndex && line == rhs.line; 0031 } 0032 0033 bool operator<(const Frame& rhs) const 0034 { 0035 return std::tie(functionIndex, fileIndex, line) < std::tie(rhs.functionIndex, rhs.fileIndex, rhs.line); 0036 } 0037 }; 0038 0039 struct InstructionPointer 0040 { 0041 uint64_t instructionPointer = 0; 0042 ModuleIndex moduleIndex; 0043 Frame frame; 0044 std::vector<Frame> inlined; 0045 0046 bool compareWithoutAddress(const InstructionPointer& other) const 0047 { 0048 return std::tie(moduleIndex, frame) < std::tie(other.moduleIndex, other.frame); 0049 } 0050 0051 bool equalWithoutAddress(const InstructionPointer& other) const 0052 { 0053 return moduleIndex == other.moduleIndex && frame == other.frame; 0054 } 0055 }; 0056 0057 struct TraceNode 0058 { 0059 IpIndex ipIndex; 0060 TraceIndex parentIndex; 0061 }; 0062 0063 struct Allocation : public AllocationData 0064 { 0065 // backtrace entry point 0066 TraceIndex traceIndex; 0067 }; 0068 0069 /** 0070 * Information for a single call to an allocation function. 0071 */ 0072 struct AllocationInfo 0073 { 0074 uint64_t size = 0; 0075 // index into AccumulatedTraceData::allocations 0076 AllocationIndex allocationIndex; 0077 bool operator==(const AllocationInfo& rhs) const 0078 { 0079 return rhs.allocationIndex == allocationIndex && rhs.size == size; 0080 } 0081 }; 0082 0083 struct Suppression; 0084 0085 struct AccumulatedTraceData 0086 { 0087 AccumulatedTraceData(); 0088 virtual ~AccumulatedTraceData(); 0089 0090 enum ParsePass 0091 { 0092 // find time of total peak cost 0093 FirstPass, 0094 // parse individual allocations 0095 SecondPass, 0096 // GUI only: graph-building 0097 ThirdPass 0098 }; 0099 0100 virtual void handleTimeStamp(int64_t oldStamp, int64_t newStamp, bool isFinalTimeStamp, const ParsePass pass) = 0; 0101 virtual void handleAllocation(const AllocationInfo& info, const AllocationInfoIndex index) = 0; 0102 virtual void handleDebuggee(const char* command) = 0; 0103 0104 const std::string& stringify(const StringIndex stringId) const; 0105 0106 std::string prettyFunction(const std::string& function) const; 0107 0108 bool read(const std::string& inputFile, bool isReparsing); 0109 bool read(const std::string& inputFile, const ParsePass pass, bool isReparsing); 0110 bool read(boost::iostreams::filtering_istream& in, const ParsePass pass, bool isReparsing); 0111 0112 void diff(const AccumulatedTraceData& base); 0113 0114 bool shortenTemplates = false; 0115 bool fromAttached = false; 0116 FilterParameters filterParameters; 0117 0118 std::vector<Allocation> allocations; 0119 AllocationData totalCost; 0120 int64_t totalTime = 0; 0121 int64_t peakTime = 0; 0122 int64_t peakRSS = 0; 0123 0124 struct SystemInfo 0125 { 0126 int64_t pages = 0; 0127 int64_t pageSize = 0; 0128 }; 0129 SystemInfo systemInfo; 0130 0131 // our indices are sequentially increasing thus a new allocation can only ever 0132 // occur with an index larger than any other we encountered so far 0133 // this can be used to our advantage in speeding up the mapToAllocationIndex calls. 0134 TraceIndex m_maxAllocationTraceIndex; 0135 AllocationIndex m_maxAllocationIndex; 0136 // we don't want to shuffle allocations around, so instead keep a secondary 0137 // vector around for efficient index lookup 0138 std::vector<std::pair<TraceIndex, AllocationIndex>> traceIndexToAllocationIndex; 0139 0140 /// find and return the index into the @c allocations vector for the given trace index. 0141 /// if the trace index wasn't mapped before, an empty Allocation will be added 0142 /// and its index returned. 0143 AllocationIndex mapToAllocationIndex(const TraceIndex traceIndex); 0144 0145 const InstructionPointer& findIp(const IpIndex ipIndex) const; 0146 0147 TraceNode findTrace(const TraceIndex traceIndex) const; 0148 0149 bool isStopIndex(const StringIndex index) const; 0150 0151 // indices of functions that should stop the backtrace, e.g. main or static 0152 // initialization 0153 std::vector<StringIndex> stopIndices; 0154 std::vector<InstructionPointer> instructionPointers; 0155 std::vector<TraceNode> traces; 0156 std::vector<std::string> strings; 0157 std::vector<IpIndex> opNewIpIndices; 0158 0159 std::vector<AllocationInfo> allocationInfos; 0160 0161 struct ParsingState 0162 { 0163 int64_t fileSize = 0; // bytes 0164 int64_t readCompressedByte = 0; 0165 int64_t readUncompressedByte = 0; 0166 int64_t timestamp = 0; // ms 0167 ParsePass pass = ParsePass::FirstPass; 0168 bool reparsing = false; 0169 }; 0170 0171 ParsingState parsingState; 0172 0173 void applyLeakSuppressions(); 0174 std::vector<Suppression> suppressions; 0175 int64_t totalLeakedSuppressed = 0; 0176 }; 0177 0178 #endif // ACCUMULATEDTRACEDATA_H