1 /* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 #ifndef NATIVE_HOOK_FILTER_H 16 #define NATIVE_HOOK_FILTER_H 17 #include <set> 18 #include "common_types.pb.h" 19 #include "native_hook_result.pb.h" 20 #include "numerical_to_string.h" 21 #include "offline_symbolization_filter.h" 22 #include "stat_filter.h" 23 #include "string_help.h" 24 #include "symbols_file.h" 25 namespace SysTuning { 26 namespace TraceStreamer { 27 using namespace OHOS::Developtools::HiPerf; 28 class NativeHookFrameInfo { 29 public: NativeHookFrameInfo()30 NativeHookFrameInfo() 31 : ip_(INVALID_UINT64), 32 sp_(INVALID_UINT64), 33 symbolIndex_(INVALID_UINT64), 34 filePathIndex_(INVALID_UINT64), 35 offset_(INVALID_UINT64), 36 symbolOffset_(INVALID_UINT64) 37 { 38 } NativeHookFrameInfo(uint64_t ip,uint64_t sp,uint64_t symbolIndex,uint64_t filePathIndex,uint64_t offset,uint64_t symbolOffset)39 NativeHookFrameInfo(uint64_t ip, 40 uint64_t sp, 41 uint64_t symbolIndex, 42 uint64_t filePathIndex, 43 uint64_t offset, 44 uint64_t symbolOffset) 45 : ip_(ip), 46 sp_(sp), 47 symbolIndex_(symbolIndex), 48 filePathIndex_(filePathIndex), 49 offset_(offset), 50 symbolOffset_(symbolOffset) 51 { 52 } ~NativeHookFrameInfo()53 ~NativeHookFrameInfo() {} 54 uint64_t ip_; 55 uint64_t sp_; 56 uint64_t symbolIndex_; 57 uint64_t filePathIndex_; 58 uint64_t offset_; 59 uint64_t symbolOffset_; 60 }; 61 struct CommHookData { 62 size_t size = 0; 63 std::unique_ptr<BatchNativeHookData> datas = nullptr; 64 }; 65 class NativeHookFilter : public OfflineSymbolizationFilter { 66 public: 67 NativeHookFilter(TraceDataCache*, const TraceStreamerFilters*); 68 NativeHookFilter(const NativeHookFilter&) = delete; 69 NativeHookFilter& operator=(const NativeHookFilter&) = delete; 70 ~NativeHookFilter() override = default; 71 72 public: 73 void MaybeParseNativeHookMainEvent(uint64_t timeStamp, std::unique_ptr<NativeHookMetaData> nativeHookMetaData); 74 void ParseConfigInfo(ProtoReader::BytesView& protoData); 75 void AppendStackMaps(uint32_t ipid, uint32_t stackid, std::vector<uint64_t>& frames); 76 void AppendFrameMaps(uint32_t ipid, uint32_t frameMapId, const ProtoReader::BytesView& bytesView); 77 void AppendFilePathMaps(uint32_t ipid, uint32_t filePathId, uint64_t fileIndex); 78 void AppendSymbolMap(uint32_t ipid, uint32_t symId, uint64_t symbolIndex); 79 void AppendThreadNameMap(uint32_t ipid, uint32_t nameId, uint64_t threadNameIndex); 80 void ParseMapsEvent(std::unique_ptr<NativeHookMetaData>& nativeHookMetaData); 81 void ParseSymbolTableEvent(std::unique_ptr<NativeHookMetaData>& nativeHookMetaData); 82 void ParseTagEvent(const ProtoReader::BytesView& bytesView); 83 void FinishParseNativeHookData(); 84 bool NativeHookReloadElfSymbolTable(const std::vector<std::unique_ptr<SymbolsFile>>& symbolsFiles); 85 CommHookData& GetCommHookData(); 86 ProfilerPluginData* GetHookPluginData(); 87 void SerializeHookCommDataToString(); IsSingleProcData()88 const bool IsSingleProcData() 89 { 90 return isSingleProcData_; 91 } 92 93 private: 94 void ProcSymbolTable(uint32_t ipid, uint32_t filePathId, std::shared_ptr<ProtoReader::SymbolTable_Reader> reader); 95 void FilterNativeHookMainEvent(size_t num); 96 void ParseStatisticEvent(uint64_t timeStamp, const ProtoReader::BytesView& bytesView); 97 template <class T1, class T2> 98 void UpdateMap(std::unordered_map<T1, T2>& sourceMap, T1 key, T2 value); 99 void ParseAllocEvent(uint64_t timeStamp, const ProtoReader::BytesView& bytesView); 100 void ParseFreeEvent(uint64_t timeStamp, const ProtoReader::BytesView& bytesView); 101 void SetFreeEventCallChainId(uint32_t& callChainId, 102 uint32_t ipid, 103 uint32_t itid, 104 const ProtoReader::FreeEvent_Reader& freeEventReader); 105 void ParseMmapEvent(uint64_t timeStamp, const ProtoReader::BytesView& bytesView); 106 void SetMmapEventCallChainId(uint32_t& callChainId, 107 uint32_t ipid, 108 uint32_t itid, 109 const ProtoReader::MmapEvent_Reader& mMapEventReader); 110 void ParseMunmapEvent(uint64_t timeStamp, const ProtoReader::BytesView& bytesView); 111 void SetMunmapEventCallChainId(uint32_t& callChainId, 112 uint32_t ipid, 113 uint32_t itid, 114 const ProtoReader::MunmapEvent_Reader& mUnmapEventReader); 115 116 void MaybeUpdateCurrentSizeDur(uint64_t row, uint64_t timeStamp, bool isMalloc); 117 void UpdateThreadNameWithNativeHookData() const; 118 void GetCallIdToLastLibId(); 119 void GetNativeHookFrameVaddrs(); 120 void UpdateSymbolIdsForSymbolizationFailed(); 121 void ParseFramesInOfflineSymbolizationMode(); 122 void ParseFramesInCallStackCompressedMode(); 123 void ParseFramesWithOutCallStackCompressedMode(); 124 void ParseSymbolizedNativeHookFrame(); 125 bool GetIpsWitchNeedResymbolization(uint64_t ipid, DataIndex filePathId, std::set<uint64_t>& ips); 126 template <class T> 127 void UpdateSymbolTablePtrAndStValueToSymAddrMap(T* firstSymbolAddr, 128 const int size, 129 std::shared_ptr<ProtoReader::SymbolTable_Reader> reader); 130 void FillOfflineSymbolizationFrames(std::map<uint64_t, std::shared_ptr<std::vector<uint64_t>>>::iterator mapItor); 131 void ReparseStacksWithAddrRange(uint64_t start, uint64_t end); 132 void ReparseStacksWithDifferentMeans(); 133 void CompressStackAndFrames(uint64_t row, ProtoReader::RepeatedDataAreaIterator<ProtoReader::BytesView> frames); 134 std::tuple<uint64_t, uint64_t> GetNeedUpdateProcessMapsAddrRange(uint32_t ipid, 135 uint64_t startAddr, 136 uint64_t endAddr); 137 std::unique_ptr<NativeHookFrameInfo> ParseFrame(uint64_t row, const ProtoReader::DataArea& frame); 138 template <class T> 139 void UpdateFilePathIdAndStValueToSymAddrMap(T* firstSymbolAddr, const int size, uint32_t filePathId); 140 uint64_t GetMemMapSubTypeWithAddr(uint64_t addr); 141 void UpdateAnonMmapDataDbIndex(uint64_t addr, uint32_t size, uint64_t row); 142 void UpdateLastCallerPathAndSymbolIndexs(); 143 void UpdateFilePathIndexToCallStackRowMap(size_t row, DataIndex filePathIndex); 144 145 private: 146 // first key is addr, second key is size, value is set<row> in db 147 // mmap update anonymous memory tag always use the anonMmapData_ value 148 DoubleMap<uint64_t, uint32_t, std::shared_ptr<std::set<uint64_t>>> anonMmapData_; 149 std::unique_ptr<ProfilerPluginData> hookPluginData_ = nullptr; 150 DoubleMap<uint32_t, uint32_t, uint64_t> ipidToSymIdToSymIndex_; 151 DoubleMap<uint32_t, uint32_t, uint64_t> ipidToFilePathIdToFileIndex_; 152 DoubleMap<uint32_t, uint32_t, std::shared_ptr<const ProtoReader::BytesView>> ipidToFrameIdToFrameBytes_; 153 std::unordered_map<DataIndex, std::shared_ptr<std::set<size_t>>> filePathIndexToFrameTableRowMap_ = {}; 154 std::multimap<uint64_t, std::unique_ptr<NativeHookMetaData>> tsToMainEventsMap_ = {}; 155 std::map<uint64_t /* ipidWithStackIdIndex */, std::shared_ptr<std::vector<uint64_t>>> reparseStackIdToFramesMap_ = 156 {}; 157 std::map<uint64_t /* ipidWithStackIdIndex */, std::shared_ptr<std::vector<uint64_t>>> allStackIdToFramesMap_ = {}; 158 std::map<uint64_t /* ipidWithStackIdIndex */, std::shared_ptr<std::vector<uint64_t>>> stackIdToFramesMap_ = {}; 159 std::map<uint32_t, uint64_t> callChainIdToStackHashValueMap_ = {}; 160 std::unordered_map<uint64_t, std::vector<uint64_t>> stackHashValueToFramesHashMap_ = {}; 161 std::unordered_map<uint64_t, std::unique_ptr<NativeHookFrameInfo>> frameHashToFrameInfoMap_ = {}; 162 std::unordered_map<uint64_t /* ipidWithThreadNameIdIndex */, uint64_t> threadNameIdToThreadNameIndex_ = {}; 163 std::unordered_map<uint32_t, std::tuple<uint64_t, uint64_t>> callIdToLastCallerPathIndex_ = {}; 164 std::unordered_map<uint64_t, std::string> functionNameIndexToVaddr_ = {}; 165 std::unordered_map<uint64_t, uint32_t> stackHashValueToCallChainIdMap_ = {}; 166 std::unordered_map<uint32_t, uint64_t> itidToThreadNameId_ = {}; 167 std::unordered_map<uint32_t, uint32_t> stackIdToCallChainIdMap_ = {}; 168 std::unordered_map<uint64_t, uint64_t>* addrToAllocEventRow_ = nullptr; 169 std::unordered_map<uint64_t, uint64_t>* addrToMmapEventRow_ = nullptr; 170 std::set<DataIndex> invalidLibPathIndexs_ = {}; 171 std::deque<std::string> vaddrs_ = {}; 172 // munmap update anonymous or named memory tag always use the last addrToMmapTag_ value 173 std::unordered_map<uint64_t, uint64_t> addrToMmapTag_ = {}; 174 std::hash<std::string_view> hashFun_; 175 bool isOfflineSymbolizationMode_ = false; 176 bool isCallStackCompressedMode_ = false; 177 bool isStringCompressedMode_ = false; 178 bool isStatisticMode_ = false; 179 const size_t MAX_CACHE_SIZE = 200000; 180 uint32_t callChainId_ = 0; 181 CommHookData commHookData_; 182 }; 183 } // namespace TraceStreamer 184 } // namespace SysTuning 185 #endif // NATIVE_HOOK_FILTER_H 186