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