• 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 namespace {
39 constexpr size_t MAX_LITE_PERF_PIPE_SIZE = 100;
40 }
41 
FaultLoggerPipe()42 FaultLoggerPipe::FaultLoggerPipe()
43 {
44     int fds[PIPE_NUM_SZ] = {-1, -1};
45     if (pipe2(fds, O_NONBLOCK) != 0) {
46         DFXLOGE("%{public}s :: Failed to create pipe, errno: %{public}d.", __func__, errno);
47         return;
48     }
49     DFXLOGD("%{public}s :: create pipe.", __func__);
50     readFd_ = SmartFd{fds[PIPE_READ]};
51     writeFd_ = SmartFd{fds[PIPE_WRITE]};
52 
53     if (fcntl(readFd_.GetFd(), F_SETPIPE_SZ, MAX_PIPE_SIZE) < 0 ||
54         fcntl(writeFd_.GetFd(), F_SETPIPE_SZ, MAX_PIPE_SIZE) < 0) {
55         DFXLOGE("%{public}s :: Failed to set pipe size, errno: %{public}d.", __func__, errno);
56     }
57 }
58 
GetReadFd() const59 int FaultLoggerPipe::GetReadFd() const
60 {
61     DFXLOGD("%{public}s :: pipe read fd: %{public}d", __func__, readFd_);
62     return readFd_.GetFd();
63 }
64 
GetWriteFd()65 int FaultLoggerPipe::GetWriteFd()
66 {
67     DFXLOGD("%{public}s :: pipe write fd: %{public}d", __func__, writeFd_);
68     if (!write_) {
69         write_ = true;
70         return writeFd_.GetFd();
71     }
72     return -1;
73 }
74 
75 std::list<FaultLoggerPipePair> FaultLoggerPipePair::sdkDumpPipes_{};
76 std::list<LitePerfPipePair> LitePerfPipePair::pipes_{};
77 
FaultLoggerPipePair(int32_t pid,uint64_t requestTime)78 FaultLoggerPipePair::FaultLoggerPipePair(int32_t pid, uint64_t requestTime) : pid_(pid), requestTime_(requestTime) {}
79 
IsValid(uint64_t checkTime) const80 bool FaultLoggerPipePair::IsValid(uint64_t checkTime) const
81 {
82     constexpr int pipeTimeOut = 10000; // 10s
83     return checkTime <= requestTime_ + pipeTimeOut;
84 }
85 
GetPipeFd(PipeFdUsage usage,FaultLoggerPipeType pipeType)86 int32_t FaultLoggerPipePair::GetPipeFd(PipeFdUsage usage, FaultLoggerPipeType pipeType)
87 {
88     FaultLoggerPipe& targetPipe = (usage == PipeFdUsage::BUFFER_FD) ? faultLoggerPipeBuf_ : faultLoggerPipeRes_;
89     if (pipeType == FaultLoggerPipeType::PIPE_FD_READ) {
90         return targetPipe.GetReadFd();
91     }
92     if (pipeType == FaultLoggerPipeType::PIPE_FD_WRITE) {
93         return targetPipe.GetWriteFd();
94     }
95     return -1;
96 }
97 
CreateSdkDumpPipePair(int pid,uint64_t requestTime)98 FaultLoggerPipePair& FaultLoggerPipePair::CreateSdkDumpPipePair(int pid, uint64_t requestTime)
99 {
100     auto pipePair = GetSdkDumpPipePair(pid);
101     if (pipePair != nullptr) {
102         return *pipePair;
103     }
104     return sdkDumpPipes_.emplace_back(pid, requestTime);
105 }
106 
CheckSdkDumpRecord(int pid,uint64_t checkTime)107 bool FaultLoggerPipePair::CheckSdkDumpRecord(int pid, uint64_t checkTime)
108 {
109     auto iter = std::find_if(sdkDumpPipes_.begin(), sdkDumpPipes_.end(),
110         [pid](const FaultLoggerPipePair& faultLoggerPipePair) {
111             return faultLoggerPipePair.pid_ == pid;
112         });
113     if (iter != sdkDumpPipes_.end()) {
114         if (iter->IsValid(checkTime)) {
115             return true;
116         }
117         sdkDumpPipes_.erase(iter);
118     }
119     return false;
120 }
121 
GetSdkDumpPipePair(int pid)122 FaultLoggerPipePair* FaultLoggerPipePair::GetSdkDumpPipePair(int pid)
123 {
124     auto iter = std::find_if(sdkDumpPipes_.begin(), sdkDumpPipes_.end(),
125         [pid](const FaultLoggerPipePair& faultLoggerPipePair) {
126             return faultLoggerPipePair.pid_ == pid;
127         });
128     return iter == sdkDumpPipes_.end() ? nullptr : &(*iter);
129 }
130 
DelSdkDumpPipePair(int pid)131 void FaultLoggerPipePair::DelSdkDumpPipePair(int pid)
132 {
133     sdkDumpPipes_.remove_if([pid](const FaultLoggerPipePair& faultLoggerPipePair) {
134         return faultLoggerPipePair.pid_ == pid;
135     });
136 }
137 
LitePerfPipePair(int32_t uid)138 LitePerfPipePair::LitePerfPipePair(int32_t uid) : uid_(uid) {}
139 
GetPipeFd(PipeFdUsage usage,FaultLoggerPipeType pipeType)140 int32_t LitePerfPipePair::GetPipeFd(PipeFdUsage usage, FaultLoggerPipeType pipeType)
141 {
142     FaultLoggerPipe& targetPipe = (usage == PipeFdUsage::BUFFER_FD) ? faultLoggerPipeBuf_ : faultLoggerPipeRes_;
143     if (pipeType == FaultLoggerPipeType::PIPE_FD_READ) {
144         return targetPipe.GetReadFd();
145     }
146     if (pipeType == FaultLoggerPipeType::PIPE_FD_WRITE) {
147         return targetPipe.GetWriteFd();
148     }
149     return -1;
150 }
151 
CreatePipePair(int uid)152 LitePerfPipePair& LitePerfPipePair::CreatePipePair(int uid)
153 {
154     auto pipePair = GetPipePair(uid);
155     if (pipePair != nullptr) {
156         return *pipePair;
157     }
158     return pipes_.emplace_back(uid);
159 }
160 
CheckDumpMax()161 bool LitePerfPipePair::CheckDumpMax()
162 {
163     if (pipes_.size() > MAX_LITE_PERF_PIPE_SIZE) {
164         return true;
165     }
166     return false;
167 }
168 
CheckDumpRecord(int uid)169 bool LitePerfPipePair::CheckDumpRecord(int uid)
170 {
171     auto iter = std::find_if(pipes_.begin(), pipes_.end(),
172         [uid](const LitePerfPipePair& pipePair) {
173             return pipePair.uid_ == uid;
174         });
175     return iter != pipes_.end();
176 }
177 
GetPipePair(int uid)178 LitePerfPipePair* LitePerfPipePair::GetPipePair(int uid)
179 {
180     auto iter = std::find_if(pipes_.begin(), pipes_.end(),
181         [uid](const LitePerfPipePair& pipePair) {
182             return pipePair.uid_ == uid;
183         });
184     return iter == pipes_.end() ? nullptr : &(*iter);
185 }
186 
DelPipePair(int uid)187 void LitePerfPipePair::DelPipePair(int uid)
188 {
189     pipes_.remove_if([uid](const LitePerfPipePair& pipePair) {
190         return pipePair.uid_ == uid;
191     });
192 }
193 } // namespace HiviewDfx
194 } // namespace OHOS
195