• 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 <cstdio>
21 #include <cstdlib>
22 #include <cstring>
23 #include <ctime>
24 #include <fcntl.h>
25 #include <securec.h>
26 #include <string>
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 #include <unistd.h>
33 #include <vector>
34 #include "dfx_define.h"
35 #include "dfx_log.h"
36 
37 
38 namespace OHOS {
39 namespace HiviewDFX {
40 namespace {
41 static const std::string FAULTLOGGER_PIPE_TAG = "FaultLoggerPipe";
42 const int PIPE_READ = 0;
43 const int PIPE_WRITE = 1;
44 const int PIPE_TIMEOUT = 10000; // 10 seconds
45 }
46 
FaultLoggerPipe()47 FaultLoggerPipe::FaultLoggerPipe()
48 {
49     init_ = false;
50     write_ = false;
51     Init();
52 }
53 
~FaultLoggerPipe()54 FaultLoggerPipe::~FaultLoggerPipe()
55 {
56     Destroy();
57 }
58 
GetReadFd(void)59 int FaultLoggerPipe::GetReadFd(void)
60 {
61     DFXLOG_DEBUG("%s :: pipe read fd: %d", __func__, fds_[PIPE_READ]);
62     return fds_[PIPE_READ];
63 }
64 
GetWriteFd(void)65 int FaultLoggerPipe::GetWriteFd(void)
66 {
67     DFXLOG_DEBUG("%s :: pipe write fd: %d", __func__, fds_[PIPE_WRITE]);
68     if (!write_) {
69         write_ = true;
70         return fds_[PIPE_WRITE];
71     }
72     return -1;
73 }
74 
Init(void)75 bool FaultLoggerPipe::Init(void)
76 {
77     if (!init_) {
78         if (pipe(fds_) != 0) {
79             DFXLOG_ERROR("%s :: Failed to create pipe.", __func__);
80             return false;
81         }
82         DFXLOG_DEBUG("%s :: create pipe.", __func__);
83     }
84     init_ = true;
85     if (!SetSize(MAX_PIPE_SIZE)) {
86         DFXLOG_ERROR("%s :: Failed to set pipe size.", __func__);
87     }
88     return true;
89 }
90 
SetSize(long sz)91 bool FaultLoggerPipe::SetSize(long sz)
92 {
93     if (!init_) {
94         return false;
95     }
96     if (fcntl(fds_[PIPE_READ], F_SETPIPE_SZ, sz) < 0) {
97         return false;
98     }
99     if (fcntl(fds_[PIPE_WRITE], F_SETPIPE_SZ, sz) < 0) {
100         return false;
101     }
102     return true;
103 }
104 
Destroy(void)105 void FaultLoggerPipe::Destroy(void)
106 {
107     if (init_) {
108         DFXLOG_DEBUG("%s :: close pipe.", __func__);
109         Close(fds_[PIPE_READ]);
110         Close(fds_[PIPE_WRITE]);
111     }
112     init_ = false;
113 }
114 
Close(int fd) const115 void FaultLoggerPipe::Close(int fd) const
116 {
117     if (fd > 0) {
118         syscall(SYS_close, fd);
119     }
120 }
121 
FaultLoggerPipe2(uint64_t time,bool isJson)122 FaultLoggerPipe2::FaultLoggerPipe2(uint64_t time, bool isJson)
123 {
124     if (isJson) {
125         faultLoggerJsonPipeBuf_ = std::unique_ptr<FaultLoggerPipe>(new FaultLoggerPipe());
126         faultLoggerJsonPipeRes_ = std::unique_ptr<FaultLoggerPipe>(new FaultLoggerPipe());
127     } else {
128         faultLoggerPipeBuf_ = std::unique_ptr<FaultLoggerPipe>(new FaultLoggerPipe());
129         faultLoggerPipeRes_ = std::unique_ptr<FaultLoggerPipe>(new FaultLoggerPipe());
130     }
131     time_ = time;
132 }
133 
~FaultLoggerPipe2()134 FaultLoggerPipe2::~FaultLoggerPipe2()
135 {
136     faultLoggerPipeBuf_.reset();
137     faultLoggerPipeRes_.reset();
138     faultLoggerJsonPipeBuf_.reset();
139     faultLoggerJsonPipeRes_.reset();
140     time_ = 0;
141 }
142 
FaultLoggerPipeMap()143 FaultLoggerPipeMap::FaultLoggerPipeMap()
144 {
145     std::lock_guard<std::mutex> lck(pipeMapsMutex_);
146     faultLoggerPipes_.clear();
147 }
148 
~FaultLoggerPipeMap()149 FaultLoggerPipeMap::~FaultLoggerPipeMap()
150 {
151     std::lock_guard<std::mutex> lck(pipeMapsMutex_);
152     std::map<int, std::unique_ptr<FaultLoggerPipe2> >::iterator iter = faultLoggerPipes_.begin();
153     while (iter != faultLoggerPipes_.end()) {
154         faultLoggerPipes_.erase(iter++);
155     }
156 }
157 
Set(int pid,uint64_t time,bool isJson)158 void FaultLoggerPipeMap::Set(int pid, uint64_t time, bool isJson)
159 {
160     std::lock_guard<std::mutex> lck(pipeMapsMutex_);
161     if (!Find(pid)) {
162         std::unique_ptr<FaultLoggerPipe2> ptr = std::unique_ptr<FaultLoggerPipe2>(new FaultLoggerPipe2(time, isJson));
163         faultLoggerPipes_.emplace(pid, std::move(ptr));
164     }
165 }
166 
Check(int pid,uint64_t time)167 bool FaultLoggerPipeMap::Check(int pid, uint64_t time)
168 {
169     std::lock_guard<std::mutex> lck(pipeMapsMutex_);
170     std::map<int, std::unique_ptr<FaultLoggerPipe2> >::const_iterator iter = faultLoggerPipes_.find(pid);
171     if (iter != faultLoggerPipes_.end()) {
172         if ((time > faultLoggerPipes_[pid]->time_) && (time - faultLoggerPipes_[pid]->time_) > PIPE_TIMEOUT) {
173             faultLoggerPipes_.erase(iter);
174             return false;
175         }
176         return true;
177     }
178     return false;
179 }
180 
Get(int pid)181 FaultLoggerPipe2* FaultLoggerPipeMap::Get(int pid)
182 {
183     std::lock_guard<std::mutex> lck(pipeMapsMutex_);
184     if (!Find(pid)) {
185         return nullptr;
186     }
187     return faultLoggerPipes_[pid].get();
188 }
189 
Del(int pid)190 void FaultLoggerPipeMap::Del(int pid)
191 {
192     std::lock_guard<std::mutex> lck(pipeMapsMutex_);
193     std::map<int, std::unique_ptr<FaultLoggerPipe2> >::const_iterator iter = faultLoggerPipes_.find(pid);
194     if (iter != faultLoggerPipes_.end()) {
195         faultLoggerPipes_.erase(iter);
196     }
197 }
198 
Find(int pid) const199 bool FaultLoggerPipeMap::Find(int pid) const
200 {
201     std::map<int, std::unique_ptr<FaultLoggerPipe2> >::const_iterator iter = faultLoggerPipes_.find(pid);
202     if (iter != faultLoggerPipes_.end()) {
203         return true;
204     }
205     return false;
206 }
207 } // namespace HiviewDfx
208 } // namespace OHOS
209