1 /*
2  * Copyright (c) 2024 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 "fault_detector_manager.h"
16 
17 #include <memory>
18 #include <string>
19 #include <vector>
20 
21 #include <sys/epoll.h>
22 
23 #include "app_event_publisher.h"
24 #include "app_event_publisher_factory.h"
25 #include "event_loop.h"
26 #include "fault_detector_util.h"
27 #include "fault_state_base.h"
28 #include "hiview_logger.h"
29 #include "native_leak_detector.h"
30 #include "native_leak_state_context.h"
31 #include "plugin.h"
32 #include "plugin_factory.h"
33 #include "sys_event.h"
34 
35 namespace OHOS {
36 namespace HiviewDFX {
37 using std::string;
38 REGISTER(FaultDetectorManager);
39 REGISTER_PUBLISHER(FaultDetectorManager);
40 DEFINE_LOG_TAG("FaultDetectorManager");
41 
OnEvent(std::shared_ptr<Event> & event)42 bool FaultDetectorManager::OnEvent(std::shared_ptr<Event> &event)
43 {
44     return true;
45 }
46 
ReadyToLoad()47 bool FaultDetectorManager::ReadyToLoad()
48 {
49     if (!FaultDetectorUtil::IsMemLeakEnable()) {
50         HIVIEW_LOGW("fault detector not enable, Load is not ready");
51         return false;
52     }
53     HIVIEW_LOGI("Load is ready");
54     isLoopContinue_ = true;
55     return true;
56 }
57 
PrepareFaultDetectorEnv()58 void FaultDetectorManager::PrepareFaultDetectorEnv()
59 {
60     if (FaultDetectorUtil::IsMemLeakEnable()) {
61         HIVIEW_LOGI("Prepare Enviroment for memory leak");
62         NativeLeakDetector::GetInstance().PrepareNativeLeakEnv();
63         detectorList_.push_back(NATIVE_LEAK_DETECTOR);
64     }
65 }
66 
HandleNativeLeakDetection()67 void FaultDetectorManager::HandleNativeLeakDetection()
68 {
69     ffrt::submit([] {
70         ErrCode ret = NativeLeakDetector::GetInstance().MainProcess();
71         if (ret) {
72             HIVIEW_LOGE("NativeLeakDetector MainProcess failed, err is %{public}d", ret);
73         }
74     });
75 }
76 
MonitorProcess()77 void FaultDetectorManager::MonitorProcess()
78 {
79     for (auto item : detectorList_) {
80         switch (item) {
81             case NATIVE_LEAK_DETECTOR:
82                 HandleNativeLeakDetection();
83                 break;
84             default:
85                 break;
86         }
87     }
88 }
89 
90 
OnLoad()91 void FaultDetectorManager::OnLoad()
92 {
93     SetName("FaultDetectorManager");
94     SetVersion("FaultDetectorManager1.0");
95     HIVIEW_LOGI("FaultDetectorManager OnLoad");
96 
97     PrepareFaultDetectorEnv();
98 
99     workLoop_ = GetHiviewContext()->GetSharedWorkLoop();
100     if (!workLoop_) {
101         HIVIEW_LOGI("workLoop_ is nullptr. stop load.");
102         return;
103     }
104 
105     auto detectorProcessLoop = [this]() {
106         HIVIEW_LOGI("start detectorProcessLoop task");
107         while (isLoopContinue_) {
108             FaultDetectorManager::MonitorProcess();
109             ffrt::this_task::sleep_for(std::chrono::microseconds(TASK_TIMER_INTERVAL * 1000 * 1000)); // 5s
110         }
111     };
112     processTaskHandle_ = ffrt::submit_h(detectorProcessLoop);
113 }
114 
OnUnload()115 void FaultDetectorManager::OnUnload()
116 {
117     isLoopContinue_ = false;
118     ffrt::wait({processTaskHandle_});
119     HIVIEW_LOGI("FaultDetectorManager OnUnload");
120 }
121 
OnEventListeningCallback(const Event & msg)122 void FaultDetectorManager::OnEventListeningCallback(const Event &msg)
123 {
124     Event& eventRef = const_cast<Event&>(msg);
125     SysEvent& sysEvent = static_cast<SysEvent&>(eventRef);
126 
127     string eventMsg = sysEvent.GetEventValue("MSG");
128     if (eventMsg.empty()) {
129         eventMsg = sysEvent.eventName_;
130     }
131     string processName = sysEvent.GetEventValue("PROCESS_NAME");
132     HIVIEW_LOGD("FaultDetector receive watchpoint report, jsonExtraInfo is %{public}s", sysEvent.AsJsonStr().c_str());
133 
134     if (sysEvent.eventName_ == eventNameLowmem) {
135         NativeLeakDetector::GetInstance().ProcessUserEvent(processName, eventMsg, sysEvent.GetEventIntValue("PID"));
136     }
137 }
138 
AddAppEventHandler(std::shared_ptr<AppEventHandler> handler)139 void FaultDetectorManager::AddAppEventHandler(std::shared_ptr<AppEventHandler> handler)
140 {
141     HIVIEW_LOGI("FaultDetectorManager::AddAppEventHandler");
142     FaultStateBase *baseState = NativeLeakStateContext::GetInstance().GetStateObj(PROC_REPORT_STATE);
143     NativeLeakReportState *reportObj = static_cast<NativeLeakReportState *>(baseState);
144     reportObj->setEventHandler(handler);
145 }
146 
147 #if defined(__HIVIEW_OHOS__)
OnFileDescriptorEvent(int fd,int type)148 bool FaultDetectorManager::OnFileDescriptorEvent(int fd, int type)
149 {
150     return true;
151 }
152 
GetPollFd()153 int32_t FaultDetectorManager::GetPollFd()
154 {
155     return 0;
156 }
157 
GetPollType()158 int32_t FaultDetectorManager::GetPollType()
159 {
160     return EPOLLIN;
161 }
162 #endif
163 } // namespace HiviewDFX
164 } // namespace OHOS
165