• 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 #include "print_event_parser.h"
16 #include "animation_filter.h"
17 #include "clock_filter_ex.h"
18 #include "frame_filter.h"
19 #include "stat_filter.h"
20 #include "string_to_numerical.h"
21 #include <cinttypes>
22 namespace SysTuning {
23 namespace TraceStreamer {
24 const uint8_t POINT_LENGTH = 1;
25 const uint8_t MAX_POINT_LENGTH = 2;
PrintEventParser(TraceDataCache * dataCache,const TraceStreamerFilters * filter)26 PrintEventParser::PrintEventParser(TraceDataCache *dataCache, const TraceStreamerFilters *filter)
27     : EventParserBase(dataCache, filter)
28 {
29     rsOnDoCompositionEvent_ = traceDataCache_->GetDataIndex(rsOnDoCompositionStr_);
30     eventToFrameFunctionMap_ = {
31         {recvievVsync_, bind(&PrintEventParser::ReciveVsync, this, std::placeholders::_1, std::placeholders::_2,
32                              std::placeholders::_3)},
33         {rsOnDoCompositionEvent_, bind(&PrintEventParser::RSReciveOnDoComposition, this, std::placeholders::_1,
34                                        std::placeholders::_2, std::placeholders::_3)},
35         {marshRwTransactionData_, bind(&PrintEventParser::OnRwTransaction, this, std::placeholders::_1,
36                                        std::placeholders::_2, std::placeholders::_3)},
37         {rsMainThreadProcessCmd_, bind(&PrintEventParser::OnMainThreadProcessCmd, this, std::placeholders::_1,
38                                        std::placeholders::_2, std::placeholders::_3)}};
39 }
40 
ParsePrintEvent(const std::string & comm,uint64_t ts,uint32_t pid,std::string_view event,const BytraceLine & line)41 bool PrintEventParser::ParsePrintEvent(const std::string &comm,
42                                        uint64_t ts,
43                                        uint32_t pid,
44                                        std::string_view event,
45                                        const BytraceLine &line)
46 {
47     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_TRACING_MARK_WRITE, STAT_EVENT_RECEIVED);
48     TracePoint point;
49     if (GetTracePoint(event, point) != PARSE_SUCCESS) {
50         streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_TRACING_MARK_WRITE, STAT_EVENT_DATA_INVALID);
51         return false;
52     }
53     if (point.tgid_) {
54         // tgid use 'B|' after with 'TGID', the '(TGID)' maybe wrong, eg: xxx-21675 ( 1264) ...: print: B|21675|...
55         const_cast<BytraceLine &>(line).tgid = point.tgid_;
56         streamFilters_->processFilter_->GetOrCreateInternalPid(ts, point.tgid_);
57     }
58     switch (point.phase_) {
59         case 'B': {
60             ParseBeginEvent(comm, ts, pid, point, line);
61             break;
62         }
63         case 'E': {
64             ParseEndEvent(ts, pid, point);
65             break;
66         }
67         case 'S': {
68             ParseStartEvent(comm, ts, pid, point, line);
69             break;
70         }
71         case 'F': {
72             ParseFinishEvent(ts, pid, point, line);
73             break;
74         }
75         case 'C': {
76             ParseCreateEvent(ts, point);
77             break;
78         }
79         default:
80             TS_LOGD("point missing!");
81             return false;
82     }
83     return true;
84 }
ParseBeginEvent(const std::string & comm,uint64_t ts,uint32_t pid,TracePoint & point,const BytraceLine & line)85 void PrintEventParser::ParseBeginEvent(const std::string &comm,
86                                        uint64_t ts,
87                                        uint32_t pid,
88                                        TracePoint &point,
89                                        const BytraceLine &line)
90 {
91     uint32_t index = streamFilters_->sliceFilter_->BeginSlice(comm, ts, pid, point.tgid_, INVALID_DATAINDEX,
92                                                               traceDataCache_->GetDataIndex(point.name_));
93     if (index != INVALID_UINT32) {
94         // add distributed data
95         traceDataCache_->GetInternalSlicesData()->SetDistributeInfo(index, point.chainId_, point.spanId_,
96                                                                     point.parentSpanId_, point.flag_);
97         if (pid == point.tgid_) {
98             if (HandleFrameSliceBeginEvent(point.funcPrefixId_, index, point.funcArgs_, line)) {
99                 return;
100             }
101         }
102         bool isDiscontinued = false;
103         if (traceDataCache_->TaskPoolTraceEnabled()) {
104             isDiscontinued = streamFilters_->taskPoolFilter_->TaskPoolEvent(point.name_, index);
105         }
106         if (traceDataCache_->AnimationTraceEnabled() && !isDiscontinued) {
107             (void)HandleAnimationBeginEvent(point, index, line);
108         }
109     } else {
110         streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_TRACING_MARK_WRITE, STAT_EVENT_DATA_LOST);
111     }
112 }
ParseEndEvent(uint64_t ts,uint32_t pid,const TracePoint & point)113 void PrintEventParser::ParseEndEvent(uint64_t ts, uint32_t pid, const TracePoint &point)
114 {
115     uint32_t index = streamFilters_->sliceFilter_->EndSlice(ts, pid, point.tgid_);
116     if (pid == point.tgid_) {
117         HandleFrameSliceEndEvent(ts, point.tgid_, pid, index);
118     }
119     if (traceDataCache_->AnimationTraceEnabled()) {
120         streamFilters_->animationFilter_->EndDynamicFrameEvent(ts, index);
121     }
122 }
ParseStartEvent(const std::string & comm,uint64_t ts,uint32_t pid,const TracePoint & point,const BytraceLine & line)123 void PrintEventParser::ParseStartEvent(const std::string &comm,
124                                        uint64_t ts,
125                                        uint32_t pid,
126                                        const TracePoint &point,
127                                        const BytraceLine &line)
128 {
129     auto cookie = static_cast<int64_t>(point.value_);
130     auto index = streamFilters_->sliceFilter_->StartAsyncSlice(ts, pid, point.tgid_, cookie,
131                                                                traceDataCache_->GetDataIndex(point.name_));
132     if (point.name_ == onFrameQueeuStartEvent_ && index != INVALID_UINT64) {
133         OnFrameQueueStart(ts, index, point.tgid_);
134     } else if (traceDataCache_->AnimationTraceEnabled() && index != INVALID_UINT64 &&
135                base::EndWith(comm, onAnimationProcEvent_)) { // the comm is taskName
136         streamFilters_->animationFilter_->StartAnimationEvent(line, point, index);
137     }
138 }
ParseFinishEvent(uint64_t ts,uint32_t pid,const TracePoint & point,const BytraceLine & line)139 void PrintEventParser::ParseFinishEvent(uint64_t ts, uint32_t pid, const TracePoint &point, const BytraceLine &line)
140 {
141     auto cookie = static_cast<int64_t>(point.value_);
142     auto index = streamFilters_->sliceFilter_->FinishAsyncSlice(ts, pid, point.tgid_, cookie,
143                                                                 traceDataCache_->GetDataIndex(point.name_));
144     HandleFrameQueueEndEvent(ts, point.tgid_, point.tgid_, index);
145     if (traceDataCache_->AnimationTraceEnabled()) {
146         streamFilters_->animationFilter_->FinishAnimationEvent(line, index);
147     }
148 }
ParseCreateEvent(uint64_t ts,const TracePoint & point)149 void PrintEventParser::ParseCreateEvent(uint64_t ts, const TracePoint &point)
150 {
151     DataIndex nameIndex = traceDataCache_->GetDataIndex(point.name_);
152     uint32_t internalPid = streamFilters_->processFilter_->GetInternalPid(point.tgid_);
153     if (internalPid != INVALID_ID) {
154         streamFilters_->processMeasureFilter_->AppendNewMeasureData(internalPid, nameIndex, ts, point.value_);
155         streamFilters_->processFilter_->AddProcessMemory(internalPid);
156     } else {
157         streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_TRACING_MARK_WRITE, STAT_EVENT_DATA_INVALID);
158     }
159 }
HandleAnimationBeginEvent(const TracePoint & point,size_t callStackRow,const BytraceLine & line)160 bool PrintEventParser::HandleAnimationBeginEvent(const TracePoint &point, size_t callStackRow, const BytraceLine &line)
161 {
162     if (!streamFilters_->animationFilter_->UpdateDeviceInfoEvent(point, line)) {
163         return streamFilters_->animationFilter_->BeginDynamicFrameEvent(point, callStackRow);
164     }
165     return true;
166 }
SetTraceType(TraceFileType traceType)167 void PrintEventParser::SetTraceType(TraceFileType traceType)
168 {
169     traceType_ = traceType;
170 }
SetTraceClockId(BuiltinClocks clock)171 void PrintEventParser::SetTraceClockId(BuiltinClocks clock)
172 {
173     if (clock != clock_) {
174         clock_ = clock;
175     }
176 }
Finish()177 void PrintEventParser::Finish()
178 {
179     eventToFrameFunctionMap_.clear();
180     frameCallIds_.clear();
181     vsyncSliceIds_.clear();
182     streamFilters_->animationFilter_->Clear();
183     streamFilters_->frameFilter_->Clear();
184 }
CheckTracePoint(std::string_view pointStr) const185 ParseResult PrintEventParser::CheckTracePoint(std::string_view pointStr) const
186 {
187     if (pointStr.size() == 0) {
188         TS_LOGD("get trace point data size is 0!");
189         return PARSE_ERROR;
190     }
191 
192     std::string clockSyncSts = "trace_event_clock_sync";
193     if (pointStr.compare(0, clockSyncSts.length(), clockSyncSts.c_str()) == 0) {
194         TS_LOGD("skip trace point :%s!", clockSyncSts.c_str());
195         return PARSE_ERROR;
196     }
197 
198     if (pointStr.find_first_of('B') != 0 && pointStr.find_first_of('E') != 0 && pointStr.find_first_of('C') != 0 &&
199         pointStr.find_first_of('S') != 0 && pointStr.find_first_of('F') != 0) {
200         TS_LOGD("trace point not supported : [%c] !", pointStr[0]);
201         return PARSE_ERROR;
202     }
203 
204     if (pointStr.find_first_of('E') != 0 && pointStr.size() == 1) {
205         TS_LOGD("point string size error!");
206         return PARSE_ERROR;
207     }
208 
209     if (pointStr.size() >= MAX_POINT_LENGTH) {
210         if ((pointStr[1] != '|') && (pointStr[1] != '\n')) {
211             TS_LOGD("not support data formart!");
212             return PARSE_ERROR;
213         }
214     }
215 
216     return PARSE_SUCCESS;
217 }
218 
GetPointNameForBegin(std::string_view pointStr,size_t tGidlength) const219 std::string_view PrintEventParser::GetPointNameForBegin(std::string_view pointStr, size_t tGidlength) const
220 {
221     size_t index = MAX_POINT_LENGTH + tGidlength + POINT_LENGTH;
222 
223     size_t length = pointStr.size() - index - ((pointStr.back() == '\n') ? 1 : 0);
224     std::string_view name = std::string_view(pointStr.data() + index, length);
225     // remove space at the end
226     name = std::string_view(name.data(), name.find_last_not_of(" ") + 1);
227     return name;
228 }
229 
HandlerB(std::string_view pointStr,TracePoint & outPoint,size_t tGidlength) const230 ParseResult PrintEventParser::HandlerB(std::string_view pointStr, TracePoint &outPoint, size_t tGidlength) const
231 {
232     outPoint.name_ = GetPointNameForBegin(pointStr, tGidlength);
233     if (outPoint.name_.empty()) {
234         TS_LOGD("point name is empty!");
235         return PARSE_ERROR;
236     }
237     // Use ## to differentiate distributed data
238     if (outPoint.name_.find("##") == std::string::npos) {
239         auto space = outPoint.name_.find(' ');
240         if (space != std::string::npos) {
241             outPoint.funcPrefix_ = outPoint.name_.substr(0, space);
242             outPoint.funcPrefixId_ = traceDataCache_->GetDataIndex(outPoint.funcPrefix_);
243             outPoint.funcArgs_ = outPoint.name_.substr(space + 1);
244         } else {
245             outPoint.funcPrefixId_ = traceDataCache_->GetDataIndex(outPoint.name_);
246         }
247         return PARSE_SUCCESS;
248     }
249     // Resolve distributed calls
250     // the normal data mybe like:
251     // system-1298 ( 1298) [001] ...1 174330.287420: tracing_mark_write: B|1298|H:[8b00e96b2,2,1]#C##decodeFrame"
252     const std::regex distributeMatcher = std::regex(R"(H:\[([a-z0-9]+),([a-z0-9]+),([a-z0-9]+)\]#([CS]?)##(.*))");
253     std::smatch matcheLine;
254     bool matched = std::regex_match(outPoint.name_, matcheLine, distributeMatcher);
255     if (matched) {
256         size_t index = 0;
257         outPoint.chainId_ = matcheLine[++index].str();
258         outPoint.spanId_ = matcheLine[++index].str();
259         outPoint.parentSpanId_ = matcheLine[++index].str();
260         outPoint.flag_ = matcheLine[++index].str();
261     }
262     return PARSE_SUCCESS;
263 }
264 
HandleFrameSliceBeginEvent(DataIndex eventName,size_t callStackRow,std::string & args,const BytraceLine & line)265 bool PrintEventParser::HandleFrameSliceBeginEvent(DataIndex eventName,
266                                                   size_t callStackRow,
267                                                   std::string &args,
268                                                   const BytraceLine &line)
269 {
270     auto it = eventToFrameFunctionMap_.find(eventName);
271     if (it != eventToFrameFunctionMap_.end()) {
272         it->second(callStackRow, args, line);
273         return true;
274     } else if (StartWith(traceDataCache_->GetDataFromDict(eventName), rsOnDoCompositionStr_)) {
275         RSReciveOnDoComposition(callStackRow, args, line);
276         return true;
277     }
278     return false;
279 }
ReciveVsync(size_t callStackRow,std::string & args,const BytraceLine & line)280 bool PrintEventParser::ReciveVsync(size_t callStackRow, std::string &args, const BytraceLine &line)
281 {
282     streamFilters_->statFilter_->IncreaseStat(TRACE_VSYNC, STAT_EVENT_RECEIVED);
283     // args is like "dataCount:24bytes now:211306766162 expectedEnd:211323423844 vsyncId:3179"
284     std::sregex_iterator it(args.begin(), args.end(), recvVsyncPattern_);
285     std::sregex_iterator end;
286     uint64_t now = INVALID_UINT64;
287     uint64_t expectEnd = INVALID_UINT64;
288     uint32_t vsyncId = INVALID_UINT32;
289     while (it != end) {
290         std::smatch match = *it;
291         std::string key = match.str(1);
292         std::string value = match.str(2);
293         if (key == "now") {
294             now = base::StrToInt<uint64_t>(value).value();
295         } else if (key == "expectedEnd") {
296             expectEnd = base::StrToInt<uint64_t>(value).value();
297         } else if (key == "vsyncId") {
298             vsyncId = base::StrToInt<uint64_t>(value).value();
299         }
300         ++it;
301     }
302     if (convertVsyncTs_ && traceType_ == TRACE_FILETYPE_H_TRACE) {
303         if (now != INVALID_UINT64) {
304             now = streamFilters_->clockFilter_->ToPrimaryTraceTime(TS_MONOTONIC, now);
305         }
306         if (expectEnd != INVALID_UINT64) {
307             expectEnd = streamFilters_->clockFilter_->ToPrimaryTraceTime(TS_MONOTONIC, expectEnd);
308         }
309     }
310     streamFilters_->frameFilter_->BeginVsyncEvent(line, now, expectEnd, vsyncId, callStackRow);
311     vsyncSliceIds_.push_back(callStackRow);
312     return true;
313 }
RSReciveOnDoComposition(size_t callStackRow,std::string & args,const BytraceLine & line)314 bool PrintEventParser::RSReciveOnDoComposition(size_t callStackRow, std::string &args, const BytraceLine &line)
315 {
316     streamFilters_->statFilter_->IncreaseStat(TRACE_ON_DO_COMPOSITION, STAT_EVENT_RECEIVED);
317     auto iTid = streamFilters_->processFilter_->GetInternalTid(line.pid);
318     (void)streamFilters_->frameFilter_->MarkRSOnDoCompositionEvent(line.ts, iTid);
319     return true;
320 }
OnRwTransaction(size_t callStackRow,std::string & args,const BytraceLine & line)321 bool PrintEventParser::OnRwTransaction(size_t callStackRow, std::string &args, const BytraceLine &line)
322 {
323     // H:MarshRSTransactionData cmdCount:20 transactionFlag:[3799,8] isUni:1
324     std::smatch match;
325     if (std::regex_search(args, match, transFlagPattern_)) {
326         std::string flag2 = match.str(2);
327         auto iTid = streamFilters_->processFilter_->GetInternalTid(line.pid);
328         return streamFilters_->frameFilter_->BeginRSTransactionData(line.ts, iTid,
329                                                                     base::StrToInt<uint32_t>(flag2).value());
330     }
331     return true;
332 }
OnMainThreadProcessCmd(size_t callStackRow,std::string & args,const BytraceLine & line)333 bool PrintEventParser::OnMainThreadProcessCmd(size_t callStackRow, std::string &args, const BytraceLine &line)
334 {
335     std::sregex_iterator it(args.begin(), args.end(), mainProcessCmdPattern);
336     std::sregex_iterator end;
337     std::vector<FrameFilter::FrameMap> frames;
338     while (it != end) {
339         std::smatch match = *it;
340         std::string value1 = match.str(1);
341         std::string value2 = match.str(2);
342         frames.push_back({streamFilters_->processFilter_->GetInternalTid(base::StrToInt<uint32_t>(value1).value()),
343                           base::StrToInt<uint32_t>(value2).value()});
344         ++it;
345     }
346     auto iTid = streamFilters_->processFilter_->GetInternalTid(line.pid);
347     return streamFilters_->frameFilter_->BeginProcessCommandUni(line.ts, iTid, frames, callStackRow);
348 }
OnFrameQueueStart(uint64_t ts,size_t callStackRow,uint64_t pid)349 bool PrintEventParser::OnFrameQueueStart(uint64_t ts, size_t callStackRow, uint64_t pid)
350 {
351     streamFilters_->statFilter_->IncreaseStat(TRACE_FRAMEQUEUE, STAT_EVENT_RECEIVED);
352     auto iTid = streamFilters_->processFilter_->GetInternalTid(pid);
353     if (streamFilters_->frameFilter_->StartFrameQueue(ts, iTid)) {
354         frameCallIds_.push_back(callStackRow);
355     }
356     return true;
357 }
HandleFrameSliceEndEvent(uint64_t ts,uint64_t pid,uint64_t tid,size_t callStackRow)358 void PrintEventParser::HandleFrameSliceEndEvent(uint64_t ts, uint64_t pid, uint64_t tid, size_t callStackRow)
359 {
360     // it can be frame or slice
361     auto iTid = streamFilters_->processFilter_->GetInternalTid(tid);
362     auto pos = std::find(vsyncSliceIds_.begin(), vsyncSliceIds_.end(), callStackRow);
363     if (pos != vsyncSliceIds_.end()) {
364         if (!streamFilters_->frameFilter_->EndVsyncEvent(ts, iTid)) {
365             streamFilters_->statFilter_->IncreaseStat(TRACE_VSYNC, STAT_EVENT_NOTMATCH);
366         }
367         vsyncSliceIds_.erase(pos);
368     }
369     return;
370 }
371 
HandleFrameQueueEndEvent(uint64_t ts,uint64_t pid,uint64_t tid,size_t callStackRow)372 void PrintEventParser::HandleFrameQueueEndEvent(uint64_t ts, uint64_t pid, uint64_t tid, size_t callStackRow)
373 {
374     // it can be frame or slice
375     auto iTid = streamFilters_->processFilter_->GetInternalTid(tid);
376     auto pos = std::find(frameCallIds_.begin(), frameCallIds_.end(), callStackRow);
377     if (pos != frameCallIds_.end()) {
378         TS_LOGD("ts:%" PRIu64 ", frameSliceEnd:%" PRIu64 "", ts, tid);
379         if (!streamFilters_->frameFilter_->EndFrameQueue(ts, iTid)) {
380             streamFilters_->statFilter_->IncreaseStat(TRACE_FRAMEQUEUE, STAT_EVENT_NOTMATCH);
381             TS_LOGW("ts:%" PRIu64 ", frameSliceEnd:%" PRIu64 " failed", ts, tid);
382         }
383         frameCallIds_.erase(pos);
384     }
385     return;
386 }
HandlerE(void)387 ParseResult PrintEventParser::HandlerE(void)
388 {
389     return PARSE_SUCCESS;
390 }
391 
GetNameLength(std::string_view pointStr,size_t nameIndex)392 size_t PrintEventParser::GetNameLength(std::string_view pointStr, size_t nameIndex)
393 {
394     size_t namelength = 0;
395     for (size_t i = nameIndex; i < pointStr.size(); i++) {
396         if (pointStr[i] == ' ') {
397             namelength = i - nameIndex;
398         }
399         if (pointStr[i] == '|') {
400             namelength = i - nameIndex;
401             break;
402         }
403     }
404     return namelength;
405 }
406 
GetValueLength(std::string_view pointStr,size_t valueIndex) const407 size_t PrintEventParser::GetValueLength(std::string_view pointStr, size_t valueIndex) const
408 {
409     size_t valuePipe = pointStr.find('|', valueIndex);
410     size_t valueLen = pointStr.size() - valueIndex;
411     if (valuePipe != std::string_view::npos) {
412         valueLen = valuePipe - valueIndex;
413     }
414 
415     if (valueLen == 0) {
416         return 0;
417     }
418 
419     if (pointStr[valueIndex + valueLen - POINT_LENGTH] == '\n') {
420         valueLen--;
421     }
422 
423     return valueLen;
424 }
425 
HandlerCSF(std::string_view pointStr,TracePoint & outPoint,size_t tGidlength) const426 ParseResult PrintEventParser::HandlerCSF(std::string_view pointStr, TracePoint &outPoint, size_t tGidlength) const
427 {
428     // point name
429     size_t nameIndex = MAX_POINT_LENGTH + tGidlength + POINT_LENGTH;
430     size_t namelength = GetNameLength(pointStr, nameIndex);
431     if (namelength == 0) {
432         TS_LOGD("point name length is error!");
433         return PARSE_ERROR;
434     }
435     outPoint.name_ = std::string_view(pointStr.data() + nameIndex, namelength);
436 
437     // point value
438     size_t valueIndex = nameIndex + namelength + POINT_LENGTH;
439     size_t valueLen = GetValueLength(pointStr, valueIndex);
440     if (valueLen == 0) {
441         TS_LOGD("point value length is error!");
442         return PARSE_ERROR;
443     }
444 
445     std::string valueStr(pointStr.data() + valueIndex, valueLen);
446     if (!base::StrToInt<int64_t>(valueStr).has_value()) {
447         TS_LOGD("point value is error!");
448         return PARSE_ERROR;
449     }
450     outPoint.value_ = base::StrToInt<int64_t>(valueStr).value();
451 
452     size_t valuePipe = pointStr.find('|', valueIndex);
453     if (valuePipe != std::string_view::npos) {
454         size_t groupLen = pointStr.size() - valuePipe - POINT_LENGTH;
455         if (groupLen == 0) {
456             return PARSE_ERROR;
457         }
458 
459         if (pointStr[pointStr.size() - POINT_LENGTH] == '\n') {
460             groupLen--;
461         }
462 
463         outPoint.categoryGroup_ = std::string_view(pointStr.data() + valuePipe + 1, groupLen);
464     }
465 
466     return PARSE_SUCCESS;
467 }
468 
GetTracePoint(std::string_view pointStr,TracePoint & outPoint) const469 ParseResult PrintEventParser::GetTracePoint(std::string_view pointStr, TracePoint &outPoint) const
470 {
471     if (CheckTracePoint(pointStr) != PARSE_SUCCESS) {
472         return PARSE_ERROR;
473     }
474 
475     size_t tGidlength = 0;
476     // we may get wrong format data like tracing_mark_write: E
477     // while the format data must be E|call-tid
478     // please use a regular-format to get all the data
479     outPoint.phase_ = pointStr.front();
480     outPoint.tgid_ = GetThreadGroupId(pointStr, tGidlength);
481 
482     ParseResult ret = PARSE_ERROR;
483     switch (outPoint.phase_) {
484         case 'B': {
485             ret = HandlerB(pointStr, outPoint, tGidlength);
486             break;
487         }
488         case 'E': {
489             ret = HandlerE();
490             break;
491         }
492         case 'S':
493         case 'F':
494         case 'C': {
495             ret = HandlerCSF(pointStr, outPoint, tGidlength);
496             break;
497         }
498         default:
499             return PARSE_ERROR;
500     }
501     return ret;
502 }
503 
GetThreadGroupId(std::string_view pointStr,size_t & length) const504 uint32_t PrintEventParser::GetThreadGroupId(std::string_view pointStr, size_t &length) const
505 {
506     for (size_t i = MAX_POINT_LENGTH; i < pointStr.size(); i++) {
507         if (pointStr[i] == '|' || pointStr[i] == '\n') {
508             break;
509         }
510 
511         if (pointStr[i] < '0' || pointStr[i] > '9') {
512             return PARSE_ERROR;
513         }
514 
515         length++;
516     }
517 
518     std::string str(pointStr.data() + MAX_POINT_LENGTH, length);
519     return base::StrToInt<uint32_t>(str).value_or(0);
520 }
521 } // namespace TraceStreamer
522 } // namespace SysTuning
523