• 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 #include "fault_logger_pipe.h"
17 
18 #include <algorithm>
19 #include <cerrno>
20 #include <ctime>
21 #include <string>
22 
23 #include <fcntl.h>
24 #include <securec.h>
25 #include <unistd.h>
26 
27 #include <sys/socket.h>
28 #include <sys/stat.h>
29 #include <sys/syscall.h>
30 #include <sys/types.h>
31 #include <sys/un.h>
32 
33 #include "dfx_define.h"
34 #include "dfx_log.h"
35 
36 namespace OHOS {
37 namespace HiviewDFX {
38 
FaultLoggerPipe()39 FaultLoggerPipe::FaultLoggerPipe()
40 {
41     int fds[PIPE_NUM_SZ] = {-1, -1};
42     if (pipe2(fds, O_NONBLOCK) != 0) {
43         DFXLOGE("%{public}s :: Failed to create pipe, errno: %{public}d.", __func__, errno);
44         return;
45     }
46     DFXLOGD("%{public}s :: create pipe.", __func__);
47     readFd_ = fds[PIPE_READ];
48     writeFd_ = fds[PIPE_WRITE];
49     if (fcntl(readFd_, F_SETPIPE_SZ, MAX_PIPE_SIZE) < 0 || fcntl(writeFd_, F_SETPIPE_SZ, MAX_PIPE_SIZE) < 0) {
50         DFXLOGE("%{public}s :: Failed to set pipe size, errno: %{public}d.", __func__, errno);
51     }
52 }
53 
~FaultLoggerPipe()54 FaultLoggerPipe::~FaultLoggerPipe()
55 {
56     DFXLOGD("%{public}s :: close pipe.", __func__);
57     Close(readFd_);
58     Close(writeFd_);
59 }
60 
FaultLoggerPipe(FaultLoggerPipe && rhs)61 FaultLoggerPipe::FaultLoggerPipe(FaultLoggerPipe&& rhs) noexcept: write_(rhs.write_),
62     readFd_(rhs.readFd_), writeFd_(rhs.writeFd_)
63 {
64     rhs.readFd_ = -1;
65     rhs.writeFd_ = -1;
66 }
67 
operator =(FaultLoggerPipe && rhs)68 FaultLoggerPipe& FaultLoggerPipe::operator=(FaultLoggerPipe&& rhs) noexcept
69 {
70     if (this != &rhs) {
71         Close(readFd_);
72         Close(writeFd_);
73         readFd_ = rhs.readFd_;
74         writeFd_ = rhs.writeFd_;
75         write_ = rhs.write_;
76         rhs.readFd_ = -1;
77         rhs.writeFd_ = -1;
78     }
79     return *this;
80 }
81 
GetReadFd() const82 int FaultLoggerPipe::GetReadFd() const
83 {
84     DFXLOGD("%{public}s :: pipe read fd: %{public}d", __func__, readFd_);
85     return readFd_;
86 }
87 
GetWriteFd()88 int FaultLoggerPipe::GetWriteFd()
89 {
90     DFXLOGD("%{public}s :: pipe write fd: %{public}d", __func__, writeFd_);
91     if (!write_) {
92         write_ = true;
93         return writeFd_;
94     }
95     return -1;
96 }
97 
Close(int & fd)98 void FaultLoggerPipe::Close(int& fd)
99 {
100     if (fd > 0) {
101         syscall(SYS_close, fd);
102         fd = -1;
103     }
104 }
105 
106 std::list<FaultLoggerPipePair> FaultLoggerPipePair::sdkDumpPipes_{};
107 
FaultLoggerPipePair(int32_t pid,uint64_t requestTime)108 FaultLoggerPipePair::FaultLoggerPipePair(int32_t pid, uint64_t requestTime) : pid_(pid), requestTime_(requestTime) {}
109 
IsValid(uint64_t checkTime) const110 bool FaultLoggerPipePair::IsValid(uint64_t checkTime) const
111 {
112     constexpr int pipeTimeOut = 10000; // 10s
113     return checkTime <= requestTime_ + pipeTimeOut;
114 }
115 
GetPipeFd(PipeFdUsage usage,FaultLoggerPipeType pipeType)116 int32_t FaultLoggerPipePair::GetPipeFd(PipeFdUsage usage, FaultLoggerPipeType pipeType)
117 {
118     FaultLoggerPipe& targetPipe = (usage == PipeFdUsage::BUFFER_FD) ? faultLoggerPipeBuf_ : faultLoggerPipeRes_;
119     if (pipeType == FaultLoggerPipeType::PIPE_FD_READ) {
120         return targetPipe.GetReadFd();
121     }
122     if (pipeType == FaultLoggerPipeType::PIPE_FD_WRITE) {
123         return targetPipe.GetWriteFd();
124     }
125     return -1;
126 }
127 
CreateSdkDumpPipePair(int pid,uint64_t requestTime)128 FaultLoggerPipePair& FaultLoggerPipePair::CreateSdkDumpPipePair(int pid, uint64_t requestTime)
129 {
130     auto pipePair = GetSdkDumpPipePair(pid);
131     if (pipePair != nullptr) {
132         return *pipePair;
133     }
134     return sdkDumpPipes_.emplace_back(pid, requestTime);
135 }
136 
CheckSdkDumpRecord(int pid,uint64_t checkTime)137 bool FaultLoggerPipePair::CheckSdkDumpRecord(int pid, uint64_t checkTime)
138 {
139     auto iter = std::find_if(sdkDumpPipes_.begin(), sdkDumpPipes_.end(),
140         [pid](const FaultLoggerPipePair& faultLoggerPipePair) {
141             return faultLoggerPipePair.pid_ == pid;
142         });
143     if (iter != sdkDumpPipes_.end()) {
144         if (iter->IsValid(checkTime)) {
145             return true;
146         }
147         sdkDumpPipes_.erase(iter);
148     }
149     return false;
150 }
151 
GetSdkDumpPipePair(int pid)152 FaultLoggerPipePair* FaultLoggerPipePair::GetSdkDumpPipePair(int pid)
153 {
154     auto iter = std::find_if(sdkDumpPipes_.begin(), sdkDumpPipes_.end(),
155         [pid](const FaultLoggerPipePair& faultLoggerPipePair) {
156             return faultLoggerPipePair.pid_ == pid;
157         });
158     return iter == sdkDumpPipes_.end() ? nullptr : &(*iter);
159 }
160 
DelSdkDumpPipePair(int pid)161 void FaultLoggerPipePair::DelSdkDumpPipePair(int pid)
162 {
163     sdkDumpPipes_.remove_if([pid](const FaultLoggerPipePair& faultLoggerPipePair) {
164         return faultLoggerPipePair.pid_ == pid;
165     });
166 }
167 } // namespace HiviewDfx
168 } // namespace OHOS
169