• 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 "freeze_detector_plugin.h"
17 
18 #include "logger.h"
19 #include "plugin_factory.h"
20 #include "string_util.h"
21 #include "sys_event_dao.h"
22 
23 namespace OHOS {
24 namespace HiviewDFX {
25 REGISTER_PROXY(FreezeDetectorPlugin);
26 DEFINE_LOG_TAG("FreezeDetector");
FreezeDetectorPlugin()27 FreezeDetectorPlugin::FreezeDetectorPlugin()
28 {
29 }
30 
~FreezeDetectorPlugin()31 FreezeDetectorPlugin::~FreezeDetectorPlugin()
32 {
33 }
34 
ReadyToLoad()35 bool FreezeDetectorPlugin::ReadyToLoad()
36 {
37     freezeCommon_ = std::make_shared<FreezeCommon>();
38     bool ret1 = freezeCommon_->Init();
39     freezeResolver_ = std::make_unique<FreezeResolver>(freezeCommon_);
40     bool ret2 = freezeResolver_->Init();
41     return ret1 && ret2;
42 }
43 
OnLoad()44 void FreezeDetectorPlugin::OnLoad()
45 {
46     HIVIEW_LOGD("OnLoad.");
47     SetName(FREEZE_DETECTOR_PLUGIN_NAME);
48     SetVersion(FREEZE_DETECTOR_PLUGIN_VERSION);
49 
50     threadLoop_ = GetWorkLoop();
51     if (threadLoop_ == nullptr) {
52         HIVIEW_LOGW("thread loop is null.");
53         return;
54     }
55     threadLoop_->StartLoop(false);
56     freezeCommon_ = std::make_shared<FreezeCommon>();
57     bool ret = freezeCommon_->Init();
58     if (!ret) {
59         HIVIEW_LOGW("freezeCommon_->Init false.");
60         freezeCommon_ = nullptr;
61         return;
62     }
63     freezeResolver_ = std::make_unique<FreezeResolver>(freezeCommon_);
64     ret = freezeResolver_->Init();
65     if (!ret) {
66         HIVIEW_LOGW("freezeResolver_->Init false.");
67         freezeCommon_ = nullptr;
68         freezeResolver_ = nullptr;
69     }
70 }
71 
OnUnload()72 void FreezeDetectorPlugin::OnUnload()
73 {
74     HIVIEW_LOGD("OnUnload.");
75 }
76 
OnEvent(std::shared_ptr<Event> & event)77 bool FreezeDetectorPlugin::OnEvent(std::shared_ptr<Event> &event)
78 {
79     return false;
80 }
81 
CanProcessEvent(std::shared_ptr<Event> event)82 bool FreezeDetectorPlugin::CanProcessEvent(std::shared_ptr<Event> event)
83 {
84     return false;
85 }
86 
RemoveRedundantNewline(const std::string & content) const87 std::string FreezeDetectorPlugin::RemoveRedundantNewline(const std::string& content) const
88 {
89     std::vector<std::string> lines;
90     StringUtil::SplitStr(content, "\\n", lines, false, false);
91 
92     std::string outContent;
93     for (const auto& line : lines) {
94         outContent.append(line).append("\n");
95     }
96     return outContent;
97 }
98 
MakeWatchPoint(const Event & event)99 WatchPoint FreezeDetectorPlugin::MakeWatchPoint(const Event& event)
100 {
101     Event& eventRef = const_cast<Event&>(event);
102     SysEvent& sysEvent = static_cast<SysEvent&>(eventRef);
103 
104     long seq = sysEvent.GetSeq();
105     long tid = sysEvent.GetTid();
106     long pid = sysEvent.GetEventIntValue(FreezeCommon::EVENT_PID);
107     pid = pid ? pid : sysEvent.GetPid();
108     long uid = sysEvent.GetEventIntValue(FreezeCommon::EVENT_UID);
109     uid = uid ? uid : sysEvent.GetUid();
110     std::string packageName = sysEvent.GetEventValue(FreezeCommon::EVENT_PACKAGE_NAME);
111     std::string processName = sysEvent.GetEventValue(FreezeCommon::EVENT_PROCESS_NAME);
112     std::string msg = RemoveRedundantNewline(sysEvent.GetEventValue(FreezeCommon::EVENT_MSG));
113     std::string info = sysEvent.GetEventValue(EventStore::EventCol::INFO);
114     std::regex reg("logPath:([^,]+)");
115     std::smatch result;
116     std::string logPath = "";
117     if (std::regex_search(info, result, reg)) {
118         logPath = result[1].str();
119     }
120     WatchPoint watchPoint = OHOS::HiviewDFX::WatchPoint::Builder()
121         .InitSeq(seq)
122         .InitDomain(event.domain_)
123         .InitStringId(event.eventName_)
124         .InitTimestamp(event.happenTime_)
125         .InitPid(pid)
126         .InitTid(tid)
127         .InitUid(uid)
128         .InitPackageName(packageName)
129         .InitProcessName(processName)
130         .InitMsg(msg)
131         .InitLogPath(logPath)
132         .Build();
133     HIVIEW_LOGI("watchpoint domain=%{public}s, stringid=%{public}s, pid=%{public}ld, uid=%{public}ld, "
134         "seq=%{public}ld, packageName=%{public}s, processName=%{public}s, msg=%{public}s logPath=%{public}s.",
135         event.domain_.c_str(), event.eventName_.c_str(), pid, uid,
136         seq, packageName.c_str(), processName.c_str(), msg.c_str(), logPath.c_str());
137 
138     return watchPoint;
139 }
140 
OnEventListeningCallback(const Event & event)141 void FreezeDetectorPlugin::OnEventListeningCallback(const Event& event)
142 {
143     HIVIEW_LOGD("received event id=%{public}u, domain=%{public}s, stringid=%{public}s, extraInfo=%{public}s.",
144         event.eventId_, event.domain_.c_str(), event.eventName_.c_str(), event.jsonExtraInfo_.c_str());
145     if (freezeCommon_ == nullptr) {
146         return;
147     }
148 
149     if (freezeCommon_->IsFreezeEvent(event.domain_, event.eventName_) == false) {
150         HIVIEW_LOGE("not freeze event.");
151         return;
152     }
153 
154     HIVIEW_LOGD("received event domain=%{public}s, stringid=%{public}s",
155         event.domain_.c_str(), event.eventName_.c_str());
156     HIVIEW_LOGD("threadLoop_->IsRunning() = %{public}d", threadLoop_->IsRunning());
157     this->AddUseCount();
158     // dispatcher context, send task to our thread
159     WatchPoint watchPoint = MakeWatchPoint(event);
160     if (watchPoint.GetLogPath().empty()) {
161         return;
162     }
163 
164     std::shared_ptr<FreezeRuleCluster> freezeRuleCluster = freezeCommon_->GetFreezeRuleCluster();
165     std::vector<FreezeResult> freezeResultList;
166     bool ruleRet = freezeRuleCluster->GetResult(watchPoint, freezeResultList);
167     if (!ruleRet) {
168         return;
169     }
170     long delayTime = 0;
171     if (freezeResultList.size() > 1) {
172         for (auto& i : freezeResultList) {
173             long window = i.GetWindow();
174             delayTime = std::max(delayTime, window);
175         }
176         if (delayTime == 0) {
177             delayTime = 10; // delay: 10s
178         }
179     }
180     auto task = std::bind(&FreezeDetectorPlugin::ProcessEvent, this, watchPoint);
181     threadLoop_->AddTimerEvent(nullptr, nullptr, task, delayTime, false);
182 }
183 
ProcessEvent(WatchPoint watchPoint)184 void FreezeDetectorPlugin::ProcessEvent(WatchPoint watchPoint)
185 {
186     HIVIEW_LOGD("received event domain=%{public}s, stringid=%{public}s",
187         watchPoint.GetDomain().c_str(), watchPoint.GetStringId().c_str());
188     if (freezeResolver_ == nullptr) {
189         this->SubUseCount();
190         return;
191     }
192 
193     auto ret = freezeResolver_->ProcessEvent(watchPoint);
194     if (ret < 0) {
195         HIVIEW_LOGE("FreezeResolver ProcessEvent filled.");
196     }
197     this->SubUseCount();
198 }
199 } // namespace HiviewDFX
200 } // namespace OHOS
201