• 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 "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 
CaDoInChildProcesscatcher(int writeFd)40 int ShellCatcher::CaDoInChildProcesscatcher(int writeFd)
41 {
42     int ret = -1;
43     switch (catcherType_) {
44         case CATCHER_HILOG:
45             ret = execl("/system/bin/hilog", "hilog", "-x", nullptr);
46             break;
47         case CATCHER_LIGHT_HILOG:
48             ret = execl("/system/bin/hilog", "hilog", "-z", "100", "-P", std::to_string(pid_).c_str(),
49                 nullptr);
50             break;
51         case CATCHER_SNAPSHOT:
52             {
53                 std::string path = "/data/log/eventlog/snapshot_display_";
54                 path += TimeUtil::TimestampFormatToDate(TimeUtil::GetMilliseconds() / TimeUtil::SEC_TO_MILLISEC,
55                     "%Y%m%d%H%M%S");
56                 path += ".jpeg";
57                 ret = execl("/system/bin/snapshot_display", "snapshot_display", "-f", path.c_str(), nullptr);
58             }
59             break;
60         case CATCHER_SCBSESSION:
61             ret = execl("/system/bin/scb_debug", "scb_debug", "SCBScenePanel", "getContainerSession", nullptr);
62             break;
63         case CATCHER_SCBVIEWPARAM:
64             ret = execl("/system/bin/scb_debug", "scb_debug", "SCBScenePanel", "getViewParam", nullptr);
65         default:
66             break;
67     }
68     return ret;
69 }
70 
DoChildProcess(int writeFd)71 void ShellCatcher::DoChildProcess(int writeFd)
72 {
73     if (writeFd < 0 || dup2(writeFd, STDOUT_FILENO) == -1 ||
74         dup2(writeFd, STDIN_FILENO) == -1 || dup2(writeFd, STDERR_FILENO) == -1) {
75         HIVIEW_LOGE("dup2 writeFd fail");
76         _exit(-1);
77     }
78 
79     int ret = -1;
80     switch (catcherType_) {
81         case CATCHER_AMS:
82             ret = execl("/system/bin/hidumper", "hidumper", "-s", "AbilityManagerService", "-a", "-a", nullptr);
83             break;
84         case CATCHER_WMS:
85             ret = execl("/system/bin/hidumper", "hidumper", "-s", "WindowManagerService", "-a", "-a", nullptr);
86             break;
87         case CATCHER_CPU:
88             ret = execl("/system/bin/hidumper", "hidumper", "--cpuusage", nullptr);
89             break;
90         case CATCHER_MEM:
91             ret = execl("/system/bin/hidumper", "hidumper", "--mem", std::to_string(pid_).c_str(), nullptr);
92             break;
93         case CATCHER_PMS:
94             ret = execl("/system/bin/hidumper", "hidumper", "-s", "PowerManagerService", "-a", "-s", nullptr);
95             break;
96         case CATCHER_DPMS:
97             ret = execl("/system/bin/hidumper", "hidumper", "-s", "DisplayPowerManagerService", nullptr);
98             break;
99         case CATCHER_RS:
100             ret = execl("/system/bin/hidumper", "hidumper", "-s", "RenderService", "-a", "allInfo", nullptr);
101             break;
102         default:
103             ret = CaDoInChildProcesscatcher(writeFd);
104             break;
105     }
106     if (ret < 0) {
107         HIVIEW_LOGE("execl %{public}d, errno: %{public}d", ret, errno);
108         _exit(-1);
109     }
110 }
111 
ReadShellToFile(int writeFd,const std::string & cmd)112 bool ShellCatcher::ReadShellToFile(int writeFd, const std::string& cmd)
113 {
114     int childPid = fork();
115     if (childPid < 0) {
116         HIVIEW_LOGE("fork fail");
117         return false;
118     } else if (childPid == 0) {
119         DoChildProcess(writeFd);
120     } else {
121         if (waitpid(childPid, nullptr, 0) != childPid) {
122             HIVIEW_LOGE("waitpid fail, pid: %{public}d, errno: %{public}d", childPid, errno);
123             return false;
124         }
125         HIVIEW_LOGI("waitpid %{public}d success", childPid);
126     }
127     return true;
128 }
129 
Catch(int fd,int jsonFd)130 int ShellCatcher::Catch(int fd, int jsonFd)
131 {
132     auto originSize = GetFdSize(fd);
133     if (catcherCmd_.empty()) {
134         HIVIEW_LOGE("catcherCmd empty");
135         return -1;
136     }
137 
138     ReadShellToFile(fd, catcherCmd_);
139     logSize_ = GetFdSize(fd) - originSize;
140     return logSize_;
141 }
142 } // namespace HiviewDFX
143 } // namespace OHOS
144