• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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