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 "executor/sa_dumper.h"
16 #include <cstdio>
17 #include <thread>
18 #include <unistd.h>
19 #include "dump_utils.h"
20 #include "securec.h"
21
22 namespace OHOS {
23 namespace HiviewDFX {
24 namespace {
25 const int PIPE_LENGTH = 2;
26 const int PIPE_INIT = 0;
27 const int PIPE_READ = 0;
28 const int PIPE_WRITE = 1;
29 const int LINE_LENGTH = 256;
30 const int BUF_LENGTH = 1024;
31 const char *SEPARATOR_TEMPLATE = "\n----------------------------------%s---------------------------------\n";
32
33 using StringMatrix = std::shared_ptr<std::vector<std::vector<std::string>>>;
34
35 // UString class
36 class UString {
37 public:
UString(const std::u16string & String)38 explicit UString(const std::u16string &String)
39 {
40 string_ = std::wstring_convert<std::codecvt_utf8<char16_t>, char16_t> {}.to_bytes(String);
41 }
42
43 public:
GetString() const44 const char *GetString() const
45 {
46 return string_.c_str();
47 }
GetInteger() const48 int GetInteger() const
49 {
50 return stoi(string_);
51 }
52
53 private:
54 std::string string_;
55 };
56
57 // MatrixWriter
58 class MatrixWriter {
59 public:
MatrixWriter(StringMatrix Data)60 explicit MatrixWriter(StringMatrix Data) : spData_(Data)
61 {
62 }
63
64 public:
WriteLine(const char * Line)65 void WriteLine(const char *Line)
66 {
67 if (spData_) {
68 std::vector<std::string> lines;
69 lines.push_back(Line);
70 spData_->push_back(lines);
71 } else {
72 printf("%s\n", Line);
73 }
74 }
75
76 private:
77 StringMatrix spData_;
78 };
79
80 // PipeReader
81 class PipeReader {
82 public:
PipeReader(int Id,StringMatrix Data)83 PipeReader(int Id, StringMatrix Data) : id_(Id), spData_(Data)
84 {
85 fds_[PIPE_READ] = PIPE_INIT;
86 fds_[PIPE_WRITE] = PIPE_INIT;
87 pipe(fds_);
88 }
~PipeReader()89 ~PipeReader()
90 {
91 if (wt_.joinable()) {
92 wt_.join();
93 }
94 }
95
96 public:
GetWritePipe()97 int GetWritePipe()
98 {
99 return fds_[PIPE_WRITE];
100 }
Run()101 void Run()
102 {
103 wt_ = std::thread(Execute, id_, fds_[PIPE_READ], spData_);
104 }
Stop()105 void Stop()
106 {
107 close(fds_[PIPE_WRITE]);
108 }
Execute(int id,int fd,StringMatrix Data)109 static void Execute(int id, int fd, StringMatrix Data)
110 {
111 FILE *fp = fdopen(fd, "r");
112 if (fp == nullptr) {
113 return;
114 }
115 char buffer[BUF_LENGTH];
116 while (!feof(fp)) {
117 if (fgets(buffer, BUF_LENGTH - 1, fp) != nullptr) {
118 MatrixWriter(Data).WriteLine(buffer);
119 }
120 }
121 fclose(fp);
122 }
123
124 private:
125 int id_;
126 StringMatrix spData_;
127 int fds_[PIPE_LENGTH];
128 std::thread wt_;
129 };
130 } // namespace
131
SADumper(void)132 SADumper::SADumper(void)
133 {
134 }
135
~SADumper(void)136 SADumper::~SADumper(void)
137 {
138 }
139
PreExecute(const std::shared_ptr<DumperParameter> & parameter,StringMatrix dump_datas)140 DumpStatus SADumper::PreExecute(const std::shared_ptr<DumperParameter> ¶meter, StringMatrix dump_datas)
141 {
142 result_ = dump_datas;
143 names_ = ptrDumpCfg_->args_->GetNameList();
144 StringVector args = ptrDumpCfg_->args_->GetArgList();
145 if (!args.empty() && names_.size() == 1) {
146 std::transform(args.begin(), args.end(), std::back_inserter(args_), Str8ToStr16);
147 }
148 return DumpStatus::DUMP_OK;
149 }
150
GetData(const std::string & name,const sptr<ISystemAbilityManager> & sam)151 DumpStatus SADumper::GetData(const std::string &name, const sptr<ISystemAbilityManager> &sam)
152 {
153 int id = DumpUtils::StrToId(name);
154 if (id == 0) {
155 DUMPER_HILOGD(MODULE_SERVICE, "no such ability id '%{public}s'\n", name.c_str());
156 return DumpStatus::DUMP_FAIL;
157 }
158 sptr<IRemoteObject> sa = sam->CheckSystemAbility(id);
159 if (sa == nullptr) {
160 DUMPER_HILOGD(MODULE_SERVICE, "no such system ability %{public}s\n", name.c_str());
161 return DumpStatus::DUMP_FAIL;
162 }
163 char line[LINE_LENGTH] = {};
164 int ret = sprintf_s(line, sizeof(line), SEPARATOR_TEMPLATE,
165 DumpUtils::ConvertSaIdToSaName(name).c_str());
166 if (ret < 0) {
167 DUMPER_HILOGD(MODULE_SERVICE, "print separator line fail!");
168 return DumpStatus::DUMP_FAIL;
169 }
170 MatrixWriter(result_).WriteLine(line);
171 PipeReader reader(id, result_);
172 reader.Run();
173 if (sa->Dump(reader.GetWritePipe(), args_) != ERR_OK) {
174 DUMPER_HILOGD(MODULE_SERVICE, "system ability:%{public}s dump fail!\n", name.c_str());
175 }
176 reader.Stop();
177 return DumpStatus::DUMP_OK;
178 }
179
Execute()180 DumpStatus SADumper::Execute()
181 {
182 sptr<ISystemAbilityManager> sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
183 if (sam == nullptr) {
184 DUMPER_HILOGD(MODULE_SERVICE, "get samgr fail!");
185 return DumpStatus::DUMP_FAIL;
186 }
187 if (names_.empty()) {
188 U16StringVector vct = sam->ListSystemAbilities();
189 std::transform(vct.begin(), vct.end(), std::back_inserter(names_), Str16ToStr8);
190 }
191 for (size_t i = 0; i < names_.size(); ++i) {
192 if (GetData(names_[i], sam) != DumpStatus::DUMP_OK) {
193 DUMPER_HILOGD(MODULE_SERVICE, "system ability:%{public}s execute fail!\n", names_[i].c_str());
194 }
195 }
196 return DumpStatus::DUMP_OK;
197 }
198
AfterExecute()199 DumpStatus SADumper::AfterExecute()
200 {
201 return DumpStatus::DUMP_OK;
202 }
203 } // namespace HiviewDFX
204 } // namespace OHOS
205