• 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 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> &parameter, 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