• 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 
16 #include "native_hook_filter.h"
17 #include "native_hook_config.pbreader.h"
18 #include <cstddef>
19 #include <cinttypes>
20 namespace SysTuning {
21 namespace TraceStreamer {
NativeHookFilter(TraceDataCache * dataCache,const TraceStreamerFilters * filter)22 NativeHookFilter::NativeHookFilter(TraceDataCache *dataCache, const TraceStreamerFilters *filter)
23     : OfflineSymbolizationFilter(dataCache, filter),
24       anonMmapData_(nullptr),
25       hookPluginData_(std::make_unique<ProfilerPluginData>()),
26       ipidToSymIdToSymIndex_(INVALID_UINT64),
27       ipidToFilePathIdToFileIndex_(INVALID_UINT64),
28       ipidToFrameIdToFrameBytes_(nullptr)
29 {
30     invalidLibPathIndexs_.insert(traceDataCache_->dataDict_.GetStringIndex("/system/lib/libc++.so"));
31     invalidLibPathIndexs_.insert(traceDataCache_->dataDict_.GetStringIndex("/system/lib64/libc++.so"));
32     invalidLibPathIndexs_.insert(traceDataCache_->dataDict_.GetStringIndex("/system/lib/ld-musl-aarch64.so.1"));
33     invalidLibPathIndexs_.insert(traceDataCache_->dataDict_.GetStringIndex("/system/lib/ld-musl-arm.so.1"));
34     hookPluginData_->set_name("nativehook");
35     commHookData_.datas = std::make_unique<BatchNativeHookData>();
36     addrToAllocEventRow_ = traceDataCache_->GetNativeHookData()->GetAddrToAllocEventRow();
37     addrToMmapEventRow_ = traceDataCache_->GetNativeHookData()->GetAddrToMmapEventRow();
38 }
39 
ParseConfigInfo(ProtoReader::BytesView & protoData)40 void NativeHookFilter::ParseConfigInfo(ProtoReader::BytesView &protoData)
41 {
42     auto configReader = ProtoReader::NativeHookConfig_Reader(protoData);
43     if (configReader.has_expand_pids() || (configReader.has_process_name() && configReader.has_pid())) {
44         isSingleProcData_ = false;
45     }
46     if (configReader.has_statistics_interval()) {
47         isStatisticMode_ = true;
48         isCallStackCompressedMode_ = true;
49         isStringCompressedMode_ = true;
50     }
51     if (configReader.has_response_library_mode() || configReader.has_offline_symbolization()) {
52         isOfflineSymbolizationMode_ = true;
53         isCallStackCompressedMode_ = true;
54         isStringCompressedMode_ = true;
55         return;
56     }
57     if (configReader.has_callframe_compress()) {
58         isCallStackCompressedMode_ = true;
59         isStringCompressedMode_ = true;
60         return;
61     }
62     if (configReader.has_string_compressed()) {
63         isStringCompressedMode_ = true;
64         return;
65     }
66     return;
67 }
AppendStackMaps(uint32_t ipid,uint32_t stackid,std::vector<uint64_t> & frames)68 void NativeHookFilter::AppendStackMaps(uint32_t ipid, uint32_t stackid, std::vector<uint64_t> &frames)
69 {
70     uint64_t ipidWithStackIdIndex = 0;
71     // the last element is ipid for this batch of frames/ips
72     if (isSingleProcData_) {
73         frames.emplace_back(SINGLE_PROC_IPID);
74         ipidWithStackIdIndex = stackid;
75     } else {
76         frames.emplace_back(ipid);
77         ipidWithStackIdIndex = traceDataCache_->GetDataIndex(std::to_string(ipid) + "_" + std::to_string(stackid));
78     }
79     auto framesSharedPtr = std::make_shared<std::vector<uint64_t>>(frames);
80     stackIdToFramesMap_.emplace(std::make_pair(ipidWithStackIdIndex, framesSharedPtr));
81     // allStackIdToFramesMap_ save all offline symbolic call stack
82     if (isOfflineSymbolizationMode_) {
83         allStackIdToFramesMap_.emplace(std::make_pair(ipidWithStackIdIndex, framesSharedPtr));
84     }
85 }
AppendFrameMaps(uint32_t ipid,uint32_t frameMapId,const ProtoReader::BytesView & bytesView)86 void NativeHookFilter::AppendFrameMaps(uint32_t ipid, uint32_t frameMapId, const ProtoReader::BytesView &bytesView)
87 {
88     auto frames = std::make_shared<const ProtoReader::BytesView>(bytesView);
89     if (isSingleProcData_) {
90         ipidToFrameIdToFrameBytes_.Insert(SINGLE_PROC_IPID, frameMapId, frames);
91     } else {
92         ipidToFrameIdToFrameBytes_.Insert(ipid, frameMapId, frames);
93     }
94 }
AppendFilePathMaps(uint32_t ipid,uint32_t filePathId,uint64_t fileIndex)95 void NativeHookFilter::AppendFilePathMaps(uint32_t ipid, uint32_t filePathId, uint64_t fileIndex)
96 {
97     if (isSingleProcData_) {
98         ipidToFilePathIdToFileIndex_.Insert(SINGLE_PROC_IPID, filePathId, fileIndex);
99     } else {
100         ipidToFilePathIdToFileIndex_.Insert(ipid, filePathId, fileIndex);
101     }
102 }
AppendSymbolMap(uint32_t ipid,uint32_t symId,uint64_t symbolIndex)103 void NativeHookFilter::AppendSymbolMap(uint32_t ipid, uint32_t symId, uint64_t symbolIndex)
104 {
105     if (isSingleProcData_) {
106         ipidToSymIdToSymIndex_.Insert(SINGLE_PROC_IPID, symId, symbolIndex);
107     } else {
108         ipidToSymIdToSymIndex_.Insert(ipid, symId, symbolIndex);
109     }
110 }
AppendThreadNameMap(uint32_t ipid,uint32_t nameId,uint64_t threadNameIndex)111 void NativeHookFilter::AppendThreadNameMap(uint32_t ipid, uint32_t nameId, uint64_t threadNameIndex)
112 {
113     uint64_t ipidWithThreadNameIdIndex = 0;
114     if (isSingleProcData_) {
115         ipidWithThreadNameIdIndex = nameId;
116     } else {
117         ipidWithThreadNameIdIndex = traceDataCache_->GetDataIndex(std::to_string(ipid) + "_" + std::to_string(nameId));
118     }
119     threadNameIdToThreadNameIndex_.emplace(ipidWithThreadNameIdIndex, threadNameIndex);
120 }
121 
122 template <class T1, class T2>
UpdateMap(std::unordered_map<T1,T2> & sourceMap,T1 key,T2 value)123 void NativeHookFilter::UpdateMap(std::unordered_map<T1, T2> &sourceMap, T1 key, T2 value)
124 {
125     auto itor = sourceMap.find(key);
126     if (itor != sourceMap.end()) {
127         itor->second = value;
128     } else {
129         sourceMap.insert(std::make_pair(key, value));
130     }
131 }
ParseFrame(uint64_t row,const ProtoReader::DataArea & frame)132 std::unique_ptr<NativeHookFrameInfo> NativeHookFilter::ParseFrame(uint64_t row, const ProtoReader::DataArea &frame)
133 {
134     auto frameInfo = std::make_unique<NativeHookFrameInfo>();
135 
136     ProtoReader::Frame_Reader reader(frame.Data(), frame.Size());
137     auto curCacheIpid = traceDataCache_->GetNativeHookData()->Ipids()[row];
138     if (isSingleProcData_) {
139         curCacheIpid = SINGLE_PROC_IPID;
140     }
141     if (isStringCompressedMode_) {
142         frameInfo->symbolIndex_ = ipidToSymIdToSymIndex_.Find(curCacheIpid, reader.symbol_name_id());
143         TS_CHECK_TRUE(frameInfo->symbolIndex_ != INVALID_UINT64, nullptr,
144                       "Native hook ParseFrame find symbol id failed!!!");
145         frameInfo->filePathIndex_ = ipidToFilePathIdToFileIndex_.Find(curCacheIpid, reader.file_path_id());
146         TS_CHECK_TRUE(frameInfo->filePathIndex_ != INVALID_UINT64, nullptr,
147                       "Native hook ParseFrame find file path id failed!!!");
148     } else {
149         frameInfo->symbolIndex_ = traceDataCache_->dataDict_.GetStringIndex(reader.symbol_name().ToStdString());
150         frameInfo->filePathIndex_ = traceDataCache_->dataDict_.GetStringIndex(reader.file_path().ToStdString());
151     }
152     // 0 is meaningful, but it is not displayed. Other data is still needed
153     if (reader.has_ip()) {
154         frameInfo->ip_ = reader.ip();
155     }
156     if (reader.has_offset()) {
157         frameInfo->offset_ = reader.offset();
158     }
159     if (reader.has_symbol_offset()) {
160         frameInfo->symbolOffset_ = reader.symbol_offset();
161     }
162     return frameInfo;
163 }
164 
CompressStackAndFrames(uint64_t row,ProtoReader::RepeatedDataAreaIterator<ProtoReader::BytesView> frames)165 void NativeHookFilter::CompressStackAndFrames(uint64_t row,
166                                               ProtoReader::RepeatedDataAreaIterator<ProtoReader::BytesView> frames)
167 {
168     std::vector<uint64_t> framesHash;
169     std::string framesHashStr = "";
170     for (auto itor = frames; itor; itor++) {
171         std::string_view frameStr(reinterpret_cast<const char *>(itor->Data()), itor->Size());
172         auto frameHash = hashFun_(frameStr);
173         if (!frameHashToFrameInfoMap_.count(frameHash)) {
174             // the frame compression is completed and the frame is parsed.
175             auto frameInfo = ParseFrame(row, itor.GetDataArea());
176             if (!frameInfo) {
177                 continue;
178             }
179             frameHashToFrameInfoMap_.emplace(std::make_pair(frameHash, std::move(frameInfo)));
180         }
181         framesHash.emplace_back(frameHash);
182         framesHashStr.append("+");
183         framesHashStr.append(std::to_string(frameHash));
184     }
185     auto stackHashValue = hashFun_(framesHashStr);
186     uint32_t callChainId = INVALID_UINT32;
187     if (!stackHashValueToCallChainIdMap_.count(stackHashValue)) {
188         callChainId = callChainIdToStackHashValueMap_.size() + 1;
189         callChainIdToStackHashValueMap_.emplace(std::make_pair(callChainId, stackHashValue));
190         stackHashValueToCallChainIdMap_.emplace(std::make_pair(stackHashValue, callChainId));
191         stackHashValueToFramesHashMap_.emplace(std::make_pair(stackHashValue, std::move(framesHash)));
192     } else {
193         callChainId = stackHashValueToCallChainIdMap_[stackHashValue];
194     }
195     // When compressing the call stack, update the callChainId of the nativeHook table
196     traceDataCache_->GetNativeHookData()->UpdateCallChainId(row, callChainId);
197 }
ParseStatisticEvent(uint64_t timeStamp,const ProtoReader::BytesView & bytesView)198 void NativeHookFilter::ParseStatisticEvent(uint64_t timeStamp, const ProtoReader::BytesView &bytesView)
199 {
200     ProtoReader::RecordStatisticsEvent_Reader reader(bytesView);
201     uint32_t callChainId = INVALID_UINT32;
202     uint64_t ipidWithCallChainIdIndex = INVALID_UINT64;
203     auto ipid = streamFilters_->processFilter_->GetOrCreateInternalPid(timeStamp, reader.pid());
204     if (isSingleProcData_) {
205         ipidWithCallChainIdIndex = reader.callstack_id();
206     } else {
207         ipidWithCallChainIdIndex =
208             traceDataCache_->GetDataIndex(std::to_string(ipid) + "_" + std::to_string(reader.callstack_id()));
209     }
210     // When the stack id is zero, there is no matching call stack
211     if (isOfflineSymbolizationMode_ && reader.callstack_id()) {
212         // The same call stack may have different symbolic results due to changes in the symbol table
213         if (stackIdToCallChainIdMap_.count(ipidWithCallChainIdIndex)) {
214             callChainId = stackIdToCallChainIdMap_.at(ipidWithCallChainIdIndex);
215         } else {
216             TS_LOGE("invalid callChainId, can not find stack id : %u in stackIdToCallChainIdMap_!",
217                     reader.callstack_id());
218         }
219     } else if (reader.callstack_id()) { // when isStatisticMode_ is true, isCallStackCompressedMode_ must be true.
220         // when isOfflineSymblolizationMode_ is false, the stack id is unique
221         callChainId = ipidWithCallChainIdIndex;
222     }
223 
224     DataIndex memSubType = INVALID_UINT64;
225     if (reader.has_tag_name()) {
226         memSubType = traceDataCache_->GetDataIndex(reader.tag_name().ToStdString());
227     }
228     NativeHookStatisticRow nativeHookStatisticRow = {ipid,
229                                                      timeStamp,
230                                                      callChainId,
231                                                      static_cast<uint32_t>(reader.type()),
232                                                      memSubType,
233                                                      reader.apply_count(),
234                                                      reader.release_count(),
235                                                      reader.apply_size(),
236                                                      reader.release_size()};
237     traceDataCache_->GetNativeHookStatisticsData()->AppendNewNativeHookStatistic(nativeHookStatisticRow);
238 }
ParseAllocEvent(uint64_t timeStamp,const ProtoReader::BytesView & bytesView)239 void NativeHookFilter::ParseAllocEvent(uint64_t timeStamp, const ProtoReader::BytesView &bytesView)
240 {
241     ProtoReader::AllocEvent_Reader allocEventReader(bytesView);
242     uint32_t callChainId = INVALID_UINT32;
243     auto itid =
244         streamFilters_->processFilter_->GetOrCreateThreadWithPid(allocEventReader.tid(), allocEventReader.pid());
245     auto ipid = traceDataCache_->GetConstThreadData(itid).internalPid_;
246     uint64_t ipidWithStackIdIndex = INVALID_UINT64;
247     uint64_t ipidWithThreadNameIdIndex = INVALID_UINT64;
248     if (isSingleProcData_) {
249         ipidWithThreadNameIdIndex = allocEventReader.thread_name_id();
250         ipidWithStackIdIndex = allocEventReader.stack_id();
251     } else {
252         ipidWithThreadNameIdIndex = traceDataCache_->GetDataIndex(std::to_string(ipid) + "_" +
253                                                                   std::to_string(allocEventReader.thread_name_id()));
254         ipidWithStackIdIndex =
255             traceDataCache_->GetDataIndex(std::to_string(ipid) + "_" + std::to_string(allocEventReader.stack_id()));
256     }
257     // When the stack id is zero, there is no matching call stack
258     if (isOfflineSymbolizationMode_ && allocEventReader.stack_id()) {
259         // The same call stack may have different symbolic results due to changes in the symbol table
260         if (stackIdToCallChainIdMap_.count(ipidWithStackIdIndex)) {
261             callChainId = stackIdToCallChainIdMap_.at(ipidWithStackIdIndex);
262         } else {
263             TS_LOGE("invalid callChainId, can not find pid with stack id : %" PRIu64 " in stackIdToCallChainIdMap_!",
264                     ipidWithStackIdIndex);
265         }
266     } else if (isCallStackCompressedMode_ && allocEventReader.stack_id()) {
267         // when isOfflineSymblolizationMode_ is false && isCallStackCompressedMode is true, the stack id is unique
268         callChainId = ipidWithStackIdIndex;
269     }
270 
271     if (allocEventReader.has_thread_name_id()) {
272         UpdateMap(itidToThreadNameId_, itid, ipidWithThreadNameIdIndex);
273     }
274     NativeHookRow nativeHookRow = {callChainId,
275                                    ipid,
276                                    itid,
277                                    "AllocEvent",
278                                    INVALID_UINT64,
279                                    timeStamp,
280                                    0,
281                                    0,
282                                    allocEventReader.addr(),
283                                    static_cast<int64_t>(allocEventReader.size())};
284     auto row = traceDataCache_->GetNativeHookData()->AppendNewNativeHookData(nativeHookRow);
285     addrToAllocEventRow_->insert(std::make_pair(allocEventReader.addr(), static_cast<uint64_t>(row)));
286     if (allocEventReader.size() != 0) {
287         MaybeUpdateCurrentSizeDur(row, timeStamp, true);
288     }
289     // Uncompressed call stack
290     if (allocEventReader.has_frame_info()) {
291         CompressStackAndFrames(row, allocEventReader.frame_info());
292     }
293 }
294 
SetFreeEventCallChainId(uint32_t & callChainId,uint32_t ipid,uint32_t itid,const ProtoReader::FreeEvent_Reader & freeEventReader)295 void NativeHookFilter::SetFreeEventCallChainId(uint32_t &callChainId,
296                                                uint32_t ipid,
297                                                uint32_t itid,
298                                                const ProtoReader::FreeEvent_Reader &freeEventReader)
299 {
300     uint64_t ipidWithStackIdIndex = INVALID_UINT64;
301     uint64_t ipidWithThreadNameIdIndex = INVALID_UINT64;
302     if (isSingleProcData_) {
303         ipidWithStackIdIndex = freeEventReader.stack_id();
304         ipidWithThreadNameIdIndex = freeEventReader.thread_name_id();
305     } else {
306         ipidWithThreadNameIdIndex = traceDataCache_->GetDataIndex(std::to_string(ipid) + "_" +
307                                                                   std::to_string(freeEventReader.thread_name_id()));
308         ipidWithStackIdIndex =
309             traceDataCache_->GetDataIndex(std::to_string(ipid) + "_" + std::to_string(freeEventReader.stack_id()));
310     }
311     // When the stack id is zero, there is no matching call stack
312     if (isOfflineSymbolizationMode_ && freeEventReader.stack_id()) {
313         // The same call stack may have different symbolic results due to changes in the symbol table
314         if (stackIdToCallChainIdMap_.count(ipidWithStackIdIndex)) {
315             callChainId = stackIdToCallChainIdMap_.at(ipidWithStackIdIndex);
316         } else {
317             TS_LOGE("invalid callChainId, can not find pid with stack id : %" PRIu64 " in stackIdToCallChainIdMap_!",
318                     ipidWithStackIdIndex);
319         }
320     } else if (isCallStackCompressedMode_ && freeEventReader.stack_id()) {
321         // when isOfflineSymblolizationMode_ is false && isCallStackCompressedMode is true, the stack id is unique
322         callChainId = ipidWithStackIdIndex;
323     }
324     if (freeEventReader.thread_name_id() != 0) {
325         UpdateMap(itidToThreadNameId_, itid, ipidWithThreadNameIdIndex);
326     }
327 }
ParseFreeEvent(uint64_t timeStamp,const ProtoReader::BytesView & bytesView)328 void NativeHookFilter::ParseFreeEvent(uint64_t timeStamp, const ProtoReader::BytesView &bytesView)
329 {
330     ProtoReader::FreeEvent_Reader freeEventReader(bytesView);
331     uint32_t callChainId = INVALID_UINT32;
332     auto itid = streamFilters_->processFilter_->GetOrCreateThreadWithPid(freeEventReader.tid(), freeEventReader.pid());
333     auto ipid = traceDataCache_->GetConstThreadData(itid).internalPid_;
334     SetFreeEventCallChainId(callChainId, ipid, itid, freeEventReader);
335     int64_t freeHeapSize = 0;
336     // Find a matching malloc event, and if the matching fails, do not write to the database
337     uint64_t row = INVALID_UINT64;
338     if (addrToAllocEventRow_->count(freeEventReader.addr())) {
339         row = addrToAllocEventRow_->at(freeEventReader.addr());
340     }
341     if (row != INVALID_UINT64 && timeStamp > traceDataCache_->GetNativeHookData()->TimeStampData()[row]) {
342         addrToAllocEventRow_->erase(freeEventReader.addr());
343         traceDataCache_->GetNativeHookData()->UpdateEndTimeStampAndDuration(row, timeStamp);
344         freeHeapSize = traceDataCache_->GetNativeHookData()->MemSizes()[row];
345     } else {
346         TS_LOGD("func addr:%" PRIu64 " is empty", freeEventReader.addr());
347         streamFilters_->statFilter_->IncreaseStat(TRACE_NATIVE_HOOK_FREE, STAT_EVENT_DATA_INVALID);
348         return;
349     }
350     NativeHookRow nativeHookRow = {
351         callChainId, ipid, itid, "FreeEvent", INVALID_UINT64, timeStamp, 0, 0, freeEventReader.addr(), freeHeapSize};
352     row = traceDataCache_->GetNativeHookData()->AppendNewNativeHookData(nativeHookRow);
353     if (freeHeapSize != 0) {
354         MaybeUpdateCurrentSizeDur(row, timeStamp, true);
355     }
356     // Uncompressed call stack
357     if (freeEventReader.has_frame_info()) {
358         CompressStackAndFrames(row, freeEventReader.frame_info());
359     }
360 }
SetMmapEventCallChainId(uint32_t & callChainId,uint32_t ipid,uint32_t itid,const ProtoReader::MmapEvent_Reader & mMapEventReader)361 void NativeHookFilter::SetMmapEventCallChainId(uint32_t &callChainId,
362                                                uint32_t ipid,
363                                                uint32_t itid,
364                                                const ProtoReader::MmapEvent_Reader &mMapEventReader)
365 {
366     uint64_t ipidWithStackIdIndex = INVALID_UINT64;
367     uint64_t ipidWithThreadNameIdIndex = INVALID_UINT64;
368     if (isSingleProcData_) {
369         ipidWithStackIdIndex = mMapEventReader.stack_id();
370         ipidWithThreadNameIdIndex = mMapEventReader.thread_name_id();
371     } else {
372         ipidWithThreadNameIdIndex = traceDataCache_->GetDataIndex(std::to_string(ipid) + "_" +
373                                                                   std::to_string(mMapEventReader.thread_name_id()));
374         ipidWithStackIdIndex =
375             traceDataCache_->GetDataIndex(std::to_string(ipid) + "_" + std::to_string(mMapEventReader.stack_id()));
376     }
377     // When the stack id is zero, there is no matching call stack
378     if (isOfflineSymbolizationMode_ && mMapEventReader.stack_id()) {
379         // The same call stack may have different symbolic results due to changes in the symbol table
380         if (stackIdToCallChainIdMap_.count(ipidWithStackIdIndex)) {
381             callChainId = stackIdToCallChainIdMap_.at(ipidWithStackIdIndex);
382         } else {
383             TS_LOGE("invalid callChainId, can not find pid with stack id : %" PRIu64 " in stackIdToCallChainIdMap_!",
384                     ipidWithStackIdIndex);
385         }
386     } else if (isCallStackCompressedMode_ && mMapEventReader.stack_id()) {
387         // when isOfflineSymblolizationMode_ is false && isCallStackCompressedMode is true, the stack id is unique
388         callChainId = ipidWithStackIdIndex;
389     }
390     // Update the mapping of tid to thread name id.
391     if (mMapEventReader.thread_name_id() != 0) {
392         UpdateMap(itidToThreadNameId_, itid, ipidWithThreadNameIdIndex);
393     }
394 }
ParseMmapEvent(uint64_t timeStamp,const ProtoReader::BytesView & bytesView)395 void NativeHookFilter::ParseMmapEvent(uint64_t timeStamp, const ProtoReader::BytesView &bytesView)
396 {
397     ProtoReader::MmapEvent_Reader mMapEventReader(bytesView);
398     uint32_t callChainId = INVALID_UINT32;
399     auto itid = streamFilters_->processFilter_->GetOrCreateThreadWithPid(mMapEventReader.tid(), mMapEventReader.pid());
400     auto ipid = traceDataCache_->GetConstThreadData(itid).internalPid_;
401     SetMmapEventCallChainId(callChainId, ipid, itid, mMapEventReader);
402     // Gets the index of the mmap event's label in the data dictionary
403     DataIndex subType = INVALID_UINT64;
404     auto mMapAddr = mMapEventReader.addr();
405     auto mMapSize = mMapEventReader.size();
406     if (mMapEventReader.has_type() && !mMapEventReader.type().ToStdString().empty()) {
407         subType = traceDataCache_->dataDict_.GetStringIndex(mMapEventReader.type().ToStdString());
408         // Establish a mapping of addr and size to the mmap tag index.
409         addrToMmapTag_[mMapAddr] = subType; // update addr to MemMapSubType
410     }
411     NativeHookRow nativeHookRow = {callChainId, ipid, itid, "MmapEvent", subType,
412                                    timeStamp,   0,    0,    mMapAddr,    static_cast<int64_t>(mMapSize)};
413     auto row = traceDataCache_->GetNativeHookData()->AppendNewNativeHookData(nativeHookRow);
414     if (subType == INVALID_UINT64) {
415         UpdateAnonMmapDataDbIndex(mMapAddr, mMapSize, static_cast<uint64_t>(row));
416     }
417     addrToMmapEventRow_->insert(std::make_pair(mMapAddr, static_cast<uint64_t>(row)));
418     // update currentSizeDur.
419     if (mMapSize) {
420         MaybeUpdateCurrentSizeDur(row, timeStamp, false);
421     }
422     // Uncompressed call stack
423     if (mMapEventReader.has_frame_info()) {
424         CompressStackAndFrames(row, mMapEventReader.frame_info());
425     }
426 }
SetMunmapEventCallChainId(uint32_t & callChainId,uint32_t ipid,uint32_t itid,const ProtoReader::MunmapEvent_Reader & mUnmapEventReader)427 void NativeHookFilter::SetMunmapEventCallChainId(uint32_t &callChainId,
428                                                  uint32_t ipid,
429                                                  uint32_t itid,
430                                                  const ProtoReader::MunmapEvent_Reader &mUnmapEventReader)
431 {
432     uint64_t ipidWithStackIdIndex = INVALID_UINT64;
433     uint64_t ipidWithThreadNameIdIndex = INVALID_UINT64;
434     if (isSingleProcData_) {
435         ipidWithStackIdIndex = mUnmapEventReader.stack_id();
436         ipidWithThreadNameIdIndex = mUnmapEventReader.thread_name_id();
437     } else {
438         ipidWithThreadNameIdIndex = traceDataCache_->GetDataIndex(std::to_string(ipid) + "_" +
439                                                                   std::to_string(mUnmapEventReader.thread_name_id()));
440         ipidWithStackIdIndex =
441             traceDataCache_->GetDataIndex(std::to_string(ipid) + "_" + std::to_string(mUnmapEventReader.stack_id()));
442     }
443     // When the stack id is zero, there is no matching call stack
444     if (isOfflineSymbolizationMode_) {
445         // The same call stack may have different symbolic results due to changes in the symbol table
446         if (stackIdToCallChainIdMap_.count(ipidWithStackIdIndex)) {
447             callChainId = stackIdToCallChainIdMap_.at(mUnmapEventReader.stack_id());
448         } else {
449             TS_LOGE("invalid callChainId, can not find pid with stack id : %" PRIu64 " in stackIdToCallChainIdMap_!",
450                     ipidWithStackIdIndex);
451         }
452     } else if (isCallStackCompressedMode_) {
453         // when isOfflineSymblolizationMode_ is false && isCallStackCompressedMode is true, the stack id is unique
454         callChainId = ipidWithStackIdIndex;
455     }
456     if (mUnmapEventReader.thread_name_id() != 0) {
457         UpdateMap(itidToThreadNameId_, itid, ipidWithThreadNameIdIndex);
458     }
459 }
ParseMunmapEvent(uint64_t timeStamp,const ProtoReader::BytesView & bytesView)460 void NativeHookFilter::ParseMunmapEvent(uint64_t timeStamp, const ProtoReader::BytesView &bytesView)
461 {
462     ProtoReader::MunmapEvent_Reader mUnmapEventReader(bytesView);
463     uint32_t callChainId = INVALID_UINT32;
464     auto itid =
465         streamFilters_->processFilter_->GetOrCreateThreadWithPid(mUnmapEventReader.tid(), mUnmapEventReader.pid());
466     auto ipid = traceDataCache_->GetConstThreadData(itid).internalPid_;
467     SetMunmapEventCallChainId(callChainId, ipid, itid, mUnmapEventReader);
468     // Query for MMAP events that match the current data. If there are no matching MMAP events, the current data is not
469     // written to the database.
470     uint64_t row = INVALID_UINT64;
471     if (addrToMmapEventRow_->count(mUnmapEventReader.addr())) {
472         row = addrToMmapEventRow_->at(mUnmapEventReader.addr());
473     }
474     if (row != INVALID_UINT64 && timeStamp > traceDataCache_->GetNativeHookData()->TimeStampData()[row]) {
475         addrToMmapEventRow_->erase(mUnmapEventReader.addr());
476         traceDataCache_->GetNativeHookData()->UpdateEndTimeStampAndDuration(row, timeStamp);
477     } else {
478         TS_LOGD("func addr:%" PRIu64 " is empty", mUnmapEventReader.addr());
479         streamFilters_->statFilter_->IncreaseStat(TRACE_NATIVE_HOOK_MUNMAP, STAT_EVENT_DATA_INVALID);
480         return;
481     }
482     NativeHookRow nativeHookRow = {callChainId,
483                                    ipid,
484                                    itid,
485                                    "MunmapEvent",
486                                    GetMemMapSubTypeWithAddr(mUnmapEventReader.addr()),
487                                    timeStamp,
488                                    0,
489                                    0,
490                                    mUnmapEventReader.addr(),
491                                    static_cast<int64_t>(mUnmapEventReader.size())};
492     row = traceDataCache_->GetNativeHookData()->AppendNewNativeHookData(nativeHookRow);
493     addrToMmapTag_.erase(mUnmapEventReader.addr()); // earse MemMapSubType with addr
494     if (mUnmapEventReader.size() != 0) {
495         MaybeUpdateCurrentSizeDur(row, timeStamp, false);
496     }
497     // Uncompressed call stack
498     if (mUnmapEventReader.has_frame_info()) {
499         CompressStackAndFrames(row, mUnmapEventReader.frame_info());
500     }
501 }
ParseTagEvent(const ProtoReader::BytesView & bytesView)502 void NativeHookFilter::ParseTagEvent(const ProtoReader::BytesView &bytesView)
503 {
504     ProtoReader::MemTagEvent_Reader memTagEventReader(bytesView);
505     auto addr = memTagEventReader.addr();
506     auto size = memTagEventReader.size();
507     if (traceDataCache_->isSplitFile_) {
508         auto hookData = commHookData_.datas->add_events();
509         MemTagEvent *memTagEvent = hookData->mutable_tag_event();
510         memTagEvent->ParseFromArray(bytesView.Data(), bytesView.Size());
511         commHookData_.size += bytesView.Size();
512         return;
513     }
514     auto tagIndex = traceDataCache_->dataDict_.GetStringIndex(memTagEventReader.tag().ToStdString());
515     NativeHook *nativeHookPtr = traceDataCache_->GetNativeHookData();
516     std::shared_ptr<std::set<uint64_t>> indexSetPtr = anonMmapData_.Find(addr, size); // get anonMmapData dbIndex
517     if (indexSetPtr != nullptr) {
518         for (auto rowIter = indexSetPtr->begin(); rowIter != indexSetPtr->end(); rowIter++) {
519             nativeHookPtr->UpdateMemMapSubType(*rowIter, tagIndex);
520         }
521         indexSetPtr->clear();            // clear annoMmapData dbIndex
522         addrToMmapTag_[addr] = tagIndex; // update addr to MemMapSubType
523     }
524 }
GetMemMapSubTypeWithAddr(uint64_t addr)525 inline uint64_t NativeHookFilter::GetMemMapSubTypeWithAddr(uint64_t addr)
526 {
527     auto iter = addrToMmapTag_.find(addr);
528     if (iter != addrToMmapTag_.end()) {
529         return iter->second; // subType
530     } else {
531         return INVALID_UINT64;
532     }
533 }
UpdateAnonMmapDataDbIndex(uint64_t addr,uint64_t size,uint64_t row)534 inline void NativeHookFilter::UpdateAnonMmapDataDbIndex(uint64_t addr, uint64_t size, uint64_t row)
535 {
536     auto indexPtr = anonMmapData_.Find(addr, size);
537     if (indexPtr == nullptr) {
538         std::shared_ptr<std::set<uint64_t>> rowPtr_ = std::make_shared<std::set<uint64_t>>();
539         rowPtr_->insert(row);
540         anonMmapData_.Insert(addr, size, std::move(rowPtr_));
541     } else {
542         indexPtr->insert(row);
543     }
544 }
FilterNativeHookMainEvent(size_t num)545 void NativeHookFilter::FilterNativeHookMainEvent(size_t num)
546 {
547     auto itor = tsToMainEventsMap_.begin();
548     for (; itor != tsToMainEventsMap_.end() && num; num--, itor++) {
549         auto nativeHookDataReader = itor->second->reader_.get();
550         auto timeStamp = itor->first;
551         if (nativeHookDataReader->has_alloc_event()) {
552             streamFilters_->statFilter_->IncreaseStat(TRACE_NATIVE_HOOK_MALLOC, STAT_EVENT_RECEIVED);
553             ParseAllocEvent(timeStamp, nativeHookDataReader->alloc_event());
554         } else if (nativeHookDataReader->has_free_event()) {
555             streamFilters_->statFilter_->IncreaseStat(TRACE_NATIVE_HOOK_FREE, STAT_EVENT_RECEIVED);
556             ParseFreeEvent(timeStamp, nativeHookDataReader->free_event());
557         } else if (nativeHookDataReader->has_mmap_event()) {
558             streamFilters_->statFilter_->IncreaseStat(TRACE_NATIVE_HOOK_MMAP, STAT_EVENT_RECEIVED);
559             ParseMmapEvent(timeStamp, nativeHookDataReader->mmap_event());
560         } else if (nativeHookDataReader->has_munmap_event()) {
561             streamFilters_->statFilter_->IncreaseStat(TRACE_NATIVE_HOOK_MUNMAP, STAT_EVENT_RECEIVED);
562             ParseMunmapEvent(timeStamp, nativeHookDataReader->munmap_event());
563         } else if (nativeHookDataReader->has_statistics_event()) {
564             streamFilters_->statFilter_->IncreaseStat(TRACE_NATIVE_HOOK_RECORD_STATISTICS, STAT_EVENT_RECEIVED);
565             ParseStatisticEvent(timeStamp, nativeHookDataReader->statistics_event());
566         } else if (nativeHookDataReader->has_tag_event()) {
567             streamFilters_->statFilter_->IncreaseStat(TRACE_NATIVE_HOOK_MEMTAG, STAT_EVENT_RECEIVED);
568             ParseTagEvent(nativeHookDataReader->tag_event());
569         }
570     }
571     tsToMainEventsMap_.erase(tsToMainEventsMap_.begin(), itor);
572 }
573 
MaybeParseNativeHookMainEvent(uint64_t timeStamp,std::unique_ptr<NativeHookMetaData> nativeHookMetaData)574 void NativeHookFilter::MaybeParseNativeHookMainEvent(uint64_t timeStamp,
575                                                      std::unique_ptr<NativeHookMetaData> nativeHookMetaData)
576 {
577     tsToMainEventsMap_.insert(std::make_pair(timeStamp, std::move(nativeHookMetaData)));
578     if (tsToMainEventsMap_.size() > MAX_CACHE_SIZE) {
579         if (isOfflineSymbolizationMode_) {
580             ParseFramesInOfflineSymbolizationMode();
581             ReparseStacksWithDifferentMeans();
582         }
583         FilterNativeHookMainEvent(tsToMainEventsMap_.size() - MAX_CACHE_SIZE);
584     }
585 }
586 
587 // Returns the address range of memMaps that conflict with start Addr and endAddr, as [start, end).
GetNeedUpdateProcessMapsAddrRange(uint32_t ipid,uint64_t startAddr,uint64_t endAddr)588 std::tuple<uint64_t, uint64_t> NativeHookFilter::GetNeedUpdateProcessMapsAddrRange(uint32_t ipid,
589                                                                                    uint64_t startAddr,
590                                                                                    uint64_t endAddr)
591 {
592     uint64_t start = INVALID_UINT64;
593     uint64_t end = INVALID_UINT64;
594     auto startAddrToMapsInfoMapPtr = ipidToStartAddrToMapsInfoMap_.Find(ipid);
595     if (startAddr >= endAddr || startAddrToMapsInfoMapPtr == nullptr) {
596         return std::make_tuple(start, end);
597     }
598     // Find first item in startAddrToMapsInfoMapPtr,
599     // that startItor->second()->start <= startAddr && startItor->second()->end > startAddr.
600     auto startItor = startAddrToMapsInfoMapPtr->upper_bound(startAddr);
601     if (startAddrToMapsInfoMapPtr->begin() != startItor) {
602         --startItor;
603         // Follow the rules of front closing and rear opening, [start, end)
604         if (startItor != startAddrToMapsInfoMapPtr->end() && startAddr >= startItor->second->end()) {
605             ++startItor;
606         }
607     }
608     // Forward query for the last item with filePathId == startItor ->filePathId()
609     if (startItor != startAddrToMapsInfoMapPtr->end()) {
610         auto startFilePathId = startItor->second->file_path_id();
611         while (startAddrToMapsInfoMapPtr->begin() != startItor) {
612             --startItor;
613             if (startFilePathId != startItor->second->file_path_id()) {
614                 ++startItor;
615                 break;
616             }
617         }
618         start = startItor->first;
619     }
620 
621     // Find first item in startAddrToMapsInfoMapPtr, that endItor->second()->start > endAddr
622     auto endItor = startAddrToMapsInfoMapPtr->upper_bound(endAddr);
623     if (endItor == startAddrToMapsInfoMapPtr->end()) {
624         return std::make_tuple(start, end);
625     }
626     if (endItor == startAddrToMapsInfoMapPtr->begin()) {
627         start = INVALID_UINT64;
628         return std::make_tuple(start, end);
629     }
630     // Backward query for the last item with filePathId == endItor ->filePathId()
631     --endItor;
632     auto endFilePathId = endItor->second->file_path_id();
633     ++endItor;
634     while (endItor != startAddrToMapsInfoMapPtr->end()) {
635         if (endFilePathId != endItor->second->file_path_id()) {
636             end = endItor->second->start();
637             break;
638         }
639         endItor++;
640     }
641     return std::make_tuple(start, end);
642 }
643 
ParseArktsOfflineSymbolization(uint64_t ipid,uint64_t arktsIp)644 std::shared_ptr<FrameInfo> NativeHookFilter::ParseArktsOfflineSymbolization(uint64_t ipid, uint64_t arktsIp)
645 {
646     auto arktsFrameInfo = std::make_shared<FrameInfo>();
647     // Under offline symbolization, there is no need to symbolize js data
648     uint64_t arktsFrame = arktsIp & (~JS_IP_MASK);
649     auto arktsReaderFrameInfo = ipidToFrameIdToFrameBytes_.Find(ipid, arktsFrame);
650     if (arktsReaderFrameInfo == nullptr) {
651         TS_LOGE("Can not to find Frame_map.id for js(arkts)!!!");
652         return nullptr;
653     }
654     ProtoReader::Frame_Reader reader(*arktsReaderFrameInfo);
655     // 0 is meaningful, but it is not displayed. Other data is still needed
656     // For js, the last 5 bytes of stack.ip and the outgoing frame member IP are reserved
657     if (reader.has_ip()) {
658         arktsFrameInfo->ip_ = reader.ip();
659     }
660     if (reader.has_symbol_name_id()) {
661         arktsFrameInfo->symbolIndex_ = ipidToSymIdToSymIndex_.Find(ipid, reader.symbol_name_id());
662     }
663     if (reader.has_file_path_id()) {
664         arktsFrameInfo->filePathId_ = reader.file_path_id();
665     }
666     if (reader.has_offset()) {
667         arktsFrameInfo->offset_ = reader.offset();
668     }
669     // Unchanged data is the default value
670     return arktsFrameInfo;
671 }
672 
OfflineSymbolization(const std::shared_ptr<std::vector<uint64_t>> ips)673 std::shared_ptr<std::vector<std::shared_ptr<FrameInfo>>> NativeHookFilter::OfflineSymbolization(
674     const std::shared_ptr<std::vector<uint64_t>> ips)
675 {
676     auto ipid = ips->back();
677     auto result = std::make_shared<std::vector<std::shared_ptr<FrameInfo>>>();
678     for (auto itor = ips->begin(); (itor + 1) != ips->end(); itor++) {
679         if (JS_IP_MASK == (*itor & ALLOC_IP_MASK)) {
680             auto arktsFrameInfo = ParseArktsOfflineSymbolization(ipid, *itor);
681             if (!arktsFrameInfo) {
682                 break;
683             }
684             result->emplace_back(arktsFrameInfo);
685             continue;
686         }
687         auto frameInfo = OfflineSymbolizationByIp(ipid, *itor);
688         // If the IP in the middle of the call stack cannot be symbolized, the remaining IP is discarded
689         if (!frameInfo) {
690             break;
691         }
692         result->emplace_back(frameInfo);
693     }
694     return result;
695 }
FillOfflineSymbolizationFrames(std::map<uint64_t,std::shared_ptr<std::vector<uint64_t>>>::iterator mapItor)696 void NativeHookFilter::FillOfflineSymbolizationFrames(
697     std::map<uint64_t, std::shared_ptr<std::vector<uint64_t>>>::iterator mapItor)
698 {
699     auto curCacheIpid = mapItor->second->back();
700     stackIdToCallChainIdMap_.insert(std::make_pair(mapItor->first, ++callChainId_));
701     auto framesInfo = OfflineSymbolization(mapItor->second);
702     uint16_t depth = 0;
703     if (isSingleProcData_) {
704         curCacheIpid = SINGLE_PROC_IPID;
705     }
706     uint64_t filePathIndex = INVALID_UINT64;
707     for (auto itor = framesInfo->rbegin(); itor != framesInfo->rend(); itor++) {
708         // Note that the filePathId here is provided for the end side. Not a true TS internal index dictionary.
709         auto frameInfo = itor->get();
710         filePathIndex = ipidToFilePathIdToFileIndex_.Find(curCacheIpid, frameInfo->filePathId_);
711         std::string vaddr = base::Uint64ToHexText(frameInfo->symVaddr_);
712         NativeHookFrameVaddrRow nativeHookFrameVaddrRow = {callChainId_,
713                                                            depth++,
714                                                            frameInfo->ip_,
715                                                            frameInfo->symbolIndex_,
716                                                            filePathIndex,
717                                                            frameInfo->offset_,
718                                                            frameInfo->symbolOffset_,
719                                                            vaddr};
720         auto row = traceDataCache_->GetNativeHookFrameData()->AppendNewNativeHookFrame(nativeHookFrameVaddrRow);
721         UpdateFilePathIndexToCallStackRowMap(row, filePathIndex);
722     }
723 }
724 
ReparseStacksWithDifferentMeans()725 void NativeHookFilter::ReparseStacksWithDifferentMeans()
726 {
727     for (auto itor = reparseStackIdToFramesMap_.begin(); itor != reparseStackIdToFramesMap_.end(); itor++) {
728         // Items with key equal to stack id should not be retained in stackIdToCallChainIdMap_
729         if (stackIdToCallChainIdMap_.count(itor->first)) {
730             TS_LOGE("error! The mapping of ambiguous call stack id and callChainId has not been deleted!");
731         }
732         FillOfflineSymbolizationFrames(itor);
733     }
734     reparseStackIdToFramesMap_.clear();
735 }
736 
UpdateReparseStack(uint64_t stackId,std::shared_ptr<std::vector<uint64_t>> frames)737 void NativeHookFilter::UpdateReparseStack(uint64_t stackId, std::shared_ptr<std::vector<uint64_t>> frames)
738 {
739     // delete the stack ids whitch should be parsed again
740     if (stackIdToCallChainIdMap_.count(stackId)) {
741         stackIdToCallChainIdMap_.erase(stackId);
742     }
743     /* update reparseStackIdToFramesMap_. The reparseStackIdToFramesMap_ cannot be parsed immediately.
744     Wait until the relevant memmaps and symbolTable updates are completed. After the main event is
745     updated and before the main event is about to be parsed, parse reparseStackIdToFramesMap_ first. */
746     if (!stackIdToFramesMap_.count(stackId)) {
747         reparseStackIdToFramesMap_.emplace(std::make_pair(stackId, frames));
748     }
749 }
ReparseStacksWithAddrRange(uint64_t start,uint64_t end)750 inline void NativeHookFilter::ReparseStacksWithAddrRange(uint64_t start, uint64_t end)
751 {
752     // Get the list of call stack ids that should be parsed again
753     for (auto itor = allStackIdToFramesMap_.begin(); itor != allStackIdToFramesMap_.end(); itor++) {
754         auto ips = itor->second;
755         for (auto ipsItor = ips->begin(); ipsItor != ips->end(); ipsItor++) {
756             if (*ipsItor >= start && *ipsItor < end) {
757                 UpdateReparseStack(itor->first, itor->second);
758                 break;
759             }
760         }
761     }
762 }
763 
764 // Only called in offline symbolization mode.
ParseMapsEvent(std::unique_ptr<NativeHookMetaData> & nativeHookMetaData)765 void NativeHookFilter::ParseMapsEvent(std::unique_ptr<NativeHookMetaData> &nativeHookMetaData)
766 {
767     segs_.emplace_back(nativeHookMetaData->seg_);
768     const ProtoReader::BytesView &mapsInfoByteView = nativeHookMetaData->reader_->maps_info();
769     if (traceDataCache_->isSplitFile_) {
770         auto hookData = commHookData_.datas->add_events();
771         MapsInfo *mapsInfo = hookData->mutable_maps_info();
772         mapsInfo->ParseFromArray(mapsInfoByteView.Data(), mapsInfoByteView.Size());
773         commHookData_.size += mapsInfoByteView.Size();
774         return;
775     }
776     auto reader = std::make_shared<ProtoReader::MapsInfo_Reader>(mapsInfoByteView);
777 
778     // The temporary variable startAddr here is to solve the problem of parsing errors under the window platform
779     auto startAddr = reader->start();
780     auto endAddr = reader->end();
781     uint64_t start = INVALID_UINT64;
782     uint64_t end = INVALID_UINT64;
783     auto ipid = streamFilters_->processFilter_->UpdateOrCreateProcessWithName(reader->pid(), "");
784     if (isSingleProcData_) {
785         ipid = SINGLE_PROC_IPID;
786     }
787     // Get [start, end) of ips addr range which need to update
788     std::tie(start, end) = GetNeedUpdateProcessMapsAddrRange(ipid, startAddr, endAddr);
789     if (start != INVALID_UINT64 && start != end) { // Conflicting
790         /* First parse the updated call stacks, then parse the main events, and finally update Maps or SymbolTable
791         Note that when tsToMainEventsMap_.size() > MAX_CACHE_SIZE and main events need to be resolved, this logic
792         should also be followed. */
793         ParseFramesInOfflineSymbolizationMode();
794         // When a main event is updated, the call stack that needs to be parsed again is parsed.
795         if (tsToMainEventsMap_.size()) {
796             ReparseStacksWithDifferentMeans();
797             FilterNativeHookMainEvent(tsToMainEventsMap_.size());
798         }
799 
800         // Delete IP symbolization results within the conflict range.
801         auto ipToFrameInfoPtr = const_cast<IpToFrameInfoType *>(ipidToIpToFrameInfo_.Find(ipid));
802         if (ipToFrameInfoPtr != nullptr) {
803             auto ipToFrameInfoItor = ipToFrameInfoPtr->lower_bound(start);
804             while (ipToFrameInfoItor != ipToFrameInfoPtr->end() && ipToFrameInfoItor->first < end) {
805                 ipToFrameInfoItor = ipToFrameInfoPtr->erase(ipToFrameInfoItor);
806             }
807         }
808         // Delete MapsInfo within the conflict range
809         auto startAddrToMapsInfoMapPtr =
810             const_cast<StartAddrToMapsInfoType *>(ipidToStartAddrToMapsInfoMap_.Find(ipid));
811         if (startAddrToMapsInfoMapPtr != nullptr) {
812             auto itor = startAddrToMapsInfoMapPtr->lower_bound(start);
813             while (itor != startAddrToMapsInfoMapPtr->end() && itor->first < end) {
814                 itor = startAddrToMapsInfoMapPtr->erase(itor);
815             }
816         }
817         ReparseStacksWithAddrRange(start, end);
818     }
819     ipidToStartAddrToMapsInfoMap_.Insert(ipid, startAddr, std::move(reader));
820 }
821 template <class T>
UpdateSymbolTablePtrAndStValueToSymAddrMap(T * firstSymbolAddr,const int size,std::shared_ptr<ProtoReader::SymbolTable_Reader> reader)822 void NativeHookFilter::UpdateSymbolTablePtrAndStValueToSymAddrMap(
823     T *firstSymbolAddr,
824     const int size,
825     std::shared_ptr<ProtoReader::SymbolTable_Reader> reader)
826 {
827     for (auto i = 0; i < size; i++) {
828         auto symAddr = firstSymbolAddr + i;
829         if ((symAddr->st_info & STT_FUNC) && symAddr->st_value) {
830             symbolTablePtrAndStValueToSymAddr_.Insert(reader, symAddr->st_value,
831                                                       reinterpret_cast<const uint8_t *>(symAddr));
832         }
833     }
834 }
GetIpRangeByIpidAndFilePathId(uint32_t ipid,uint32_t filePathId)835 std::tuple<uint64_t, uint64_t> NativeHookFilter::GetIpRangeByIpidAndFilePathId(uint32_t ipid, uint32_t filePathId)
836 {
837     uint64_t start = INVALID_UINT32;
838     uint64_t end = 0;
839     auto startAddrToMapsInfoMapPtr = ipidToStartAddrToMapsInfoMap_.Find(ipid);
840     if (startAddrToMapsInfoMapPtr != nullptr) {
841         for (auto itor = startAddrToMapsInfoMapPtr->begin(); itor != startAddrToMapsInfoMapPtr->end(); itor++) {
842             if (itor->second->file_path_id() == filePathId) {
843                 start = std::min(itor->first, start);
844                 end = std::max(itor->second->end(), end);
845             } else if (start != INVALID_UINT32) {
846                 break;
847             }
848         }
849     }
850     return std::make_tuple(start, end);
851 }
DeleteFrameInfoWhichNeedsReparse(uint32_t ipid,uint32_t filePathId)852 void NativeHookFilter::DeleteFrameInfoWhichNeedsReparse(uint32_t ipid, uint32_t filePathId)
853 {
854     // Delete symbolic results with the same filePathId
855     auto ipToFrameInfoPtr = const_cast<IpToFrameInfoType *>(ipidToIpToFrameInfo_.Find(ipid));
856     if (ipToFrameInfoPtr != nullptr) {
857         for (auto itor = ipToFrameInfoPtr->begin(); itor != ipToFrameInfoPtr->end();) {
858             if (itor->second->filePathId_ == filePathId) {
859                 itor = ipToFrameInfoPtr->erase(itor);
860                 continue;
861             }
862             itor++;
863         }
864     }
865 }
ProcSymbolTable(uint32_t ipid,uint32_t filePathId,std::shared_ptr<ProtoReader::SymbolTable_Reader> reader)866 void NativeHookFilter::ProcSymbolTable(uint32_t ipid,
867                                        uint32_t filePathId,
868                                        std::shared_ptr<ProtoReader::SymbolTable_Reader> reader)
869 {
870     auto symbolTablePtr = ipidTofilePathIdToSymbolTableMap_.Find(ipid, filePathId);
871     if (symbolTablePtr != nullptr) { // SymbolTable already exists.
872         /* First parse the updated call stacks, then parse the main events, and finally update Maps or SymbolTable
873         Note that when tsToMainEventsMap_.size() > MAX_CACHE_SIZE and main events need to be resolved, this logic
874         should also be followed. */
875         ParseFramesInOfflineSymbolizationMode();
876         // When a main event is updated, the call stack that needs to be parsed again is parsed.
877         if (tsToMainEventsMap_.size()) {
878             ReparseStacksWithDifferentMeans();
879             FilterNativeHookMainEvent(tsToMainEventsMap_.size());
880         }
881         DeleteFrameInfoWhichNeedsReparse(ipid, filePathId);
882         uint64_t start = INVALID_UINT32;
883         uint64_t end = 0;
884         std::tie(start, end) = GetIpRangeByIpidAndFilePathId(ipid, filePathId);
885         ReparseStacksWithAddrRange(start, end);
886         symbolTablePtr = reader;
887     } else {
888         ipidTofilePathIdToSymbolTableMap_.Insert(ipid, filePathId, reader);
889     }
890 }
891 // Only called in offline symbolization mode.
ParseSymbolTableEvent(std::unique_ptr<NativeHookMetaData> & nativeHookMetaData)892 void NativeHookFilter::ParseSymbolTableEvent(std::unique_ptr<NativeHookMetaData> &nativeHookMetaData)
893 {
894     segs_.emplace_back(nativeHookMetaData->seg_);
895     const ProtoReader::BytesView &symbolTableByteView = nativeHookMetaData->reader_->symbol_tab();
896     if (traceDataCache_->isSplitFile_) {
897         auto hookData = commHookData_.datas->add_events();
898         SymbolTable *symbolTable = hookData->mutable_symbol_tab();
899         symbolTable->ParseFromArray(symbolTableByteView.Data(), symbolTableByteView.Size());
900         commHookData_.size += symbolTableByteView.Size();
901         return;
902     }
903     auto reader = std::make_shared<ProtoReader::SymbolTable_Reader>(symbolTableByteView);
904     auto ipid = streamFilters_->processFilter_->UpdateOrCreateProcessWithName(reader->pid(), "");
905     if (isSingleProcData_) {
906         ipid = SINGLE_PROC_IPID;
907     }
908     ProcSymbolTable(ipid, reader->file_path_id(), reader);
909     auto symEntrySize = reader->sym_entry_size();
910     auto symTable = reader->sym_table();
911     if (symEntrySize == 0) {
912         return;
913     }
914     auto size = symTable.Size() / symEntrySize;
915     if (symEntrySize == ELF32_SYM) {
916         UpdateSymbolTablePtrAndStValueToSymAddrMap(reinterpret_cast<const Elf32_Sym *>(symTable.Data()), size, reader);
917     } else {
918         UpdateSymbolTablePtrAndStValueToSymAddrMap(reinterpret_cast<const Elf64_Sym *>(symTable.Data()), size, reader);
919     }
920 }
921 
MaybeUpdateCurrentSizeDur(uint64_t row,uint64_t timeStamp,bool isMalloc)922 void NativeHookFilter::MaybeUpdateCurrentSizeDur(uint64_t row, uint64_t timeStamp, bool isMalloc)
923 {
924     auto &lastAnyEventRaw = isMalloc ? traceDataCache_->GetNativeHookData()->GetLastMallocEventRaw()
925                                      : traceDataCache_->GetNativeHookData()->GetLastMmapEventRaw();
926     if (lastAnyEventRaw != INVALID_UINT64) {
927         traceDataCache_->GetNativeHookData()->UpdateCurrentSizeDur(lastAnyEventRaw, timeStamp);
928     }
929     lastAnyEventRaw = row;
930 }
931 
932 // when symbolization failed, use filePath + vaddr as symbol name
UpdateSymbolIdsForSymbolizationFailed()933 void NativeHookFilter::UpdateSymbolIdsForSymbolizationFailed()
934 {
935     auto size = traceDataCache_->GetNativeHookFrameData()->Size();
936     for (size_t i = 0; i < size; ++i) {
937         auto symbolNameIndex = traceDataCache_->GetNativeHookFrameData()->SymbolNames()[i];
938         if (symbolNameIndex != INVALID_UINT64) {
939             continue;
940         }
941         auto filePathIndex = traceDataCache_->GetNativeHookFrameData()->FilePaths()[i];
942         if (filePathIndex != INVALID_UINT64) {
943             auto filePathStr = traceDataCache_->dataDict_.GetDataFromDict(filePathIndex);
944             auto vaddrStr = traceDataCache_->GetNativeHookFrameData()->Vaddrs()[i];
945             traceDataCache_->GetNativeHookFrameData()->UpdateSymbolId(
946                 i, traceDataCache_->dataDict_.GetStringIndex(filePathStr + "+" + vaddrStr));
947         } else {
948             // when symbolization failed,filePath and symbolNameIndex invalid
949             auto ip = traceDataCache_->GetNativeHookFrameData()->Ips()[i];
950             // Distinguish whether it is the last layer call stack using the first 3 bytes
951             if (ALLOC_IP_MASK == (ip & ALLOC_IP_MASK)) {
952                 // Take the last five bytes from the IP address
953                 uint64_t ipBitOperation = ip & IP_BIT_OPERATION;
954                 std::ostringstream newSymbol;
955                 //  alloc size (IP(Decimal))bytes 0xIP(hexadecimal conversion)
956                 newSymbol << "alloc size(" << base::number(ipBitOperation, base::INTEGER_RADIX_TYPE_DEC) << "bytes)"
957                           << "0x" << base::number(ip, base::INTEGER_RADIX_TYPE_HEX);
958                 traceDataCache_->GetNativeHookFrameData()->UpdateSymbolId(
959                     i, traceDataCache_->dataDict_.GetStringIndex(newSymbol.str()));
960             } else {
961                 // If the current callChainId is same,unknow 0x ip(Convert IP to hexadecimal)
962                 traceDataCache_->GetNativeHookFrameData()->UpdateSymbolId(
963                     i, traceDataCache_->dataDict_.GetStringIndex("unknown 0x" +
964                                                                  base::number(ip, base::INTEGER_RADIX_TYPE_HEX)));
965             }
966         }
967     }
968 }
ParseFramesInOfflineSymbolizationMode()969 void NativeHookFilter::ParseFramesInOfflineSymbolizationMode()
970 {
971     for (auto stackIdToFramesItor = stackIdToFramesMap_.begin(); stackIdToFramesItor != stackIdToFramesMap_.end();
972          stackIdToFramesItor++) {
973         FillOfflineSymbolizationFrames(stackIdToFramesItor);
974     }
975     // In offline symbolization scenarios, The updated call stack information is saved in stackIdToFramesMap_.
976     // After each parsing is completed, it needs to be cleared to avoid repeated parsing.
977     stackIdToFramesMap_.clear();
978 }
979 
GetNativeHookFrameVaddrs()980 void NativeHookFilter::GetNativeHookFrameVaddrs()
981 {
982     vaddrs_.clear();
983     auto size = traceDataCache_->GetNativeHookFrameData()->Size();
984     // Traverse every piece of native_hook frame data
985     for (size_t i = 0; i < size; i++) {
986         auto symbolOffset = traceDataCache_->GetNativeHookFrameData()->SymbolOffsets()[i];
987         auto fileOffset = traceDataCache_->GetNativeHookFrameData()->Offsets()[i];
988         // When the symbol offset not is INVALID_UINT64, vaddr=offset+symbol offset
989         if (symbolOffset != INVALID_UINT64 && fileOffset != INVALID_UINT64) {
990             auto vaddr = base::Uint64ToHexText(fileOffset + symbolOffset);
991             vaddrs_.emplace_back(vaddr);
992             continue;
993         }
994         // When the symbol offset is 0, vaddr takes the string after the plus sign in the function name
995         auto functionNameIndex = traceDataCache_->GetNativeHookFrameData()->SymbolNames()[i];
996         std::string vaddr = "";
997         auto itor = functionNameIndexToVaddr_.find(functionNameIndex);
998         if (itor == functionNameIndexToVaddr_.end()) {
999             auto functionName = traceDataCache_->dataDict_.GetDataFromDict(functionNameIndex);
1000             auto pos = functionName.rfind("+");
1001             if (pos != functionName.npos && pos != functionName.length() - 1) {
1002                 vaddr = functionName.substr(++pos);
1003             }
1004             // Vaddr keeps "" when lookup failed
1005             functionNameIndexToVaddr_.emplace(std::make_pair(functionNameIndex, vaddr));
1006         } else {
1007             vaddr = itor->second;
1008         }
1009         vaddrs_.emplace_back(vaddr);
1010     }
1011 }
1012 // Called When isCallStackCompressedMode_ is true && isOfflineSymbolizationMode_ is false.
ParseFramesInCallStackCompressedMode()1013 void NativeHookFilter::ParseFramesInCallStackCompressedMode()
1014 {
1015     for (auto stackIdToFramesItor = stackIdToFramesMap_.begin(); stackIdToFramesItor != stackIdToFramesMap_.end();
1016          stackIdToFramesItor++) {
1017         auto frameIds = stackIdToFramesItor->second;
1018         uint16_t depth = 0;
1019         auto curCacheIpid = frameIds->back();
1020         if (isSingleProcData_) {
1021             curCacheIpid = SINGLE_PROC_IPID;
1022         }
1023         for (auto frameIdsItor = frameIds->crbegin() + 1; frameIdsItor != frameIds->crend(); frameIdsItor++) {
1024             auto frameBytesPtr = ipidToFrameIdToFrameBytes_.Find(curCacheIpid, *frameIdsItor);
1025             if (frameBytesPtr == nullptr) {
1026                 TS_LOGE("Can not find Frame by frame_map_id!!!");
1027                 continue;
1028             }
1029             ProtoReader::Frame_Reader reader(*frameBytesPtr);
1030             if (!reader.has_file_path_id() or !reader.has_symbol_name_id()) {
1031                 TS_LOGE("Data exception, frames should has fil_path_id and symbol_name_id");
1032                 continue;
1033             }
1034             auto filePathIndex = ipidToFilePathIdToFileIndex_.Find(curCacheIpid, reader.file_path_id());
1035             if (filePathIndex == INVALID_UINT64) {
1036                 TS_LOGE("Data exception, can not find fil_path_id(%u)!!!", reader.file_path_id());
1037                 continue;
1038             }
1039             auto symbolIndex = ipidToSymIdToSymIndex_.Find(curCacheIpid, reader.symbol_name_id());
1040             if (symbolIndex == INVALID_UINT64) {
1041                 TS_LOGE("Data exception, can not find symbol_name_id!!!");
1042                 continue;
1043             }
1044             // IP may not exist
1045             // 0 is meaningful, but it is not displayed. Other data is still needed
1046             auto frameIp = reader.has_ip() ? reader.ip() : INVALID_UINT64;
1047             auto frameOffset = reader.has_offset() ? reader.offset() : INVALID_UINT64;
1048             auto frameSymbolOffset = reader.has_symbol_offset() ? reader.symbol_offset() : INVALID_UINT64;
1049             NativeHookFrameRow nativeHookFrameRow = {static_cast<uint32_t>(stackIdToFramesItor->first),
1050                                                      depth++,
1051                                                      frameIp,
1052                                                      symbolIndex,
1053                                                      filePathIndex,
1054                                                      frameOffset,
1055                                                      frameSymbolOffset};
1056             auto row = traceDataCache_->GetNativeHookFrameData()->AppendNewNativeHookFrame(nativeHookFrameRow);
1057             UpdateFilePathIndexToCallStackRowMap(row, filePathIndex);
1058         }
1059     }
1060 }
1061 // Called When isCallStackCompressedMode_ is false
ParseFramesWithOutCallStackCompressedMode()1062 void NativeHookFilter::ParseFramesWithOutCallStackCompressedMode()
1063 {
1064     for (auto itor = callChainIdToStackHashValueMap_.begin(); itor != callChainIdToStackHashValueMap_.end(); itor++) {
1065         auto callChainId = itor->first;
1066         if (!stackHashValueToFramesHashMap_.count(itor->second)) {
1067             continue;
1068         }
1069         auto &framesHash = stackHashValueToFramesHashMap_.at(itor->second);
1070         uint16_t depth = 0;
1071         for (auto frameHashValueVectorItor = framesHash.crbegin(); frameHashValueVectorItor != framesHash.crend();
1072              frameHashValueVectorItor++) {
1073             if (!frameHashToFrameInfoMap_.count(*frameHashValueVectorItor)) {
1074                 TS_LOGE("find matching frameInfo failed!!!!");
1075                 return;
1076             }
1077             auto &frameInfo = frameHashToFrameInfoMap_.at(*frameHashValueVectorItor);
1078             NativeHookFrameRow nativeHookFrameRow = {callChainId,
1079                                                      depth++,
1080                                                      frameInfo->ip_,
1081                                                      frameInfo->symbolIndex_,
1082                                                      frameInfo->filePathIndex_,
1083                                                      frameInfo->offset_,
1084                                                      frameInfo->symbolOffset_};
1085             auto row = traceDataCache_->GetNativeHookFrameData()->AppendNewNativeHookFrame(nativeHookFrameRow);
1086             UpdateFilePathIndexToCallStackRowMap(row, frameInfo->filePathIndex_);
1087         }
1088     }
1089 }
ParseSymbolizedNativeHookFrame()1090 void NativeHookFilter::ParseSymbolizedNativeHookFrame()
1091 {
1092     // isOfflineSymbolizationMode is false, but isCallStackCompressedMode is true.
1093     if (isCallStackCompressedMode_) {
1094         ParseFramesInCallStackCompressedMode();
1095     } else {
1096         ParseFramesWithOutCallStackCompressedMode();
1097     }
1098     GetNativeHookFrameVaddrs();
1099     traceDataCache_->GetNativeHookFrameData()->UpdateVaddrs(vaddrs_);
1100     return;
1101 }
UpdateThreadNameWithNativeHookData() const1102 void NativeHookFilter::UpdateThreadNameWithNativeHookData() const
1103 {
1104     if (itidToThreadNameId_.empty() || threadNameIdToThreadNameIndex_.empty()) {
1105         return;
1106     }
1107     for (auto itor = itidToThreadNameId_.begin(); itor != itidToThreadNameId_.end(); ++itor) {
1108         auto thread = traceDataCache_->GetThreadData(itor->first);
1109         if (!thread->nameIndex_) {
1110             auto threadNameMapItor = threadNameIdToThreadNameIndex_.find(itor->second);
1111             if (threadNameMapItor != threadNameIdToThreadNameIndex_.end()) {
1112                 thread->nameIndex_ = threadNameMapItor->second;
1113             }
1114         }
1115     }
1116 }
FinishParseNativeHookData()1117 void NativeHookFilter::FinishParseNativeHookData()
1118 {
1119     // In offline symbolization mode Parse all NativeHook main events depends on updated stackIdToCallChainIdMap_
1120     // during execute ParseSymbolizedNativeHookFrame or ReparseStacksWithDifferentMeans , So first parse the call
1121     // stack data and then parse the main event.
1122     if (isOfflineSymbolizationMode_) {
1123         ParseFramesInOfflineSymbolizationMode();
1124         ReparseStacksWithDifferentMeans();
1125         UpdateSymbolIdsForSymbolizationFailed();
1126     }
1127     FilterNativeHookMainEvent(tsToMainEventsMap_.size());
1128     // In online symbolization mode and callstack is not compressed mode parse stack should after parse main event
1129     // In online symbolization mode and callstack is compressed mode, there is no need worry about the order
1130     if (!isOfflineSymbolizationMode_) {
1131         ParseSymbolizedNativeHookFrame();
1132     }
1133 
1134     // update last lib id
1135     UpdateLastCallerPathAndSymbolIndexs();
1136     UpdateThreadNameWithNativeHookData();
1137 }
UpdateLastCallerPathAndSymbolIndexs()1138 void NativeHookFilter::UpdateLastCallerPathAndSymbolIndexs()
1139 {
1140     GetCallIdToLastLibId();
1141     if (isStatisticMode_) {
1142         traceDataCache_->GetNativeHookStatisticsData()->UpdateLastCallerPathAndSymbolIndexs(
1143             callIdToLastCallerPathIndex_);
1144     } else {
1145         traceDataCache_->GetNativeHookData()->UpdateLastCallerPathAndSymbolIndexs(callIdToLastCallerPathIndex_);
1146     }
1147 }
GetCallIdToLastLibId()1148 void NativeHookFilter::GetCallIdToLastLibId()
1149 {
1150     callIdToLastCallerPathIndex_.clear();
1151     auto size = static_cast<int64_t>(traceDataCache_->GetNativeHookFrameData()->Size());
1152     uint32_t lastCallChainId = INVALID_UINT32;
1153     bool foundLast = false;
1154     for (auto i = size - 1; i > -1; i--) {
1155         auto callChainId = traceDataCache_->GetNativeHookFrameData()->CallChainIds()[i];
1156         if (callChainId == lastCallChainId) {
1157             if (foundLast) {
1158                 continue;
1159             }
1160         }
1161         if (callChainId != lastCallChainId) {
1162             lastCallChainId = callChainId;
1163             foundLast = false;
1164         }
1165         auto filePathIndex = traceDataCache_->GetNativeHookFrameData()->FilePaths()[i];
1166         if (filePathIndex == INVALID_UINT64) {
1167             continue;
1168         }
1169         auto symbolIndex = traceDataCache_->GetNativeHookFrameData()->SymbolNames()[i];
1170         if (!traceDataCache_->GetNativeHookFrameData()->Depths()[i]) {
1171             callIdToLastCallerPathIndex_.insert({callChainId, std::make_tuple(filePathIndex, symbolIndex)});
1172             foundLast = true;
1173             continue;
1174         }
1175 
1176         auto lower = std::lower_bound(invalidLibPathIndexs_.begin(), invalidLibPathIndexs_.end(), filePathIndex);
1177         if (lower == invalidLibPathIndexs_.end() || *lower != filePathIndex) { // found
1178             auto filePath = traceDataCache_->dataDict_.GetDataFromDict(filePathIndex);
1179             auto ret = filePath.find("libc++_shared.so");
1180             if (ret == filePath.npos) {
1181                 callIdToLastCallerPathIndex_.insert({callChainId, std::make_tuple(filePathIndex, symbolIndex)});
1182                 foundLast = true;
1183             }
1184         }
1185     }
1186 }
1187 
1188 template <class T>
UpdateFilePathIdAndStValueToSymAddrMap(T * firstSymbolAddr,const int size,uint32_t filePathId)1189 void NativeHookFilter::UpdateFilePathIdAndStValueToSymAddrMap(T *firstSymbolAddr, const int size, uint32_t filePathId)
1190 {
1191     for (auto i = 0; i < size; i++) {
1192         auto symAddr = firstSymbolAddr + i;
1193         if ((symAddr->st_info & STT_FUNC) && (symAddr->st_value)) {
1194             filePathIdAndStValueToSymAddr_.Insert(filePathId, symAddr->st_value,
1195                                                   reinterpret_cast<const uint8_t *>(symAddr));
1196         }
1197     }
1198 }
1199 
NativeHookReloadElfSymbolTable(const std::vector<std::unique_ptr<SymbolsFile>> & symbolsFiles)1200 void NativeHookFilter::NativeHookReloadElfSymbolTable(const std::vector<std::unique_ptr<SymbolsFile>> &symbolsFiles)
1201 {
1202     auto nativeHookFrame = traceDataCache_->GetNativeHookFrameData();
1203     auto size = nativeHookFrame->Size();
1204     auto filePathIndexs = nativeHookFrame->FilePaths();
1205     auto vaddrs = nativeHookFrame->Vaddrs();
1206     for (const auto &symbolsFile : symbolsFiles) {
1207         std::shared_ptr<std::set<size_t>> frameRows = nullptr;
1208         for (const auto &item : filePathIndexToFrameTableRowMap_) {
1209             auto filePath = traceDataCache_->GetDataFromDict(item.first);
1210             if (base::EndWith(filePath, symbolsFile->filePath_)) {
1211                 frameRows = item.second;
1212                 break;
1213             }
1214         }
1215         if (frameRows == nullptr) {
1216             continue;
1217         }
1218         for (auto row : *frameRows) {
1219             auto symVaddr = base::StrToInt<uint32_t>(vaddrs[row], base::INTEGER_RADIX_TYPE_HEX);
1220             if (!symVaddr.has_value()) {
1221                 continue;
1222             }
1223             auto dfxSymbol = symbolsFile->GetSymbolWithVaddr(symVaddr.value());
1224             if (dfxSymbol.IsValid()) {
1225                 auto newSymbolIndex = traceDataCache_->GetDataIndex(dfxSymbol.GetName());
1226                 nativeHookFrame->UpdateSymbolId(row, newSymbolIndex);
1227             }
1228         }
1229     }
1230     UpdateLastCallerPathAndSymbolIndexs();
1231 }
UpdateFilePathIndexToCallStackRowMap(size_t row,DataIndex filePathIndex)1232 void NativeHookFilter::UpdateFilePathIndexToCallStackRowMap(size_t row, DataIndex filePathIndex)
1233 {
1234     if (filePathIndex != INVALID_UINT64) {
1235         if (filePathIndexToFrameTableRowMap_.count(filePathIndex) == 0) {
1236             auto rows = std::make_shared<std::set<size_t>>();
1237             rows->insert(row);
1238             filePathIndexToFrameTableRowMap_[filePathIndex] = rows;
1239         } else {
1240             filePathIndexToFrameTableRowMap_[filePathIndex]->insert(row);
1241         }
1242     }
1243 }
GetCommHookData()1244 CommHookData &NativeHookFilter::GetCommHookData()
1245 {
1246     return commHookData_;
1247 }
GetHookPluginData()1248 ProfilerPluginData *NativeHookFilter::GetHookPluginData()
1249 {
1250     return hookPluginData_.get();
1251 }
SerializeHookCommDataToString()1252 void NativeHookFilter::SerializeHookCommDataToString()
1253 {
1254     if (commHookData_.size == 0) {
1255         return;
1256     }
1257     std::string hookBuffer;
1258     commHookData_.datas->SerializeToString(&hookBuffer);
1259     hookPluginData_->set_data(hookBuffer);
1260     std::unique_ptr<std::string> pluginBuffer = std::make_unique<std::string>();
1261     hookPluginData_->SerializeToString(pluginBuffer.get());
1262     traceDataCache_->HookCommProtos().push_back(std::move(pluginBuffer));
1263     hookPluginData_->Clear();
1264     commHookData_.datas->Clear();
1265     commHookData_.size = 0;
1266     hookPluginData_->set_name("nativehook");
1267 }
1268 } // namespace TraceStreamer
1269 } // namespace SysTuning
1270