• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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