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