1 /* 2 * Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved. 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 <cstdint> 18 #include <set> 19 #include <unordered_set> 20 #include "common_types.pb.h" 21 #include "native_hook_result.pb.h" 22 #include "numerical_to_string.h" 23 #include "offline_symbolization_filter.h" 24 #include "stat_filter.h" 25 #include "string_help.h" 26 #include "symbols_file.h" 27 namespace SysTuning { 28 namespace TraceStreamer { 29 constexpr uint64_t IP_BIT_OPERATION = 0xFFFFFFFFFF; 30 using namespace OHOS::Developtools::HiPerf; 31 class NativeHookFrameInfo { 32 public: NativeHookFrameInfo()33 NativeHookFrameInfo() 34 : ip_(INVALID_UINT64), 35 symbolIndex_(INVALID_UINT64), 36 filePathIndex_(INVALID_UINT64), 37 offset_(INVALID_UINT64), 38 symbolOffset_(INVALID_UINT64) 39 { 40 } NativeHookFrameInfo(uint64_t ip,uint64_t symbolIndex,uint64_t filePathIndex,uint64_t offset,uint64_t symbolOffset)41 NativeHookFrameInfo(uint64_t ip, 42 uint64_t symbolIndex, 43 uint64_t filePathIndex, 44 uint64_t offset, 45 uint64_t symbolOffset) 46 : ip_(ip), 47 symbolIndex_(symbolIndex), 48 filePathIndex_(filePathIndex), 49 offset_(offset), 50 symbolOffset_(symbolOffset) 51 { 52 } ~NativeHookFrameInfo()53 ~NativeHookFrameInfo() {} 54 uint64_t ip_; 55 uint64_t symbolIndex_; 56 uint64_t filePathIndex_; 57 uint64_t offset_; 58 uint64_t symbolOffset_; 59 }; 60 struct CommHookData { 61 size_t size = 0; 62 std::unique_ptr<BatchNativeHookData> datas = nullptr; 63 }; 64 class NativeHookFilter : public OfflineSymbolizationFilter { 65 public: 66 NativeHookFilter(TraceDataCache *, const TraceStreamerFilters *); 67 NativeHookFilter(const NativeHookFilter &) = delete; 68 NativeHookFilter &operator=(const NativeHookFilter &) = delete; 69 ~NativeHookFilter() override = default; 70 71 public: 72 void MaybeParseNativeHookMainEvent(uint64_t timeStamp, std::unique_ptr<NativeHookMetaData> nativeHookMetaData); 73 void ParseConfigInfo(ProtoReader::BytesView &protoData, uint64_t &statisticsInterval); 74 void AppendStackMaps(uint32_t ipid, uint32_t stackid, std::vector<uint64_t> &frames); 75 void AppendFrameMaps(uint32_t ipid, uint32_t frameMapId, const ProtoReader::BytesView &bytesView); 76 void AppendFilePathMaps(uint32_t ipid, uint32_t filePathId, uint64_t fileIndex); 77 void AppendSymbolMap(uint32_t ipid, uint32_t symId, uint64_t symbolIndex); 78 void AppendThreadNameMap(uint32_t ipid, uint32_t nameId, uint64_t threadNameIndex); 79 void ParseMapsEvent(std::unique_ptr<NativeHookMetaData> &nativeHookMetaData); 80 void ParseSymbolTableEvent(std::unique_ptr<NativeHookMetaData> &nativeHookMetaData); 81 void ParseTagEvent(const ProtoReader::BytesView &bytesView); 82 void FinishParseNativeHookData(); 83 void NativeHookReloadElfSymbolTable(const std::unique_ptr<SymbolsFile> &symbolsFile); 84 CommHookData &GetCommHookData(); 85 ProfilerPluginData *GetHookPluginData(); 86 void SerializeHookCommDataToString(); IsSingleProcData()87 const bool IsSingleProcData() 88 { 89 return isSingleProcData_; 90 } UpdataOfflineSymbolizationMode(bool isOfflineSymbolizationMode)91 void UpdataOfflineSymbolizationMode(bool isOfflineSymbolizationMode) 92 { 93 // Ut testing the offline symbolic use of native_hook,do not delete!!! 94 isOfflineSymbolizationMode_ = isOfflineSymbolizationMode; 95 } 96 97 private: 98 void ProcSymbolTable(uint32_t ipid, uint32_t filePathId, std::shared_ptr<ProtoReader::SymbolTable_Reader> reader); 99 std::tuple<uint64_t, uint64_t> GetIpRangeByIpidAndFilePathId(uint32_t ipid, uint32_t filePathId); 100 void DeleteFrameInfoWhichNeedsReparse(uint32_t ipid, uint32_t filePathId); 101 void FilterNativeHookMainEvent(size_t num); 102 void ParseStatisticEvent(uint64_t timeStamp, const ProtoReader::BytesView &bytesView); 103 template <class T1, class T2> 104 void UpdateMap(std::unordered_map<T1, T2> &sourceMap, T1 key, T2 value); 105 void ParseAllocEvent(uint64_t timeStamp, const ProtoReader::BytesView &bytesView); 106 void ParseFreeEvent(uint64_t timeStamp, const ProtoReader::BytesView &bytesView); 107 void SetFreeEventCallChainId(uint32_t &callChainId, 108 uint32_t ipid, 109 uint32_t itid, 110 const ProtoReader::FreeEvent_Reader &freeEventReader); 111 void ParseMmapEvent(uint64_t timeStamp, const ProtoReader::BytesView &bytesView); 112 void SetMmapEventCallChainId(uint32_t &callChainId, 113 uint32_t ipid, 114 uint32_t itid, 115 const ProtoReader::MmapEvent_Reader &mMapEventReader); 116 void ParseMunmapEvent(uint64_t timeStamp, const ProtoReader::BytesView &bytesView); 117 void SetMunmapEventCallChainId(uint32_t &callChainId, 118 uint32_t ipid, 119 uint32_t itid, 120 const ProtoReader::MunmapEvent_Reader &mUnmapEventReader); 121 122 void MaybeUpdateCurrentSizeDur(uint64_t row, uint64_t timeStamp, bool isMalloc); 123 void UpdateThreadNameWithNativeHookData() const; 124 void GetCallIdToLastLibId(); 125 void GetNativeHookFrameVaddrs(); 126 void UpdateSymbolIdsForSymbolizationFailed(); 127 void ParseFramesInOfflineSymbolizationMode(); 128 void ParseFramesInCallStackCompressedMode(); 129 void ParseFramesWithOutCallStackCompressedMode(); 130 void ParseSymbolizedNativeHookFrame(); 131 template <class T> 132 void UpdateSymbolTablePtrAndStValueToSymAddrMap(T *firstSymbolAddr, 133 const int size, 134 std::shared_ptr<ProtoReader::SymbolTable_Reader> reader); 135 std::shared_ptr<std::vector<std::shared_ptr<FrameInfo>>> OfflineSymbolization( 136 const std::shared_ptr<std::vector<uint64_t>> ips); 137 std::shared_ptr<FrameInfo> ParseArktsOfflineSymbolization(uint64_t ipid, uint64_t arktsIp); 138 void FillOfflineSymbolizationFrames(std::map<uint64_t, std::shared_ptr<std::vector<uint64_t>>>::iterator mapItor); 139 void ReparseStacksWithAddrRange(uint64_t start, uint64_t end); 140 void UpdateReparseStack(uint64_t stackId, std::shared_ptr<std::vector<uint64_t>> frames); 141 void ReparseStacksWithDifferentMeans(); 142 void CompressStackAndFrames(uint64_t row, ProtoReader::RepeatedDataAreaIterator<ProtoReader::BytesView> frames); 143 std::tuple<uint64_t, uint64_t> GetNeedUpdateProcessMapsAddrRange(uint32_t ipid, 144 uint64_t startAddr, 145 uint64_t endAddr); 146 std::unique_ptr<NativeHookFrameInfo> ParseFrame(uint64_t row, const ProtoReader::DataArea &frame); 147 template <class T> 148 void UpdateFilePathIdAndStValueToSymAddrMap(T *firstSymbolAddr, const int size, uint32_t filePathId); 149 uint64_t GetMemMapSubTypeWithAddr(uint64_t addr); 150 void UpdateAnonMmapDataDbIndex(uint64_t addr, uint64_t size, uint64_t row); 151 void UpdateLastCallerPathAndSymbolIndexs(); 152 void UpdateFilePathIndexToCallStackRowMap(size_t row, DataIndex filePathIndex); 153 154 private: 155 // first key is addr, second key is size, value is set<row> in db 156 // mmap update anonymous memory tag always use the anonMmapData_ value 157 DoubleMap<uint64_t, uint64_t, std::shared_ptr<std::set<uint64_t>>> anonMmapData_; 158 std::unique_ptr<ProfilerPluginData> hookPluginData_ = nullptr; 159 DoubleMap<uint32_t, uint32_t, uint64_t> ipidToSymIdToSymIndex_; 160 DoubleMap<uint32_t, uint32_t, uint64_t> ipidToFilePathIdToFileIndex_; 161 DoubleMap<uint32_t, uint64_t, std::shared_ptr<const ProtoReader::BytesView>> ipidToFrameIdToFrameBytes_; 162 std::unordered_map<DataIndex, std::shared_ptr<std::set<size_t>>> filePathIndexToFrameTableRowMap_ = {}; 163 std::multimap<uint64_t, std::unique_ptr<NativeHookMetaData>> tsToMainEventsMap_ = {}; 164 std::map<uint64_t, std::shared_ptr<std::vector<uint64_t>>> reparseStackIdToFramesMap_ = {}; 165 std::map<uint64_t, std::shared_ptr<std::vector<uint64_t>>> allStackIdToFramesMap_ = {}; 166 std::map<uint64_t, std::shared_ptr<std::vector<uint64_t>>> stackIdToFramesMap_ = {}; 167 std::map<uint32_t, uint64_t> callChainIdToStackHashValueMap_ = {}; 168 std::unordered_map<uint64_t, std::vector<uint64_t>> stackHashValueToFramesHashMap_ = {}; 169 std::unordered_map<uint64_t, std::unique_ptr<NativeHookFrameInfo>> frameHashToFrameInfoMap_ = {}; 170 std::unordered_map<uint64_t, uint64_t> threadNameIdToThreadNameIndex_ = {}; 171 std::unordered_map<uint32_t, std::tuple<uint64_t, uint64_t>> callIdToLastCallerPathIndex_ = {}; 172 std::unordered_map<uint64_t, std::string> functionNameIndexToVaddr_ = {}; 173 std::unordered_map<uint64_t, uint32_t> stackHashValueToCallChainIdMap_ = {}; 174 std::unordered_map<uint32_t, uint64_t> itidToThreadNameId_ = {}; 175 std::unordered_map<uint32_t, uint32_t> stackIdToCallChainIdMap_ = {}; 176 std::unordered_map<uint64_t, uint64_t> *addrToAllocEventRow_ = nullptr; 177 std::unordered_map<uint64_t, uint64_t> *addrToMmapEventRow_ = nullptr; 178 std::set<DataIndex> invalidLibPathIndexs_ = {}; 179 std::deque<std::string> vaddrs_ = {}; 180 // munmap update anonymous or named memory tag always use the last addrToMmapTag_ value 181 std::unordered_map<uint64_t, uint64_t> addrToMmapTag_ = {}; 182 std::hash<std::string_view> hashFun_; 183 bool isOfflineSymbolizationMode_ = false; 184 bool isCallStackCompressedMode_ = false; 185 bool isStringCompressedMode_ = false; 186 bool isStatisticMode_ = false; 187 const size_t MAX_CACHE_SIZE = 200000; 188 uint32_t callChainId_ = 0; 189 CommHookData commHookData_; 190 std::unordered_set<uint32_t> callChainIdsSet_; 191 }; 192 } // namespace TraceStreamer 193 } // namespace SysTuning 194 #endif // NATIVE_HOOK_FILTER_H 195