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