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