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