1 /*
2  * Copyright (c) 2021-2023 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 DFX_DUMPCATCH_H
17 #define DFX_DUMPCATCH_H
18 
19 #include <cinttypes>
20 #include <condition_variable>
21 #include <cstring>
22 #include <memory>
23 #include <mutex>
24 #include <string>
25 #include <unistd.h>
26 #include <vector>
27 
28 namespace OHOS {
29 namespace HiviewDFX {
30 static const size_t DEFAULT_MAX_FRAME_NUM = 256;
31 class DfxDumpCatcher {
32 public:
DfxDumpCatcher()33     DfxDumpCatcher() {}
~DfxDumpCatcher()34     ~DfxDumpCatcher() {}
35 
36     /**
37      * @brief Dump native stack by specify pid and tid
38      *
39      * @param pid  process id
40      * @param tid  thread id
41      * @param msg  message of native stack
42      * @param maxFrameNums the maximum number of frames to dump, if pid is not equal to caller pid then it is ignored
43      * @param isJson whether message of native stack is json formatted
44      * @return if succeed return true, otherwise return false
45     */
46     bool DumpCatch(int pid, int tid, std::string& msg, size_t maxFrameNums = DEFAULT_MAX_FRAME_NUM,
47                    bool isJson = false);
48 
49     /**
50      * @brief Dump native stack by specify pid and tid to file
51      *
52      * @param pid  process id
53      * @param tid  thread id
54      * @param fd  file descriptor
55      * @param maxFrameNums the maximum number of frames to dump,
56      *  if pid is not equal to caller pid then it does not support setting
57      * @return if succeed return true, otherwise return false
58     */
59     bool DumpCatchFd(int pid, int tid, std::string& msg, int fd, size_t maxFrameNums = DEFAULT_MAX_FRAME_NUM);
60 
61     /**
62      * @brief Dump native stack by multi-pid
63      *
64      * @param pid  process id
65      * @param tid  thread id
66      * @param msg  message of native stack
67      * @return if succeed return true, otherwise return false
68     */
69     bool DumpCatchMultiPid(const std::vector<int> pidV, std::string& msg);
70     /**
71      * @brief Dump stack of process
72      *
73      * @param pid  process id
74      * @param msg  message of stack
75      * @param maxFrameNums the maximum number of frames to dump,
76      *  if pid is not equal to caller pid then it does not support setting
77      * @param isJson whether message of stack is json formatted
78      * @return -1: dump catch failed 0:msg is normal stack 1:msg is kernel stack(not json format)
79     */
80     int DumpCatchProcess(int pid, std::string& msg, size_t maxFrameNums = DEFAULT_MAX_FRAME_NUM,
81         bool isJson = false);
82 private:
83     bool DoDumpCurrTid(const size_t skipFrameNum, std::string& msg, size_t maxFrameNums);
84     bool DoDumpLocalTid(const int tid, std::string& msg, size_t maxFrameNums);
85     bool DoDumpLocalPid(int pid, std::string& msg, size_t maxFrameNums);
86     bool DoDumpLocalLocked(int pid, int tid, std::string& msg, size_t maxFrameNums);
87     bool DoDumpRemoteLocked(int pid, int tid, std::string& msg, bool isJson = false,
88         int timeout = DUMPCATCHER_REMOTE_TIMEOUT);
89     bool DoDumpCatchRemote(int pid, int tid, std::string& msg, bool isJson = false,
90         int timeout = DUMPCATCHER_REMOTE_TIMEOUT);
91     int DoDumpRemotePid(int pid, std::string& msg, bool isJson = false, int32_t timeout = DUMPCATCHER_REMOTE_TIMEOUT);
92     int DoDumpRemotePoll(int bufFd, int resFd, int timeout, std::string& msg, bool isJson = false);
93     bool DoReadBuf(int fd, std::string& msg);
94     bool DoReadRes(int fd, bool &ret, std::string& msg);
95     static void CollectKernelStack(pid_t pid, int waitMilliSeconds = 0);
96     void AsyncGetAllTidKernelStack(pid_t pid, int waitMilliSeconds = 0);
97 
98 private:
99     static const int DUMPCATCHER_REMOTE_P90_TIMEOUT = 1000;
100     static const int DUMPCATCHER_REMOTE_TIMEOUT = 10000;
101     std::mutex mutex_;
102     int32_t pid_ = -1;
103     std::string halfProcStatus_ = "";
104     std::string halfProcWchan_ = "";
105 };
106 } // namespace HiviewDFX
107 } // namespace OHOS
108 
109 #endif
110