1 /* 2 * Copyright (c) 2021-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 16 #ifndef RELIABILITY_WATCHDOG_INNER_H 17 #define RELIABILITY_WATCHDOG_INNER_H 18 19 #include <atomic> 20 #include <condition_variable> 21 #include <csignal> 22 #include <memory> 23 #include <mutex> 24 #include <queue> 25 #include <set> 26 #include <string> 27 #include <thread> 28 29 #include "watchdog_task.h" 30 #include "c/ffrt_dump.h" 31 #include "singleton.h" 32 #include "client/trace_collector.h" 33 34 namespace OHOS { 35 namespace HiviewDFX { 36 using TimePoint = AppExecFwk::InnerEvent::TimePoint; 37 struct TimeContent { 38 int64_t reportBegin; 39 int64_t reportEnd; 40 int64_t curBegin; 41 int64_t curEnd; 42 }; 43 44 struct StackContent { 45 int stackState; 46 int detectorCount; 47 int collectCount; 48 }; 49 50 struct TraceContent { 51 int traceState; 52 int traceCount; 53 int dumpCount; 54 }; 55 56 typedef void (*WatchdogInnerBeginFunc)(const char* eventName); 57 typedef void (*WatchdogInnerEndFunc)(const char* eventName); 58 59 typedef int (*ThreadSamplerInitFunc)(int); 60 typedef int32_t (*ThreadSamplerSampleFunc)(); 61 typedef int (*ThreadSamplerCollectFunc)(char*, size_t, int); 62 typedef int (*ThreadSamplerDeinitFunc)(); 63 typedef void (*SigActionType)(int, siginfo_t*, void*); 64 65 class WatchdogInner : public Singleton<WatchdogInner> { 66 DECLARE_SINGLETON(WatchdogInner); 67 public: 68 static const int XCOLLIE_CALLBACK_HISTORY_MAX = 5; 69 static const int XCOLLIE_CALLBACK_TIMEWIN_MAX = 60; 70 std::map<int64_t, int> taskIdCnt; 71 int AddThread(const std::string &name, std::shared_ptr<AppExecFwk::EventHandler> handler, uint64_t interval); 72 int AddThread(const std::string &name, std::shared_ptr<AppExecFwk::EventHandler> handler, 73 TimeOutCallback timeOutCallback, uint64_t interval); 74 void RunOneShotTask(const std::string& name, Task&& task, uint64_t delay); 75 void RunPeriodicalTask(const std::string& name, Task&& task, uint64_t interval, uint64_t delay); 76 int64_t RunXCollieTask(const std::string& name, uint64_t timeout, XCollieCallback func, void *arg, 77 unsigned int flag); 78 void RemoveXCollieTask(int64_t id); 79 int64_t SetTimerCountTask(const std::string &name, uint64_t timeLimit, int countLimit); 80 void TriggerTimerCountTask(const std::string &name, bool bTrigger, const std::string &message); 81 void StopWatchdog(); 82 bool IsCallbackLimit(unsigned int flag); 83 void IpcCheck(); 84 void InitFfrtWatchdog(); 85 static void WriteStringToFile(int32_t pid, const char *str); 86 static void FfrtCallback(uint64_t taskId, const char *taskInfo, uint32_t delayedTaskCount); 87 static void SendFfrtEvent(const std::string &msg, const std::string &eventName, const char *taskInfo, 88 const bool isDumpStack = true); 89 static void LeftTimeExitProcess(const std::string &description); 90 static void KillPeerBinderProcess(const std::string &description); 91 int32_t StartProfileMainThread(int32_t interval); 92 bool CollectStack(std::string& stack); 93 void CollectTrace(); 94 bool Deinit(); 95 void SetBundleInfo(const std::string& bundleName, const std::string& bundleVersion); 96 void SetForeground(const bool& isForeground); 97 void ChangeState(int& state, int targetState); 98 void DayChecker(int& state, TimePoint currenTime, TimePoint lastEndTime, int64_t checkTimer); 99 void RemoveInnerTask(const std::string& name); 100 void InitMainLooperWatcher(WatchdogInnerBeginFunc* beginFunc, WatchdogInnerEndFunc* endFunc); 101 void SetAppDebug(bool isAppDebug); 102 bool GetAppDebug(); 103 std::string currentScene_; 104 TimePoint lastTraceTime_; 105 TimePoint lastStackTime_; 106 TimePoint bussinessBeginTime_; 107 TimeContent timeContent_ {0}; 108 StackContent stackContent_ {0}; 109 TraceContent traceContent_ {0}; 110 111 private: 112 bool Start(); 113 bool Stop(); 114 bool SendMsgToHungtask(const std::string& msg); 115 bool KickWatchdog(); 116 bool IsTaskExistLocked(const std::string& name); 117 bool IsExceedMaxTaskLocked(); 118 int64_t InsertWatchdogTaskLocked(const std::string& name, WatchdogTask&& task); 119 uint64_t FetchNextTask(uint64_t now, WatchdogTask& task); 120 void ReInsertTaskIfNeed(WatchdogTask& task); 121 void CreateWatchdogThreadIfNeed(); 122 bool ReportMainThreadEvent(); 123 bool CheckEventTimer(const int64_t& currentTime); 124 void StartTraceProfile(int32_t interval); 125 126 void ThreadSampleTask(); 127 bool InitThreadSamplerFuncs(); 128 void ResetThreadSamplerFuncs(); 129 static void GetFfrtTaskTid(int32_t& tid, const std::string& msg); 130 131 static void ThreadSamplerSigHandler(int sig, siginfo_t* si, void* context); 132 bool InstallThreadSamplerSignal(); 133 void UninstallThreadSamplerSignal(); 134 135 static SigActionType threadSamplerSigHandler_; 136 137 static const unsigned int MAX_WATCH_NUM = 128; // 128: max handler thread 138 std::priority_queue<WatchdogTask> checkerQueue_; // protected by lock_ 139 std::unique_ptr<std::thread> threadLoop_; 140 std::mutex lock_; 141 static std::mutex lockFfrt_; 142 std::condition_variable condition_; 143 std::atomic_bool isNeedStop_ = false; 144 std::once_flag flag_; 145 std::set<std::string> taskNameSet_; 146 std::set<int64_t> buissnessThreadInfo_; 147 std::shared_ptr<AppExecFwk::EventRunner> mainRunner_; 148 std::shared_ptr<AppExecFwk::EventHandler> binderCheckHander_; 149 int cntCallback_; 150 time_t timeCallback_; 151 bool isHmos = false; 152 void* threadSamplerFuncHandler_ {nullptr}; 153 ThreadSamplerInitFunc threadSamplerInitFunc_ {nullptr}; 154 ThreadSamplerSampleFunc threadSamplerSampleFunc_ {nullptr}; 155 ThreadSamplerCollectFunc threadSamplerCollectFunc_ {nullptr}; 156 ThreadSamplerDeinitFunc threadSamplerDeinitFunc_ {nullptr}; 157 uint64_t watchdogStartTime_ {0}; 158 static std::mutex threadSamplerSignalMutex_; 159 160 bool isMainThreadProfileTaskEnabled_ {false}; 161 bool isMainThreadTraceEnabled_ {false}; 162 std::string bundleName_; 163 std::string bundleVersion_; 164 bool isForeground_ {false}; 165 bool isAppDebug_ {false}; 166 int sampleTaskState_; 167 std::shared_ptr<UCollectClient::TraceCollector> traceCollector_; 168 UCollectClient::AppCaller appCaller_ { 169 .actionId = 0, 170 .foreground = 0, 171 .uid = 0, 172 .pid = 0, 173 .happenTime = 0, 174 .beginTime = 0, 175 .endTime = 0, 176 .isBusinessJank = false, 177 }; 178 }; 179 } // end of namespace HiviewDFX 180 } // end of namespace OHOS 181 #endif 182