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