• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 "log_parse.h"
16 
17 #include "string_util.h"
18 #include "tbox.h"
19 
20 using namespace std;
21 namespace OHOS {
22 namespace HiviewDFX {
23 const std::string LogParse::UNMATCHED_EXCEPTION = "UnMatchedException";
24 
25 // some stack function is invalid, so it should be ignored
26 const std::map<std::string, std::set<std::string>> LogParse::ignoreList_ = {
27     {"Level1", {
28         "libc.so",
29         "libc++.so",
30         "ld-musl-aarch64.so",
31         "libc_fdleak_debug.so",
32         "unknown",
33         "watchdog",
34         "kthread",
35         "rdr_system_error"}
36     },
37     {"Level2", {
38         "libart.so",
39         "__switch_to",
40         "dump_backtrace",
41         "show_stack",
42         "dump_stack"}
43     },
44     {"Level3", {
45         "panic"}
46     }
47 };
48 
IsIgnoreLibrary(const string & val) const49 bool LogParse::IsIgnoreLibrary(const string& val) const
50 {
51     for (auto list : ignoreList_) {
52         for (auto str : list.second) {
53             if (val.find(str, 0) != string::npos) {
54                 return true;
55             }
56         }
57     }
58     return false;
59 }
60 
GetStackTop(const vector<string> & validStack,const size_t num) const61 stack<string> LogParse::GetStackTop(const vector<string>& validStack, const size_t num) const
62 {
63     size_t len = validStack.size();
64     stack<string> stackTop;
65     for (size_t i = 0; i < len; i++) {
66         if (i == 0 || len - i < num) {
67             stackTop.push(validStack.at(i));
68         }
69     }
70     return stackTop;
71 }
72 
StackToPart(stack<string> & inStack,size_t num) const73 vector<string> LogParse::StackToPart(stack<string>& inStack, size_t num) const
74 {
75     stack<string> partStack;
76     while (!inStack.empty()) {
77         string topStr = inStack.top();
78         StringUtil::EraseString(topStr, "\t");
79         partStack.push(topStr);
80         inStack.pop();
81     }
82     vector<string> validPart;
83     if (!partStack.empty()) {
84         validPart = GetValidStack(num, partStack);
85     }
86     return validPart;
87 }
88 
GetValidBlock(stack<string> inStack,vector<string> & lastPart) const89 string LogParse::GetValidBlock(stack<string> inStack, vector<string>& lastPart) const
90 {
91     vector<string> validStack;
92 
93     lastPart = StackToPart(inStack, 3); // 3 : first/second/last frame
94     if (lastPart.empty()) {
95         return "";
96     } else if (lastPart.size() > STACK_LEN_MAX) {
97         // keep the begin 28 lines and the end 2 lines
98         lastPart.erase(lastPart.begin() + (STACK_LEN_MAX - 2), lastPart.end() - 2); // 2 : end 2 lines
99     }
100 
101     reverse(lastPart.begin(), lastPart.end());
102 
103     for (auto& it : lastPart) {
104         it = Tbox::GetStackName(it);
105     }
106     return Tbox::ARRAY_STR + StringUtil::VectorToString(lastPart, false);
107 }
108 
GetValidStack(size_t num,stack<string> & inStack) const109 vector<string> LogParse::GetValidStack(size_t num, stack<string>& inStack) const
110 {
111     stack<string> src = inStack;
112     vector<string> validStack;
113     stack<string> outStatck;
114     size_t len = src.size();
115     for (size_t i = 0; i < len; i++) {
116         auto stackFrame = src.top();
117         if (!IsIgnoreLibrary(stackFrame)) {
118             validStack.push_back(stackFrame);
119         }
120         src.pop();
121     }
122     if (validStack.empty()) {
123         MatchIgnoreLibrary(inStack, outStatck, num);
124         len = outStatck.size();
125         for (size_t i = 0; i < len; i++) {
126             validStack.push_back(outStatck.top());
127             outStatck.pop();
128         }
129     }
130     return validStack;
131 }
132 
MatchIgnoreLibrary(stack<string> inStack,stack<string> & outStack,size_t num) const133 void LogParse::MatchIgnoreLibrary(stack<string> inStack, stack<string>& outStack, size_t num) const
134 {
135     if (inStack.size() <= num) {
136         outStack = inStack;
137         return;
138     }
139     size_t count = 0;
140     for (auto it = ignoreList_.rbegin(); it != ignoreList_.rend(); ++it) {
141         if (count == ignoreList_.size() - 1) {
142             outStack = inStack;
143             return;
144         }
145 
146         stack<string> src = inStack;
147         while (src.size() > num) {
148             string name = src.top();
149             for (auto str : it->second) {
150                 if (name.find(str, 0) != string::npos) {
151                     outStack = src;
152                     return;
153                 }
154             }
155             src.pop();
156         }
157         count++;
158     }
159 }
160 
161 /*
162  * INPUT :
163  *  info : trace spliting by "\n"
164  * OUTPUT :
165  *  trace : last part trace to get Frame
166  *  return string : valid trace spliting by "\n"
167  */
GetFilterTrace(const std::string & info,std::vector<std::string> & trace,std::string eventType) const168 std::string LogParse::GetFilterTrace(const std::string& info, std::vector<std::string>& trace,
169     std::string eventType) const
170 {
171     std::string newInfo = info;
172     if (eventType == "JS_ERROR" && newInfo.find("libace_napi.z.so") != std::string::npos) {
173         newInfo = StringUtil::GetRightSubstr(info, "libace_napi.z.so");
174     }
175     StringUtil::SplitStr(newInfo, "\n", trace, false, false);
176     std::stack<std::string> traceStack;
177     for (const auto& str : trace) {
178         traceStack.push(str);
179     }
180     trace.clear();
181     return GetValidBlock(traceStack, trace);
182 }
183 
SetFrame(std::stack<std::string> & stack,std::map<std::string,std::string> & eventInfo) const184 void LogParse::SetFrame(std::stack<std::string>& stack, std::map<std::string, std::string>& eventInfo) const
185 {
186     std::vector<std::string> name = {"FIRST_FRAME", "SECOND_FRAME", "LAST_FRAME"};
187     size_t len = stack.size();
188     for (size_t i = 0; i < len; i++) {
189         if (eventInfo.find(name[i]) == eventInfo.end()) {
190             eventInfo[name[i]] = stack.top();
191         }
192         stack.pop();
193     }
194 }
195 }
196 }
197