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