• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 #include "dump_utils.h"
16 
17 #include <cerrno>
18 #include <csignal>
19 #include <fcntl.h>
20 #include <poll.h>
21 #include <set>
22 #include <sys/stat.h>
23 #include <unistd.h>
24 #include <fstream>
25 #include <iostream>
26 
27 #include <sys/prctl.h>
28 #include <sys/resource.h>
29 #include <sys/times.h>
30 #include <sys/types.h>
31 #include <sys/wait.h>
32 
33 #include "common.h"
34 #include "datetime_ex.h"
35 #include "securec.h"
36 #include "string_ex.h"
37 
38 #include "system_ability_definition.h"
39 #include "hilog_wrapper.h"
40 
41 namespace OHOS {
42 namespace HiviewDFX {
IgnorePipeQuit()43 void DumpUtils::IgnorePipeQuit()
44 {
45     signal(SIGPIPE, SIG_IGN); // protect from pipe quit
46 }
47 
IgnoreStdoutCache()48 void DumpUtils::IgnoreStdoutCache()
49 {
50     setvbuf(stdout, nullptr, _IONBF, 0); // never cache stdout
51 }
52 
IgnoreOom()53 void DumpUtils::IgnoreOom()
54 {
55     setpriority(PRIO_PROCESS, 0, TOP_PRIORITY); // protect from OOM
56 }
57 
SetAdj(int adj)58 void DumpUtils::SetAdj(int adj)
59 {
60     int fd = FdToWrite(FILE_CUR_OOM_ADJ);
61     if (fd < 0) {
62         return;
63     }
64     dprintf(fd, "%d", adj);
65     close(fd);
66 }
67 
BoostPriority()68 void DumpUtils::BoostPriority()
69 {
70     IgnoreOom();
71     IgnorePipeQuit();
72     IgnoreStdoutCache();
73     SetAdj(TOP_OOM_ADJ);
74 }
75 
ErrnoToMsg(const int & error)76 std::string DumpUtils::ErrnoToMsg(const int &error)
77 {
78     const int bufSize = 128;
79     char buf[bufSize] = {0};
80     strerror_r(error, buf, bufSize);
81     return buf;
82 }
83 
FdToRead(const std::string & file)84 int DumpUtils::FdToRead(const std::string &file)
85 {
86     char path[PATH_MAX] = {0};
87     if (realpath(file.c_str(), path) == nullptr) {
88         DUMPER_HILOGD(MODULE_COMMON, "realpath, no such file. path=[%{public}s], file=[%{public}s]",
89             path, file.c_str());
90         return -1;
91     }
92 
93     if (file != std::string(path)) {
94         DUMPER_HILOGI(MODULE_COMMON, "fail to check consistency. path=[%{public}s], file=[%{public}s]",
95             path, file.c_str());
96     }
97 
98     int fd = TEMP_FAILURE_RETRY(open(path, O_RDONLY | O_CLOEXEC | O_NONBLOCK));
99     if (fd == -1) {
100         DUMPER_HILOGD(MODULE_COMMON, "open [%{public}s] %{public}s", path, ErrnoToMsg(errno).c_str());
101     }
102     return fd;
103 }
104 
FdToWrite(const std::string & file)105 int DumpUtils::FdToWrite(const std::string &file)
106 {
107     std::string split = "/";
108     auto pos = file.find_last_of(split);
109     if (pos == std::string::npos) {
110         DUMPER_HILOGD(MODULE_COMMON, "file path:[%{public}s] error", file.c_str());
111         return -1;
112     }
113     std::string tempPath = file.substr(0, pos + 1);
114     std::string name = file.substr(pos + 1);
115 
116     char path[PATH_MAX] = {0};
117     if (realpath(tempPath.c_str(), path) != nullptr) {
118         std::string fileName = path + split + name;
119         int fd = TEMP_FAILURE_RETRY(open(fileName.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW,
120                                          S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH));
121         if (fd == -1) {
122             DUMPER_HILOGD(MODULE_COMMON, "open [%{public}s] %{public}s",
123                 fileName.c_str(), ErrnoToMsg(errno).c_str());
124         }
125         return fd;
126     }
127     DUMPER_HILOGD(MODULE_COMMON, "realpath, no such file. path=[%{public}s], tempPath=[%{public}s]",
128         path, tempPath.c_str());
129     return -1;
130 }
131 
FileWriteable(const std::string & file)132 bool DumpUtils::FileWriteable(const std::string &file)
133 {
134     int fd = FdToWrite(file);
135     if (fd >= 0) {
136         close(fd);
137         return true;
138     }
139     return false;
140 }
141 
CheckProcessAlive(uint32_t pid)142 bool DumpUtils::CheckProcessAlive(uint32_t pid)
143 {
144     char path[PATH_MAX] = {0};
145     char pathPid[PATH_MAX] = {0};
146     int ret = sprintf_s(pathPid, PATH_MAX, "/proc/%u", pid);
147     if (ret < 0) {
148         return false;
149     }
150     if (realpath(pathPid, path) != nullptr) { // path exist
151         if (access(path, F_OK) == 0) {        // can be read
152             return true;
153         }
154     }
155     return false;
156 }
157 
RemoveDuplicateString(std::vector<std::string> & strList)158 void DumpUtils::RemoveDuplicateString(std::vector<std::string> &strList)
159 {
160     std::vector<std::string> tmpVtr;
161     std::set<std::string> tmpSet;
162     for (auto &it : strList) {
163         auto ret = tmpSet.insert(it);
164         if (ret.second) {
165             tmpVtr.push_back(it);
166         }
167     }
168     strList = tmpVtr;
169 }
170 
StrToId(const std::string & name)171 int DumpUtils::StrToId(const std::string &name)
172 {
173     int id = 0;
174     auto iter = std::find_if(saNameMap_.begin(), saNameMap_.end(), [&](const std::pair<int, std::string> &item) {
175         return name.compare(item.second) == 0;
176     });
177     if (iter == saNameMap_.end()) {
178         if (!StrToInt(name, id)) { // Decimal string
179             return 0; // invalid ability ID
180         }
181     } else {
182         id = iter->first;
183     }
184     return id;
185 }
186 
ConvertSaIdToSaName(const std::string & saIdStr)187 std::string DumpUtils::ConvertSaIdToSaName(const std::string &saIdStr)
188 {
189     int saId = StrToId(saIdStr);
190     auto iter = saNameMap_.find(saId);
191     if (iter == saNameMap_.end()) {
192         return saIdStr;
193     }
194     return iter->second;
195 }
196 
DirectoryExists(const std::string & path)197 bool DumpUtils::DirectoryExists(const std::string &path)
198 {
199     struct stat fileInfo;
200     if (stat(path.c_str(), &fileInfo) == 0) {
201         return S_ISDIR(fileInfo.st_mode);
202     }
203     return false;
204 }
205 
PathIsValid(const std::string & path)206 bool DumpUtils::PathIsValid(const std::string &path)
207 {
208     return access(path.c_str(), F_OK) == 0;
209 }
210 
CopyFile(const std::string & src,const std::string & des)211 bool DumpUtils::CopyFile(const std::string &src, const std::string &des)
212 {
213     std::ifstream fin(src);
214     std::ofstream fout(des);
215     if ((!fin.is_open()) || (!fout.is_open())) {
216         return false;
217     }
218     fout << fin.rdbuf();
219     if (fout.fail()) {
220         fout.clear();
221     }
222     fout.flush();
223     return true;
224 }
225 } // namespace HiviewDFX
226 } // namespace OHOS
227