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