• 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 namespace OHOS {
38 namespace HiviewDFX {
39 namespace {
40 static const std::string FAULTLOGGER_PIPE_TAG = "FaultLoggerPipe";
41 const int PIPE_READ = 0;
42 const int PIPE_WRITE = 1;
43 const int PIPE_TIMEOUT = 10000; // 10 seconds
44 }
45 
FaultLoggerPipe()46 FaultLoggerPipe::FaultLoggerPipe()
47 {
48     init_ = false;
49     write_ = false;
50     Init();
51 }
52 
~FaultLoggerPipe()53 FaultLoggerPipe::~FaultLoggerPipe()
54 {
55     Destroy();
56 }
57 
GetReadFd(void)58 int FaultLoggerPipe::GetReadFd(void)
59 {
60     DFXLOG_DEBUG("%s :: pipe read fd: %d", __func__, fds_[PIPE_READ]);
61     return fds_[PIPE_READ];
62 }
63 
GetWriteFd(void)64 int FaultLoggerPipe::GetWriteFd(void)
65 {
66     DFXLOG_DEBUG("%s :: pipe write fd: %d", __func__, fds_[PIPE_WRITE]);
67     if (!write_) {
68         write_ = true;
69         return fds_[PIPE_WRITE];
70     }
71     return -1;
72 }
73 
Init(void)74 bool FaultLoggerPipe::Init(void)
75 {
76     if (!init_) {
77         if (pipe(fds_) != 0) {
78             DFXLOG_ERROR("%s :: Failed to create pipe.", __func__);
79             return false;
80         }
81         DFXLOG_DEBUG("%s :: create pipe.", __func__);
82     }
83     init_ = true;
84     return true;
85 }
86 
Destroy(void)87 void FaultLoggerPipe::Destroy(void)
88 {
89     if (init_) {
90         DFXLOG_DEBUG("%s :: close pipe.", __func__);
91         Close(fds_[PIPE_READ]);
92         Close(fds_[PIPE_WRITE]);
93     }
94     init_ = false;
95 }
96 
Close(int fd) const97 void FaultLoggerPipe::Close(int fd) const
98 {
99     if (fd > 0) {
100         syscall(SYS_close, fd);
101     }
102 }
103 
FaultLoggerPipe2(uint64_t time)104 FaultLoggerPipe2::FaultLoggerPipe2(uint64_t time)
105     : faultLoggerPipeBuf_(std::unique_ptr<FaultLoggerPipe>(new FaultLoggerPipe())),
106     faultLoggerPipeRes_(std::unique_ptr<FaultLoggerPipe>(new FaultLoggerPipe()))
107 {
108     time_ = time;
109 }
110 
~FaultLoggerPipe2()111 FaultLoggerPipe2::~FaultLoggerPipe2()
112 {
113     faultLoggerPipeBuf_.reset();
114     faultLoggerPipeRes_.reset();
115     time_ = 0;
116 }
117 
FaultLoggerPipeMap()118 FaultLoggerPipeMap::FaultLoggerPipeMap()
119 {
120     std::lock_guard<std::mutex> lck(pipeMapsMutex_);
121     faultLoggerPipes_.clear();
122 }
123 
~FaultLoggerPipeMap()124 FaultLoggerPipeMap::~FaultLoggerPipeMap()
125 {
126     std::lock_guard<std::mutex> lck(pipeMapsMutex_);
127     std::map<int, std::unique_ptr<FaultLoggerPipe2> >::iterator iter = faultLoggerPipes_.begin();
128     while (iter != faultLoggerPipes_.end()) {
129         faultLoggerPipes_.erase(iter++);
130     }
131 }
132 
Set(int pid,uint64_t time)133 void FaultLoggerPipeMap::Set(int pid, uint64_t time)
134 {
135     std::lock_guard<std::mutex> lck(pipeMapsMutex_);
136     if (!Find(pid)) {
137         std::unique_ptr<FaultLoggerPipe2> ptr = std::unique_ptr<FaultLoggerPipe2>(new FaultLoggerPipe2(time));
138         faultLoggerPipes_.emplace(pid, std::move(ptr));
139     }
140 }
141 
Check(int pid,uint64_t time)142 bool FaultLoggerPipeMap::Check(int pid, uint64_t time)
143 {
144     std::lock_guard<std::mutex> lck(pipeMapsMutex_);
145     std::map<int, std::unique_ptr<FaultLoggerPipe2> >::const_iterator iter = faultLoggerPipes_.find(pid);
146     if (iter != faultLoggerPipes_.end()) {
147         if ((time > faultLoggerPipes_[pid]->time_) && (time - faultLoggerPipes_[pid]->time_) > PIPE_TIMEOUT) {
148             faultLoggerPipes_.erase(iter);
149             return false;
150         }
151         return true;
152     }
153     return false;
154 }
155 
Get(int pid)156 FaultLoggerPipe2* FaultLoggerPipeMap::Get(int pid)
157 {
158     std::lock_guard<std::mutex> lck(pipeMapsMutex_);
159     if (!Find(pid)) {
160         return nullptr;
161     }
162     return faultLoggerPipes_[pid].get();
163 }
164 
Del(int pid)165 void FaultLoggerPipeMap::Del(int pid)
166 {
167     std::lock_guard<std::mutex> lck(pipeMapsMutex_);
168     std::map<int, std::unique_ptr<FaultLoggerPipe2> >::const_iterator iter = faultLoggerPipes_.find(pid);
169     if (iter != faultLoggerPipes_.end()) {
170         faultLoggerPipes_.erase(iter);
171     }
172 }
173 
Find(int pid) const174 bool FaultLoggerPipeMap::Find(int pid) const
175 {
176     std::map<int, std::unique_ptr<FaultLoggerPipe2> >::const_iterator iter = faultLoggerPipes_.find(pid);
177     if (iter != faultLoggerPipes_.end()) {
178         return true;
179     }
180     return false;
181 }
182 } // namespace HiviewDfx
183 } // namespace OHOS
184