• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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