• 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 
16 #include "lmks_utils.h"
17 
18 #include <csignal>
19 #include <sys/stat.h>
20 #include <fcntl.h>
21 #include <unistd.h>
22 
23 #include "securec.h"
24 #include "hilog/log.h"
25 
26 namespace OHOS {
27 namespace LMKS {
28 namespace {
29 constexpr int PROC_PATH_MAX = 256;
30 constexpr int PROC_LINE_MAX = 128;
31 }  // namespace
32 
33 using namespace OHOS::HiviewDFX;
34 static constexpr HiLogLabel LABEL = {LOG_CORE, 0, "LmksUtils"};
35 
LmksUtils()36 LmksUtils::LmksUtils()
37 {}
38 
~LmksUtils()39 LmksUtils::~LmksUtils()
40 {}
41 
RemoveProcess(pid_t pid)42 int LmksUtils::RemoveProcess(pid_t pid)
43 {
44     auto procName = GetProcName(pid);
45     if (procName.empty()) {
46         HiLog::Error(LABEL, "pid %{public}d process name emptry", pid);
47         return -1;
48     }
49 
50     auto procSize = GetProcSize(pid);
51     if (procSize <= 0) {
52         HiLog::Error(LABEL, "pid %{public}d process size error", pid);
53         return -1;
54     }
55 
56     // kill process
57     int ret = kill(pid, SIGKILL);
58     if (ret) {
59         HiLog::Warn(LABEL, "kill pid %{public}d err %{public}s", pid, strerror(errno));
60         return (-errno);
61     } else {
62         HiLog::Info(
63             LABEL, "kill pid %{public}d success, name %{public}s size %{public}d", pid, procName.c_str(), procSize);
64     }
65 
66     return 0;
67 }
68 
GetProcName(pid_t pid)69 std::string LmksUtils::GetProcName(pid_t pid)
70 {
71     std::string name = "";
72 
73     if (pid < 1) {
74         HiLog::Warn(LABEL, "invalid pid %{public}d.", pid);
75         return name;
76     }
77 
78     char path[PROC_PATH_MAX];
79     char line[PROC_LINE_MAX];
80     int fd = -1;
81     ssize_t ret = -1;
82 
83     if (memset_s(path, sizeof(path), 0x00, sizeof(path)) != 0) {
84         HiLog::Error(LABEL, "memset_s path err %{public}s", strerror(errno));
85         return name;
86     }
87 
88     if (memset_s(line, sizeof(line), 0x00, sizeof(line)) != 0) {
89         HiLog::Error(LABEL, "memset_s line err %{public}s", strerror(errno));
90         return name;
91     }
92 
93     if (snprintf_s(path, PROC_PATH_MAX, PROC_PATH_MAX - 1, "/proc/%d/cmdline", pid) < 0) {
94         HiLog::Error(LABEL, "snprintf_s cmdline err %{public}s", strerror(errno));
95         return name;
96     }
97 
98     fd = open(path, O_RDONLY | O_CLOEXEC);
99     if (fd == -1) {
100         HiLog::Error(LABEL, "open path[%{public}s] err %{public}s", path, strerror(errno));
101         return name;
102     }
103 
104     ret = ReadAll(fd, line, sizeof(line) - 1);
105     if (ret < 0) {
106         close(fd);
107         return name;
108     }
109 
110     if (strlen(line) + 1 <= PROC_LINE_MAX && strlen(line) != 0) {
111         name = line;
112     } else {
113         HiLog::Error(LABEL, "cmdline no data");
114     }
115 
116     close(fd);
117     return name;
118 }
119 
GetProcSize(pid_t pid)120 int LmksUtils::GetProcSize(pid_t pid)
121 {
122     int rss = 0;
123 
124     if (pid <= 0) {
125         HiLog::Error(LABEL, "invalid pid %{public}d.", pid);
126         return rss;
127     }
128 
129     char path[PROC_PATH_MAX];
130     char line[PROC_LINE_MAX];
131     int fd = -1;
132     int total = -1;
133     ssize_t ret = -1;
134 
135     if (memset_s(path, sizeof(path), 0x00, sizeof(path)) != 0) {
136         HiLog::Error(LABEL, "memset_s path err %{public}s", strerror(errno));
137         return -1;
138     }
139 
140     if (memset_s(line, sizeof(line), 0x00, sizeof(line)) != 0) {
141         HiLog::Error(LABEL, "memset_s line err %{public}s", strerror(errno));
142         return -1;
143     }
144 
145     if (snprintf_s(path, PROC_PATH_MAX, PROC_PATH_MAX - 1, "/proc/%d/statm", pid) < 0) {
146         HiLog::Error(LABEL, "snprintf_s statm err %{public}s", strerror(errno));
147         return rss;
148     }
149 
150     fd = open(path, O_RDONLY | O_CLOEXEC);
151     if (fd == -1) {
152         HiLog::Error(LABEL, "open path[%{public}s] err %{public}s", path, strerror(errno));
153         return -1;
154     }
155 
156     ret = ReadAll(fd, line, sizeof(line) - 1);
157     if (ret < 0) {
158         close(fd);
159         return -1;
160     }
161 
162     if ((strlen(line) + 1 <= PROC_LINE_MAX && strlen(line) != 0) && (sscanf_s(line, "%d %d ", &total, &rss) > 0)) {
163         HiLog::Info(LABEL, "pid %{public}d total %{public}d rss %{public}d", pid, total, rss);
164     } else {
165         HiLog::Error(LABEL, "strlen or sscanf_s err %{public}s", strerror(errno));
166         rss = 0;
167     }
168 
169     close(fd);
170     return rss;
171 }
172 
ReadAll(int fd,char * buf,size_t maxLen)173 ssize_t LmksUtils::ReadAll(int fd, char *buf, size_t maxLen)
174 {
175     ssize_t ret = 0;
176     off_t offSet = 0;
177 
178     while (maxLen > 0) {
179         ssize_t rc = TEMP_FAILURE_RETRY(pread(fd, buf, maxLen, offSet));
180         if (rc == 0) {
181             break;
182         }
183         if (rc == -1) {
184             HiLog::Error(LABEL, "pread err %{public}s", strerror(errno));
185             return -1;
186         }
187         ret += rc;
188         buf += rc;
189         offSet += rc;
190         maxLen -= rc;
191     }
192 
193     return ret;
194 }
195 }  // namespace LMKS
196 }  // namespace OHOS
197