• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <poll.h>
25 #include <string>
26 #include <unistd.h>
27 #include <vector>
28 
29 #include "dfx_dump_catcher_errno.h"
30 
31 namespace OHOS {
32 namespace HiviewDFX {
33 class DfxDumpCatcher {
34 public:
35     /**
36      * @brief Dump native stack by specify pid and tid
37      *
38      * @param pid  process id
39      * @param tid  thread id
40      * @param msg  message of native stack
41      * @param maxFrameNums the maximum number of frames to dump, if pid is not equal to caller pid then it is ignored
42      * @param isJson whether message of native stack is json formatted
43      * @return if succeed return true, otherwise return false
44     */
45     bool DumpCatch(int pid, int tid, std::string& msg, size_t maxFrameNums = DEFAULT_MAX_FRAME_NUM,
46                    bool isJson = false);
47 
48     /**
49      * @brief Dump native stack by specify pid and tid to file
50      *
51      * @param pid  process id
52      * @param tid  thread id
53      * @param fd  file descriptor
54      * @param maxFrameNums the maximum number of frames to dump,
55      *  if pid is not equal to caller pid then it does not support setting
56      * @return if succeed return true, otherwise return false
57     */
58     bool DumpCatchFd(int pid, int tid, std::string& msg, int fd, size_t maxFrameNums = DEFAULT_MAX_FRAME_NUM);
59 
60     /**
61      * @brief Dump native stack by multi-pid
62      *
63      * @param pid  process id
64      * @param tid  thread id
65      * @param msg  message of native stack
66      * @return if succeed return true, otherwise return false
67     */
68     bool DumpCatchMultiPid(const std::vector<int> pidV, std::string& msg);
69     /**
70      * @brief Dump stack of process
71      *
72      * @param pid  process id
73      * @param msg  message of stack
74      * @param maxFrameNums the maximum number of frames to dump,
75      *  if pid is not equal to caller pid then it does not support setting
76      * @param isJson whether message of stack is json formatted
77      * @return -1: dump catch failed 0:msg is normal stack 1:msg is kernel stack(not json format)
78     */
79     int DumpCatchProcess(int pid, std::string& msg, size_t maxFrameNums = DEFAULT_MAX_FRAME_NUM,
80         bool isJson = false);
81     /**
82      * @brief Dump stack of process with timeout
83      *
84      * @param pid  process id
85      * @param msg  message of stack
86      * @param timeout  Set the dump timeout time to be at least 1000ms
87      * @param isJson  whether message of stack is json formatted
88      * @return ret and reason.
89      *  ret: -1: dump catch failed 0:msg is normal stack 1:msg is kernel stack(not json format)
90      *  reason: if ret is 1, it contains normal stack fail reason.
91      *          if ret is -1, it contains normal stack fail reason and kernel stack fail reason.
92     */
93     std::pair<int, std::string> DumpCatchWithTimeout(int pid, std::string& msg, int timeout = 3000,
94         int tid = 0, bool isJson = false);
95 private:
96     static constexpr size_t DEFAULT_MAX_FRAME_NUM = 256;
97     bool DoDumpCurrTid(const size_t skipFrameNum, std::string& msg, size_t maxFrameNums);
98     bool DoDumpLocalTid(const int tid, std::string& msg, size_t maxFrameNums);
99     bool DoDumpLocalPid(int pid, std::string& msg, size_t maxFrameNums);
100     bool DoDumpLocalLocked(int pid, int tid, std::string& msg, size_t maxFrameNums);
101     int32_t DoDumpRemoteLocked(int pid, int tid, std::string& msg, bool isJson = false,
102         int timeout = DUMPCATCHER_REMOTE_TIMEOUT);
103     int32_t DoDumpCatchRemote(int pid, int tid, std::string& msg, bool isJson = false,
104         int timeout = DUMPCATCHER_REMOTE_TIMEOUT);
105     int DoDumpRemotePid(int pid, std::string& msg, int (&pipeReadFd)[2],
106         bool isJson = false, int32_t timeout = DUMPCATCHER_REMOTE_TIMEOUT);
107     bool HandlePollError(const uint64_t endTime, int& remainTime,
108         bool& collectAllTidStack, std::string& resMsg, int& ret);
109     bool HandlePollTimeout(const int timeout, int& remainTime,
110         bool& collectAllTidStack, std::string& resMsg, int& ret);
111     bool HandlePollEvents(std::pair<int, std::string>& bufState, std::pair<int, std::string>& resState,
112         const struct pollfd (&readFds)[2], bool& bPipeConnect, bool& res);
113     std::pair<bool, int> DumpRemotePoll(const int timeout, std::pair<int, std::string>& bufState,
114         std::pair<int, std::string>& resState);
115     int DoDumpRemotePoll(int timeout, std::string& msg, const int (&pipeReadFd)[2], bool isJson = false);
116     bool DoReadBuf(int fd, std::string& msg);
117     bool DoReadRes(int fd, bool& ret, std::string& msg);
118     static void CollectKernelStack(pid_t pid, int waitMilliSeconds = 0);
119     void AsyncGetAllTidKernelStack(pid_t pid, int waitMilliSeconds = 0);
120     void DealWithPollRet(int pollRet, int pid, int32_t& ret, std::string& msg);
121     void DealWithSdkDumpRet(int sdkdumpRet, int pid, int32_t& ret, std::string& msg);
122 
123 private:
124     static const int DUMPCATCHER_REMOTE_P90_TIMEOUT = 1000;
125     static const int DUMPCATCHER_REMOTE_TIMEOUT = 10000;
126     std::mutex mutex_;
127     int32_t pid_ = -1;
128     std::string halfProcStatus_ = "";
129     std::string halfProcWchan_ = "";
130 };
131 } // namespace HiviewDFX
132 } // namespace OHOS
133 
134 #endif
135