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