• 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 #include "segment_analysis.h"
16 
17 #include <fcntl.h>
18 #include <unistd.h>
19 
20 #include "file_util.h"
21 #include "log_util.h"
22 #include "logger.h"
23 #include "string_util.h"
24 using namespace std;
25 namespace OHOS {
26 namespace HiviewDFX {
27 DEFINE_LOG_TAG("SegmentAnalysis");
~SegmentAnalysis()28 SegmentAnalysis::~SegmentAnalysis()
29 {
30     errLogBuf_.str("");
31 }
32 
Analyze(const string & logFile,const ParamFeature & feature,const vector<string> & startSeg,const vector<string> & segStackMatch)33 bool SegmentAnalysis::Analyze(const string& logFile, const ParamFeature& feature,
34     const vector<string>& startSeg, const vector<string>& segStackMatch)
35 {
36     if (!CheckParam(feature, startSeg)) {
37         HIVIEW_LOGE("logFile: %{public}s, CheckParam failed", logFile.c_str());
38         return false;
39     }
40     HIVIEW_LOGI("logFile: %{public}s, feature size: %{public}zu, startSeg: %{public}s",
41         logFile.c_str(), feature.size(), startSeg[0].c_str());
42     if (segMap_.size() == 0) {
43         RecordLayerOneSegment(feature);
44     }
45     if (!GetStartSegment(startSeg) || startSeg_ == nullptr) {
46         HIVIEW_LOGE("Failed to get any segment, segMap_ size: %{public}zu\n", segMap_.size());
47         return false;
48     }
49     if (!LogUtil::ReadFileBuff(logFile, errLogBuf_)) {
50         HIVIEW_LOGE("read logFile: %{public}s failed\n", logFile.c_str());
51         return false;
52     }
53     if (NeedAnalyzeBlockedChain()) {
54         AnalyzeBlockedChain();
55         GetBlockedChain();
56     }
57     GetEndStack(segStackMatch);
58     return true;
59 }
60 
GetResult(map<string,string> & result) const61 void SegmentAnalysis::GetResult(map<string, string>& result) const
62 {
63     if (!reason_.empty()) {
64         result[RESULT_REASON] = reason_;
65     }
66     if (!blockedChain_.empty()) {
67         result[RESULT_BLOCKED_CHAIN] = blockedChain_;
68     }
69     if (!allStacks_.empty()) {
70         result[RESULT_ALL_STACKS] = allStacks_;
71     }
72     if (!endStack_.empty()) {
73         result[RESULT_END_STACK] = endStack_;
74     }
75 }
76 
AddSegment(int id,UniqSegment & seg)77 void SegmentAnalysis::AddSegment(int id, UniqSegment& seg)
78 {
79     if (id < 0) {
80         HIVIEW_LOGE("segment id invalid: %{public}d", id);
81         return;
82     }
83     idNameVec_.push_back(make_tuple(id, seg->GetName()));
84     segMap_.insert(make_pair(id, move(seg))); // if id already exists, no more update
85 }
86 
GetSegment(int id,UniqSegment & seg)87 bool SegmentAnalysis::GetSegment(int id, UniqSegment& seg)
88 {
89     auto it = segMap_.find(id);
90     if (it != segMap_.end()) {
91         seg = move(it->second);
92         segMap_.erase(it); // no need to keep it in the map
93         return true;
94     }
95     return false;
96 }
97 
GetNameById(int id) const98 string SegmentAnalysis::GetNameById(int id) const
99 {
100     for (const auto& idName : idNameVec_) {
101         if (get<0>(idName) == id) {
102             return get<1>(idName);
103         }
104     }
105     return string("");
106 }
107 
RecordLayerOneSegment(const ParamFeature & feature)108 void SegmentAnalysis::RecordLayerOneSegment(const ParamFeature& feature)
109 {
110     /*
111      * examples of feature:
112      * ("LayerOneCmd.v_id", LineFeature)
113      * ("LayerOneCmd.v_name", LineFeature)
114      * ...
115      * ("LayerOneCmd.v_id", LineFeature)
116      * ("LayerOneCmd.v_name", LineFeature)
117      */
118     auto isFirst = [](const pair<string, LineFeature> &p) {return p.first.find(SEGMENT_CMD_LAYER_ONE) == 0;};
119     auto iter = find_if(begin(feature), end(feature), isFirst);
120     while (iter != end(feature)) {
121         auto nextBegin = iter->first;
122         string value = iter->second.value;
123         auto seg = make_unique<Segment>();
124         seg->SetValue(StringUtil::GetRightSubstr(iter->first, SEGMENT_DELIM), value);
125         seg->SetValue(SEGMENT_CURSOR, to_string(iter->second.lineCursor));
126         for (int i = 1; i < LAYER_ONE_CMD_PARAM_NUM; ++i) {
127             ++iter; // to prevent dead loop
128             if (iter != end(feature) &&
129                 iter->first != nextBegin &&
130                 iter->first.find(SEGMENT_CMD_LAYER_ONE) == 0) {
131                 seg->SetValue(StringUtil::GetRightSubstr(iter->first, SEGMENT_DELIM), iter->second.value);
132             } else {
133                 HIVIEW_LOGE("wrong format, nextBegin: %{public}s %{public}s", nextBegin.c_str(), value.c_str());
134                 break;
135             }
136         }
137         int id = seg->GetId();
138         AddSegment(id, seg);
139         auto isNext = [&](const pair<string, LineFeature> &p) {return p.first == nextBegin;};
140         auto iterNext = find_if(iter, end(feature), isNext);
141         RecordOtherSegment(feature, id, iter, iterNext);
142         iter = iterNext;
143     }
144 }
145 } // namespace HiviewDFX
146 } // namespace OHOS