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_client.h" 33 34 namespace OHOS { 35 namespace HiviewDFX { 36 constexpr const char* const KEY_SAMPLE_INTERVAL = "sample_interval"; 37 constexpr const char* const KEY_SAMPLE_COUNT = "sample_count"; 38 constexpr const char* const KEY_SAMPLE_REPORT_TIMES = "report_times_per_app"; 39 constexpr const char* const KEY_LOG_TYPE = "log_type"; 40 constexpr const char* const KEY_SET_TIMES_FLAG = "set_report_times_flag"; 41 constexpr const char* const KEY_IGNORE_STARTUP_TIME = "ignore_startup_time"; 42 const int SAMPLE_DEFULE_INTERVAL = 150; 43 const int SAMPLE_DEFULE_COUNT = 10; 44 const int SAMPLE_DEFULE_REPORT_TIMES = 1; 45 const int SET_TIMES_FLAG = 1; 46 const int DEFAULT_IGNORE_STARTUP_TIME = 10; // 10s 47 48 using TimePoint = AppExecFwk::InnerEvent::TimePoint; 49 struct TimeContent { 50 int64_t curBegin; 51 int64_t curEnd; 52 }; 53 54 struct StackContent { 55 bool isStartSampleEnabled {true}; 56 int detectorCount {0}; 57 int collectCount {0}; 58 int reportTimes {SAMPLE_DEFULE_REPORT_TIMES}; 59 int scrollTimes {SAMPLE_DEFULE_REPORT_TIMES}; 60 int64_t reportBegin {0}; 61 int64_t reportEnd {0}; 62 TimePoint lastEndTime; 63 }; 64 65 struct TraceContent { 66 int traceState {0}; 67 int traceCount {0}; 68 int dumpCount {0}; 69 int64_t reportBegin {0}; 70 int64_t reportEnd {0}; 71 TimePoint lastEndTime; 72 }; 73 74 typedef void (*WatchdogInnerBeginFunc)(const char* eventName); 75 typedef void (*WatchdogInnerEndFunc)(const char* eventName); 76 77 typedef int (*ThreadSamplerInitFunc)(int); 78 typedef int32_t (*ThreadSamplerSampleFunc)(); 79 typedef int (*ThreadSamplerCollectFunc)(char*, char*, size_t, size_t, int); 80 typedef int (*ThreadSamplerDeinitFunc)(); 81 typedef void (*SigActionType)(int, siginfo_t*, void*); 82 83 class WatchdogInner : public Singleton<WatchdogInner> { 84 DECLARE_SINGLETON(WatchdogInner); 85 public: 86 static const int XCOLLIE_CALLBACK_HISTORY_MAX = 5; 87 static const int XCOLLIE_CALLBACK_TIMEWIN_MAX = 60; 88 std::map<int64_t, int> taskIdCnt; 89 int AddThread(const std::string &name, std::shared_ptr<AppExecFwk::EventHandler> handler, uint64_t interval); 90 int AddThread(const std::string &name, std::shared_ptr<AppExecFwk::EventHandler> handler, 91 TimeOutCallback timeOutCallback, uint64_t interval); 92 void RunOneShotTask(const std::string& name, Task&& task, uint64_t delay); 93 void RunPeriodicalTask(const std::string& name, Task&& task, uint64_t interval, uint64_t delay); 94 int64_t RunXCollieTask(const std::string& name, uint64_t timeout, XCollieCallback func, void *arg, 95 unsigned int flag); 96 void RemoveXCollieTask(int64_t id); 97 int64_t SetTimerCountTask(const std::string &name, uint64_t timeLimit, int countLimit); 98 void TriggerTimerCountTask(const std::string &name, bool bTrigger, const std::string &message); 99 void StopWatchdog(); 100 bool IsCallbackLimit(unsigned int flag); 101 void IpcCheck(); 102 void InitFfrtWatchdog(); 103 static bool WriteStringToFile(uint32_t pid, const char *str); 104 static void FfrtCallback(uint64_t taskId, const char *taskInfo, uint32_t delayedTaskCount); 105 static void SendFfrtEvent(const std::string &msg, const std::string &eventName, const char *taskInfo); 106 static void LeftTimeExitProcess(const std::string &description); 107 static void KillPeerBinderProcess(const std::string &description); 108 bool StartScrollProfile(const TimePoint& endTime, int64_t durationTime, int sampleInterval); 109 void StartProfileMainThread(const TimePoint& endTime, int64_t durationTime, int sampleInterval); 110 bool CollectStack(std::string& stack, std::string& heaviestStack); 111 bool Deinit(); 112 void SetBundleInfo(const std::string& bundleName, const std::string& bundleVersion); 113 void SetForeground(const bool& isForeground); 114 void RemoveInnerTask(const std::string& name); 115 void InitMainLooperWatcher(WatchdogInnerBeginFunc* beginFunc, WatchdogInnerEndFunc* endFunc); 116 void SetAppDebug(bool isAppDebug); 117 bool GetAppDebug(); 118 int SetEventConfig(std::map<std::string, std::string> paramsMap); 119 bool SampleStackDetect(const TimePoint& endTime, int& reportTimes, int updateTimes, 120 int ignoreTime = DEFAULT_IGNORE_STARTUP_TIME); 121 void CollectTraceDetect(const TimePoint& endTime, int64_t durationTime); 122 void SetSpecifiedProcessName(const std::string& name); 123 std::string GetSpecifiedProcessName(); 124 void SetScrollState(bool isScroll); 125 126 public: 127 std::string currentScene_; 128 TimePoint bussinessBeginTime_; 129 TimeContent timeContent_ {0}; 130 StackContent stackContent_; 131 TraceContent traceContent_; 132 std::map<std::string, int> jankParamsMap = { 133 {KEY_SAMPLE_INTERVAL, SAMPLE_DEFULE_INTERVAL}, {KEY_IGNORE_STARTUP_TIME, DEFAULT_IGNORE_STARTUP_TIME}, 134 {KEY_SAMPLE_COUNT, SAMPLE_DEFULE_COUNT}, {KEY_SAMPLE_REPORT_TIMES, SAMPLE_DEFULE_REPORT_TIMES}, 135 {KEY_LOG_TYPE, 0}, {KEY_SET_TIMES_FLAG, SET_TIMES_FLAG} 136 }; 137 bool isScroll_ {false}; 138 139 private: 140 bool Start(); 141 bool Stop(); 142 bool SendMsgToHungtask(const std::string& msg); 143 bool KickWatchdog(); 144 bool IsTaskExistLocked(const std::string& name); 145 bool IsExceedMaxTaskLocked(); 146 int64_t InsertWatchdogTaskLocked(const std::string& name, WatchdogTask&& task); 147 bool IsInSleep(const WatchdogTask& queuedTaskCheck); 148 void CheckKickWatchdog(uint64_t now, const WatchdogTask& queuedTask); 149 bool CheckCurrentTaskLocked(const WatchdogTask& queuedTaskCheck); 150 uint64_t FetchNextTask(uint64_t now, WatchdogTask& task); 151 void ReInsertTaskIfNeed(WatchdogTask& task); 152 void CreateWatchdogThreadIfNeed(); 153 bool ReportMainThreadEvent(int64_t tid, bool isScroll = false); 154 bool CheckEventTimer(int64_t currentTime, int64_t reportBegin, int64_t reportEnd, int interval); 155 void DumpTraceProfile(int32_t interval); 156 int32_t StartTraceProfile(); 157 void UpdateTime(int64_t& reportBegin, int64_t& reportEnd, TimePoint& lastEndTime, const TimePoint& endTime); 158 bool CheckThreadSampler(); 159 bool InitThreadSamplerFuncs(); 160 void ResetThreadSamplerFuncs(); 161 static void GetFfrtTaskTid(int32_t& tid, const std::string& msg); 162 void UpdateJankParam(int sampleInterval, int startUpTime, int sampleCount, int logType, int reportTimes); 163 int ConvertStrToNum(std::map<std::string, std::string> paramsMap, const std::string& key); 164 bool CheckSampleParam(std::map<std::string, std::string> paramsMap); 165 166 static void ThreadSamplerSigHandler(int sig, siginfo_t* si, void* context); 167 bool InstallThreadSamplerSignal(); 168 void UninstallThreadSamplerSignal(); 169 170 static SigActionType threadSamplerSigHandler_; 171 172 static const unsigned int MAX_WATCH_NUM = 128; // 128: max handler thread 173 std::priority_queue<WatchdogTask> checkerQueue_; // protected by lock_ 174 std::unique_ptr<std::thread> threadLoop_; 175 std::mutex lock_; 176 static std::mutex lockFfrt_; 177 std::condition_variable condition_; 178 std::atomic_bool isNeedStop_ = false; 179 std::once_flag flag_; 180 std::set<std::string> taskNameSet_; 181 std::set<int64_t> buissnessThreadInfo_; 182 std::shared_ptr<AppExecFwk::EventRunner> mainRunner_; 183 std::shared_ptr<AppExecFwk::EventHandler> binderCheckHander_; 184 int cntCallback_; 185 time_t timeCallback_; 186 bool isHmos = false; 187 void* threadSamplerFuncHandler_ {nullptr}; 188 ThreadSamplerInitFunc threadSamplerInitFunc_ {nullptr}; 189 ThreadSamplerSampleFunc threadSamplerSampleFunc_ {nullptr}; 190 ThreadSamplerCollectFunc threadSamplerCollectFunc_ {nullptr}; 191 ThreadSamplerDeinitFunc threadSamplerDeinitFunc_ {nullptr}; 192 uint64_t watchdogStartTime_ {0}; 193 static std::mutex threadSamplerSignalMutex_; 194 195 bool isMainThreadStackEnabled_ {false}; 196 bool isMainThreadTraceEnabled_ {false}; 197 std::string bundleName_; 198 std::string bundleVersion_; 199 bool isForeground_ {false}; 200 bool isAppDebug_ {false}; 201 std::shared_ptr<UCollectClient::TraceCollector> traceCollector_; 202 UCollectClient::AppCaller appCaller_ { 203 .actionId = 0, 204 .foreground = 0, 205 .uid = 0, 206 .pid = 0, 207 .happenTime = 0, 208 .beginTime = 0, 209 .endTime = 0, 210 .isBusinessJank = false, 211 }; 212 std::string specifiedProcessName_; 213 }; 214 } // end of namespace HiviewDFX 215 } // end of namespace OHOS 216 #endif 217