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 #ifndef PBREADER_PARSER_H 17 #define PBREADER_PARSER_H 18 #include <cstdint> 19 #include <limits> 20 #include <map> 21 #include <stdexcept> 22 #include <string> 23 #include <thread> 24 #include "common_types.h" 25 #include "common_types.pbreader.h" 26 #include "clock_filter_ex.h" 27 #ifdef ENABLE_EBPF 28 #include "ebpf_data_parser.h" 29 #endif 30 #include "file.h" 31 #include "pbreader_clock_detail_parser.h" 32 #ifdef ENABLE_HTRACE 33 #include "htrace_cpu_detail_parser.h" 34 #include "htrace_symbols_detail_parser.h" 35 #endif 36 #ifdef ENABLE_FFRT 37 #include "pbreader_ffrt_parser.h" 38 #endif 39 #include "htrace_plugin_time_parser.h" 40 #ifdef ENABLE_CPUDATA 41 #include "pbreader_cpu_data_parser.h" 42 #endif 43 #ifdef ENABLE_DISKIO 44 #include "pbreader_disk_io_parser.h" 45 #endif 46 #ifdef ENABLE_HTDUMP 47 #include "pbreader_hidump_parser.h" 48 #endif 49 #ifdef ENABLE_HILOG 50 #include "pbreader_hilog_parser.h" 51 #endif 52 #ifdef ENABLE_HISYSEVENT 53 #include "pbreader_hisysevent_parser.h" 54 #endif 55 #ifdef ENABLE_ARKTS 56 #include "pbreader_js_memory_parser.h" 57 #endif 58 #ifdef ENABLE_MEMORY 59 #include "pbreader_mem_parser.h" 60 #endif 61 #ifdef ENABLE_NATIVE_HOOK 62 #include "pbreader_native_hook_parser.h" 63 #endif 64 #ifdef ENABLE_NETWORK 65 #include "pbreader_network_parser.h" 66 #endif 67 #ifdef ENABLE_PROCESS 68 #include "pbreader_process_parser.h" 69 #endif 70 #include "parser_base.h" 71 #include "pbreader_file_header.h" 72 #ifdef ENABLE_HIPERF 73 #include "perf_data_parser.h" 74 #endif 75 #include "proto_reader_help.h" 76 #include "string_help.h" 77 #include "symbols_file.h" 78 #include "trace_data_cache.h" 79 #include "trace_streamer_filters.h" 80 #include "ts_common.h" 81 #ifdef ENABLE_STREAM_EXTEND 82 #include "pbreader_stream_parser.h" 83 #endif 84 85 namespace SysTuning { 86 namespace TraceStreamer { 87 using namespace SysTuning::base; 88 using namespace OHOS::Developtools::HiPerf; 89 class PbreaderParser : public ParserBase, public HtracePluginTimeParser { 90 public: 91 PbreaderParser(TraceDataCache *dataCache, const TraceStreamerFilters *filters); 92 ~PbreaderParser(); 93 void ParseTraceDataSegment(std::unique_ptr<uint8_t[]> bufferStr, size_t size, bool isFinish = false) override; 94 bool ReparseSymbolFilesAndResymbolization(std::string &symbolsPath, std::vector<std::string> &symbolsPaths); 95 void WaitForParserEnd(); 96 #ifdef ENABLE_ARKTS 97 void EnableFileSeparate(bool enabled); 98 #endif 99 #if defined(ENABLE_HIPERF) || defined(ENABLE_NATIVE_HOOK) || defined(ENABLE_EBPF) 100 void ParserFileSO(std::string &directory, const std::vector<std::string> &relativeFilePaths); 101 #endif 102 #ifdef ENABLE_HIPERF 103 void TraceDataSegmentEnd(bool isSplitFile); 104 void StoreTraceDataSegment(std::unique_ptr<uint8_t[]> bufferStr, size_t size, int32_t isFinish); 105 #endif GetPbreaderSplitData()106 const auto &GetPbreaderSplitData() 107 { 108 return mPbreaderSplitData_; 109 } GetProfilerHeader()110 auto GetProfilerHeader() 111 { 112 return profilerTraceFileHeader_; 113 } 114 #ifdef ENABLE_NATIVE_HOOK ClearNativehookData()115 auto ClearNativehookData() 116 { 117 pbreaderNativeHookParser_->FinishSplitNativeHook(); 118 } 119 #endif GetDataSourceType()120 auto GetDataSourceType() 121 { 122 return dataSourceType_; 123 } 124 #ifdef ENABLE_ARKTS GetJsMemoryData()125 auto GetJsMemoryData() 126 { 127 return jsMemoryParser_.get(); 128 } GetArkTsConfigData()129 auto GetArkTsConfigData() 130 { 131 return arkTsConfigData_; 132 } 133 #endif ClearPbreaderSplitData()134 auto ClearPbreaderSplitData() 135 { 136 #ifdef ENABLE_HIPERF 137 perfDataParser_->ClearPerfSplitResult(); 138 perfProcessedLen_ = 0; 139 #endif 140 #ifdef ENABLE_EBPF 141 ebpfDataParser_->ClearEbpfSplitResult(); 142 hasInitEbpfPublicData_ = false; 143 parsedEbpfOver_ = false; 144 #endif 145 processedDataLen_ = 0; 146 splitFileOffset_ = 0; 147 hasGotHeader_ = false; 148 return mPbreaderSplitData_.clear(); 149 } 150 #ifdef ENABLE_HIPERF GetPerfSplitResult()151 const auto &GetPerfSplitResult() 152 { 153 return perfDataParser_->GetPerfSplitResult(); 154 } 155 #endif 156 #ifdef ENABLE_EBPF GetEbpfDataParser()157 const auto &GetEbpfDataParser() 158 { 159 return ebpfDataParser_; 160 } 161 #endif 162 #ifdef ENABLE_HTRACE EnableOnlyParseFtrace()163 void EnableOnlyParseFtrace() 164 { 165 onlyParseFtrace_ = true; 166 } 167 #endif 168 169 private: 170 bool ParseDataRecursively(std::deque<uint8_t>::iterator &packagesBegin, size_t ¤tLength); 171 #ifdef ENABLE_HIPERF 172 bool ParseHiperfData(std::deque<uint8_t>::iterator &packagesBegin, size_t ¤tLength); 173 #endif 174 void ParseTraceDataItem(const std::string &buffer) override; 175 void FilterData(PbreaderDataSegment &seg, bool isSplitFile); 176 void ParserData(PbreaderDataSegment &dataSeg, bool isSplitFile); 177 178 private: 179 #if IS_WASM 180 bool ParseSDKData(); 181 #endif 182 void InitPluginNameIndex(); 183 void InitHookPluginNameIndex(); 184 void InitMemoryPluginNameIndex(); 185 void InitHiPluginNameIndex(); 186 void WaitForHPluginParserEnd(); 187 void WaitForOtherPluginParserEnd(); 188 bool GetHeaderAndUpdateLengthMark(std::deque<uint8_t>::iterator &packagesBegin, size_t ¤tLength); 189 bool ParseSegLengthAndEnsureSegDataEnough(std::deque<uint8_t>::iterator &packagesBegin, size_t ¤tLength); 190 #ifdef ENABLE_MEMORY 191 void ParseMemory(const ProtoReader::ProfilerPluginData_Reader &pluginDataZero, PbreaderDataSegment &dataSeg); 192 void ParseMemoryConfig(PbreaderDataSegment &dataSeg, const ProtoReader::ProfilerPluginData_Reader &pluginDataZero); 193 #endif 194 #ifdef ENABLE_HILOG 195 void ParseHilog(PbreaderDataSegment &dataSeg); 196 #endif 197 #ifdef ENABLE_HTRACE 198 void ParseFtrace(PbreaderDataSegment &dataSeg); 199 #endif 200 #ifdef ENABLE_FFRT 201 void ParseFfrtConfig(PbreaderDataSegment &dataSeg); 202 void ParseFfrt(PbreaderDataSegment &dataSeg); 203 #endif 204 #ifdef ENABLE_HTDUMP 205 void ParseFPS(PbreaderDataSegment &dataSeg); 206 #endif 207 #ifdef ENABLE_CPUDATA 208 void ParseCpuUsage(PbreaderDataSegment &dataSeg); 209 #endif 210 #ifdef ENABLE_NETWORK 211 void ParseNetwork(PbreaderDataSegment &dataSeg); 212 #endif 213 #ifdef ENABLE_DISKIO 214 void ParseDiskIO(PbreaderDataSegment &dataSeg); 215 #endif 216 #ifdef ENABLE_PROCESS 217 void ParseProcess(PbreaderDataSegment &dataSeg); 218 #endif 219 #ifdef ENABLE_HISYSEVENT 220 void ParseHisysevent(PbreaderDataSegment &dataSeg); 221 void ParseHisyseventConfig(PbreaderDataSegment &dataSeg); 222 #endif 223 #ifdef ENABLE_NATIVE_HOOK 224 void ParseNativeHookConfig(PbreaderDataSegment &dataSeg); 225 void ParseNativeHook(PbreaderDataSegment &dataSeg, bool isSplitFile); 226 #endif 227 #ifdef ENABLE_ARKTS 228 void ParseJSMemory(const ProtoReader::ProfilerPluginData_Reader &pluginDataZero, 229 PbreaderDataSegment &dataSeg, 230 bool isSplitFile); 231 void ParseJSMemoryConfig(PbreaderDataSegment &dataSeg); 232 #endif 233 #ifdef ENABLE_STREAM_EXTEND 234 void ParseStream(PbreaderDataSegment &dataSeg); 235 #endif 236 void ParseThread(); 237 int32_t GetNextSegment(); 238 void FilterThread(); 239 #ifdef ENABLE_EBPF 240 bool CalcEbpfCutOffset(std::deque<uint8_t>::iterator &packagesBegin, size_t ¤tLength); 241 #endif 242 bool SpliteConfigData(const std::string &pluginName, const PbreaderDataSegment &dataSeg); 243 bool InitProfilerTraceFileHeader(); 244 void ParseDataByPluginName(PbreaderDataSegment &dataSeg, 245 DataIndex pulginNameIndex, 246 const ProtoReader::ProfilerPluginData_Reader &pluginDataZero, 247 bool isSplitFile); 248 bool SpliteDataBySegment(DataIndex pluginNameIndex, PbreaderDataSegment &dataSeg); 249 ProfilerTraceFileHeader profilerTraceFileHeader_; 250 uint32_t profilerDataType_ = ProfilerTraceFileHeader::UNKNOW_TYPE; 251 uint64_t profilerDataLength_ = 0; 252 ProfilerPluginDataHeader profilerPluginData_; 253 uint64_t pbreaderCurentLength_ = 0; 254 char standalonePluginName_[ProfilerTraceFileHeader::PLUGIN_MODULE_NAME_MAX + 1] = ""; 255 bool hasGotSegLength_ = false; 256 bool hasGotHeader_ = false; 257 uint32_t nextLength_ = 0; 258 const size_t packetSegLength_ = 4; 259 const size_t packetHeaderLength_ = 1024; 260 TraceDataCache *traceDataCache_; 261 std::unique_ptr<PbreaderClockDetailParser> pbreaderClockDetailParser_; 262 #ifdef ENABLE_HTRACE 263 std::unique_ptr<HtraceCpuDetailParser> htraceCpuDetailParser_; 264 std::unique_ptr<HtraceSymbolsDetailParser> htraceSymbolsDetailParser_; 265 ClockId dataSourceTypeTraceClockid_ = TS_CLOCK_UNKNOW; 266 bool onlyParseFtrace_ = false; 267 #endif 268 std::set<DataIndex> ftracePluginIndex_ = {}; 269 #ifdef ENABLE_FFRT 270 DataIndex ffrtPluginIndex_ = {}; 271 DataIndex ffrtPluginConfigIndex_ = {}; 272 std::unique_ptr<PbreaderFfrtDetailParser> pbreaderFfrtParser_; 273 #endif 274 #ifdef ENABLE_MEMORY 275 std::unique_ptr<PbreaderMemParser> pbreaderMemParser_; 276 ClockId dataSourceTypeMemClockid_ = TS_CLOCK_UNKNOW; 277 DataIndex memPluginIndex_; 278 DataIndex memoryPluginConfigIndex_; 279 #endif 280 #ifdef ENABLE_HTDUMP 281 std::unique_ptr<PbreaderHidumpParser> pbreaderHidumpParser_; 282 std::set<DataIndex> hidumpPluginIndex_ = {}; 283 ClockId dataSourceTypeFpsClockid_ = TS_CLOCK_UNKNOW; 284 #endif 285 #ifdef ENABLE_CPUDATA 286 std::unique_ptr<PbreaderCpuDataParser> cpuUsageParser_; 287 ClockId dataSourceTypeCpuClockid_ = TS_CLOCK_UNKNOW; 288 DataIndex cpuPluginIndex_; 289 #endif 290 #ifdef ENABLE_NETWORK 291 std::unique_ptr<PbreaderNetworkParser> networkParser_; 292 ClockId dataSourceTypeNetworkClockid_ = TS_CLOCK_UNKNOW; 293 DataIndex networkPluginIndex_; 294 #endif 295 #ifdef ENABLE_DISKIO 296 std::unique_ptr<PbreaderDiskIOParser> diskIOParser_; 297 ClockId dataSourceTypeDiskioClockid_ = TS_CLOCK_UNKNOW; 298 DataIndex diskioPluginIndex_; 299 #endif 300 #ifdef ENABLE_PROCESS 301 std::unique_ptr<PbreaderProcessParser> processParser_; 302 ClockId dataSourceTypeProcessClockid_ = TS_CLOCK_UNKNOW; 303 DataIndex processPluginIndex_; 304 #endif 305 #ifdef ENABLE_HISYSEVENT 306 std::unique_ptr<PbreaderHisyseventParser> hisyseventParser_; 307 ClockId dataSourceTypeHisyseventClockid_ = TS_CLOCK_UNKNOW; 308 DataIndex hisyseventPluginIndex_; 309 DataIndex hisyseventPluginConfigIndex_; 310 #endif 311 #ifdef ENABLE_ARKTS 312 std::unique_ptr<PbreaderJSMemoryParser> jsMemoryParser_; 313 ClockId dataSourceTypeJSMemoryClockid_ = TS_CLOCK_UNKNOW; 314 #endif 315 #ifdef ENABLE_HIPERF 316 uint64_t perfProcessedLen_ = 0; 317 std::unique_ptr<PerfDataParser> perfDataParser_; 318 #endif 319 #ifdef ENABLE_EBPF 320 std::unique_ptr<EbpfDataParser> ebpfDataParser_; 321 bool hasInitEbpfPublicData_ = false; 322 bool parsedEbpfOver_ = false; 323 #endif 324 #ifdef ENABLE_NATIVE_HOOK 325 std::unique_ptr<PbreaderNativeHookParser> pbreaderNativeHookParser_; 326 ClockId dataSourceTypeNativeHookClockid_ = TS_CLOCK_UNKNOW; 327 std::set<DataIndex> nativeHookPluginIndex_ = {}; 328 DataIndex nativeHookConfigIndex_; 329 #endif 330 #ifdef ENABLE_HILOG 331 std::set<DataIndex> hilogPluginIndex_ = {}; 332 std::unique_ptr<PbreaderHiLogParser> pbreaderHiLogParser_; 333 ClockId dataSourceTypeHilogClockid_ = TS_CLOCK_UNKNOW; 334 #endif 335 #ifdef ENABLE_STREAM_EXTEND 336 DataIndex streamPluginIndex_; 337 std::unique_ptr<PbreaderStreamParser> pbreaderStreamParser_; 338 #endif 339 std::unique_ptr<PbreaderDataSegment[]> dataSegArray_; 340 std::atomic<bool> filterThreadStarted_{false}; 341 const int32_t maxSegArraySize = 10000; 342 int32_t rawDataHead_ = 0; 343 bool toExit_ = false; 344 bool exited_ = false; 345 int32_t filterHead_ = 0; 346 int32_t parseHead_ = 0; 347 size_t pbreaderLength_ = 1024; 348 const int32_t sleepDur_ = 100; 349 bool parseThreadStarted_ = false; 350 int32_t parserThreadCount_ = 0; 351 std::mutex pbreaderDataSegMux_ = {}; 352 std::vector<std::unique_ptr<SymbolsFile>> symbolsFiles_; 353 std::map<int32_t, int32_t> mPbreaderSplitData_ = {}; 354 uint64_t splitFileOffset_ = 0; 355 uint64_t processedDataLen_ = 0; 356 uint64_t parsedFileOffset_ = 0; 357 uint32_t dataSourceType_ = INVALID_UINT32; 358 std::string arkTsConfigData_ = ""; 359 std::string lenBuffer_ = ""; 360 DataIndex arktsPluginIndex_; 361 DataIndex arktsPluginConfigIndex_; 362 std::set<DataIndex> supportPluginNameIndex_ = {}; 363 }; 364 } // namespace TraceStreamer 365 } // namespace SysTuning 366 367 #endif // HTRACE_PARSER_H_ 368