1 /*
2 * Copyright (C) 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 #include "shell_catcher.h"
16 #include <unistd.h>
17 #include <sys/wait.h>
18 #include "hiview_logger.h"
19 #include "common_utils.h"
20 #include "log_catcher_utils.h"
21 #include "securec.h"
22 #include "time_util.h"
23 namespace OHOS {
24 namespace HiviewDFX {
25 DEFINE_LOG_LABEL(0xD002D01, "EventLogger-ShellCatcher");
ShellCatcher()26 ShellCatcher::ShellCatcher() : EventLogCatcher()
27 {
28 name_ = "ShellCatcher";
29 }
30
Initialize(const std::string & cmd,int type,int catcherPid)31 bool ShellCatcher::Initialize(const std::string& cmd, int type, int catcherPid)
32 {
33 catcherCmd_ = cmd;
34 catcherType_ = CATCHER_TYPE(type);
35 pid_ = catcherPid;
36 description_ = "catcher cmd: " + catcherCmd_ + " ";
37 return true;
38 }
39
SetEvent(std::shared_ptr<SysEvent> event)40 void ShellCatcher::SetEvent(std::shared_ptr<SysEvent> event)
41 {
42 event_ = event;
43 }
44
DoChildProcess(int writeFd)45 void ShellCatcher::DoChildProcess(int writeFd)
46 {
47 if (writeFd < 0 || dup2(writeFd, STDOUT_FILENO) == -1 ||
48 dup2(writeFd, STDIN_FILENO) == -1 || dup2(writeFd, STDERR_FILENO) == -1) {
49 HIVIEW_LOGE("dup2 writeFd fail");
50 _exit(-1);
51 }
52
53 int ret = -1;
54 #ifdef HILOG_CATCHER_ENABLE
55 ret = DoHilogCatcher(writeFd);
56 #endif // HILOG_CATCHER_ENABLE
57
58 #ifdef USAGE_CATCHER_ENABLE
59 ret = DoUsageCatcher(writeFd);
60 #endif // USAGE_CATCHER_ENABLE
61
62 #ifdef SCB_CATCHER_ENABLE
63 ret = DoScbCatcher(writeFd);
64 #endif // SCB_CATCHER_ENABLE
65
66 #ifdef OTHER_CATCHER_ENABLE
67 ret = DoOtherCatcher(writeFd);
68 #endif // OTHER_CATCHER_ENABLE
69 if (ret < 0) {
70 HIVIEW_LOGE("execl %{public}d, errno: %{public}d", ret, errno);
71 _exit(-1);
72 }
73 }
74
75 #ifdef HILOG_CATCHER_ENABLE
DoHilogCatcher(int writeFd)76 int ShellCatcher::DoHilogCatcher(int writeFd)
77 {
78 int ret = -1;
79 switch (catcherType_) {
80 case CATCHER_HILOG:
81 ret = execl("/system/bin/hilog", "hilog", "-x", nullptr);
82 break;
83 case CATCHER_LIGHT_HILOG:
84 ret = execl("/system/bin/hilog", "hilog", "-z", "1000", "-P", std::to_string(pid_).c_str(),
85 nullptr);
86 break;
87 case CATCHER_INPUT_EVENT_HILOG:
88 ret = execl("/system/bin/hilog", "hilog", "-T", "InputKeyFlow", "-e",
89 std::to_string(pid_).c_str(), "-x", nullptr);
90 break;
91 case CATCHER_INPUT_HILOG:
92 ret = execl("/system/bin/hilog", "hilog", "-T", "InputKeyFlow", "-x", nullptr);
93 break;
94 case CATCHER_TAGHILOG:
95 ret = execl("/system/bin/hilog",
96 "hilog",
97 "-T",
98 "PowerState,PowerSuspend,PowerInput,DisplayState,DfxFaultLogger",
99 "-x",
100 nullptr);
101 break;
102 default:
103 break;
104 }
105 return ret;
106 }
107 #endif // HILOG_CATCHER_ENABLE
108
109 #ifdef USAGE_CATCHER_ENABLE
DoUsageCatcher(int writeFd)110 int ShellCatcher::DoUsageCatcher(int writeFd)
111 {
112 int ret = -1;
113 switch (catcherType_) {
114 case CATCHER_AMS:
115 ret = execl("/system/bin/hidumper", "hidumper", "-s", "AbilityManagerService", "-a", "-a", nullptr);
116 break;
117 case CATCHER_WMS:
118 ret = execl("/system/bin/hidumper", "hidumper", "-s", "WindowManagerService", "-a", "-a", nullptr);
119 break;
120 case CATCHER_CPU:
121 ret = execl("/system/bin/hidumper", "hidumper", "--cpuusage", nullptr);
122 break;
123 case CATCHER_PMS:
124 ret = execl("/system/bin/hidumper", "hidumper", "-s", "PowerManagerService", "-a", "-s", nullptr);
125 break;
126 case CATCHER_DPMS:
127 ret = execl("/system/bin/hidumper", "hidumper", "-s", "DisplayPowerManagerService", nullptr);
128 break;
129 case CATCHER_RS:
130 ret = execl("/system/bin/hidumper", "hidumper", "-s", "RenderService", "-a", "allInfo", nullptr);
131 break;
132 case CATCHER_DAM:
133 ret = execl("/system/bin/hidumper", "hidumper", "-s", "1910", "-a", "DumpAppMap", nullptr);
134 break;
135 default:
136 break;
137 }
138 return ret;
139 }
140 #endif // USAGE_CATCHER_ENABLE
141
142 #ifdef SCB_CATCHER_ENABLE
DoScbCatcher(int writeFd)143 int ShellCatcher::DoScbCatcher(int writeFd)
144 {
145 int ret = -1;
146 switch (catcherType_) {
147 case CATCHER_SCBWMS:
148 case CATCHER_SCBWMSEVT:
149 {
150 std::string cmdSuffix = (catcherType_ == CATCHER_SCBWMS) ? " -simplify" : " -event";
151 std::string cmd = "-w " + focusWindowId_ + cmdSuffix;
152 ret = execl("/system/bin/hidumper", "hidumper", "-s", "WindowManagerService", "-a",
153 cmd.c_str(), nullptr);
154 }
155 break;
156 case CATCHER_SCBSESSION:
157 case CATCHER_SCBVIEWPARAM:
158 {
159 std::string cmd = (catcherType_ == CATCHER_SCBSESSION) ? "-b SCBScenePanel getContainerSession" :
160 "-b SCBScenePanel getViewParam";
161 ret = execl("/system/bin/hidumper", "hidumper", "-s", "4606", "-a", cmd.c_str(), nullptr);
162 }
163 break;
164 case CATCHER_SCBWMSV:
165 {
166 std::string cmd = "-v all -simplify";
167 ret = execl("/system/bin/hidumper", "hidumper", "-s", "WindowManagerService", "-a",
168 cmd.c_str(), nullptr);
169 }
170 default:
171 break;
172 }
173 return ret;
174 }
175 #endif // SCB_CATCHER_ENABLE
176
177 #ifdef OTHER_CATCHER_ENABLE
DoOtherCatcher(int writeFd)178 int ShellCatcher::DoOtherCatcher(int writeFd)
179 {
180 int ret = -1;
181 switch (catcherType_) {
182 case CATCHER_SNAPSHOT:
183 {
184 std::string path = "/data/log/eventlog/snapshot_display_";
185 path += TimeUtil::TimestampFormatToDate(TimeUtil::GetMilliseconds() / TimeUtil::SEC_TO_MILLISEC,
186 "%Y%m%d%H%M%S");
187 path += ".jpeg";
188 ret = execl("/system/bin/snapshot_display", "snapshot_display", "-f", path.c_str(), nullptr);
189 }
190 break;
191 case CATCHER_EEC:
192 {
193 std::string cmd = "-b EventExclusiveCommander getAllEventExclusiveCaller";
194 ret = execl("/system/bin/hidumper", "hidumper", "-s", "4606", "-a", cmd.c_str(), nullptr);
195 }
196 break;
197 case CATCHER_GEC:
198 {
199 std::string cmd = "-b SCBGestureManager getAllGestureEnableCaller";
200 ret = execl("/system/bin/hidumper", "hidumper", "-s", "4606", "-a", cmd.c_str(), nullptr);
201 }
202 break;
203 case CATCHER_UI:
204 {
205 std::string cmd = "-p 0";
206 ret = execl("/system/bin/hidumper", "hidumper", "-s", "4606", "-a", cmd.c_str(), nullptr);
207 }
208 break;
209 case CATCHER_MMI:
210 ret = execl("/system/bin/hidumper", "hidumper", "-s", "MultimodalInput", "-a", "-w", nullptr);
211 break;
212 case CATCHER_DMS:
213 ret = execl("/system/bin/hidumper", "hidumper", "-s", "DisplayManagerService", "-a", "-a", nullptr);
214 break;
215 default:
216 ret = DoOtherChildProcesscatcher(writeFd);
217 break;
218 }
219 return ret;
220 }
221 #endif // OTHER_CATCHER_ENABLE
222
DoOtherChildProcesscatcher(int writeFd)223 int ShellCatcher::DoOtherChildProcesscatcher(int writeFd)
224 {
225 int ret = -1;
226 switch (catcherType_) {
227 case CATCHER_TAGHILOG:
228 ret = execl("/system/bin/hilog",
229 "hilog",
230 "-T",
231 "PowerState,PowerSuspend,PowerInput,DisplayState,DfxFaultLogger",
232 nullptr);
233 break;
234 default:
235 break;
236 }
237 return ret;
238 }
239
SetFocusWindowId(const std::string & focusWindowId)240 void ShellCatcher::SetFocusWindowId(const std::string& focusWindowId)
241 {
242 focusWindowId_ = focusWindowId;
243 }
244
ReadShellToFile(int writeFd,const std::string & cmd)245 bool ShellCatcher::ReadShellToFile(int writeFd, const std::string& cmd)
246 {
247 int childPid = fork();
248 if (childPid < 0) {
249 HIVIEW_LOGE("fork fail");
250 return false;
251 } else if (childPid == 0) {
252 DoChildProcess(writeFd);
253 } else {
254 if (waitpid(childPid, nullptr, 0) != childPid) {
255 HIVIEW_LOGE("waitpid fail, pid: %{public}d, errno: %{public}d", childPid, errno);
256 return false;
257 }
258 HIVIEW_LOGI("waitpid %{public}d success", childPid);
259 }
260 return true;
261 }
262
Catch(int fd,int jsonFd)263 int ShellCatcher::Catch(int fd, int jsonFd)
264 {
265 auto originSize = GetFdSize(fd);
266 if (catcherCmd_.empty()) {
267 HIVIEW_LOGE("catcherCmd empty");
268 return -1;
269 }
270
271 ReadShellToFile(fd, catcherCmd_);
272 logSize_ = GetFdSize(fd) - originSize;
273 return logSize_;
274 }
275 } // namespace HiviewDFX
276 } // namespace OHOS
277