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 <ipc_skeleton.h>
18 #include <sstream>
19 #include <thread>
20 #include <unistd.h>
21 #include "dump_utils.h"
22 #include "file_ex.h"
23 #include "securec.h"
24
25 namespace OHOS {
26 namespace HiviewDFX {
27 namespace {
28 static const std::string SEPARATOR_TEMPLATE = "----------------------------------";
29 static const std::string ABILITY_LINE = "-------------------------------[ability]-------------------------------";
30 const std::string LOG_TXT = "log.txt";
31 using StringMatrix = std::shared_ptr<std::vector<std::vector<std::string>>>;
32
33 } // namespace
34
SADumper(void)35 SADumper::SADumper(void)
36 {
37 }
38
~SADumper(void)39 SADumper::~SADumper(void)
40 {
41 }
42
PreExecute(const std::shared_ptr<DumperParameter> & parameter,StringMatrix dump_datas)43 DumpStatus SADumper::PreExecute(const std::shared_ptr<DumperParameter> ¶meter, StringMatrix dump_datas)
44 {
45 result_ = dump_datas;
46 names_ = ptrDumpCfg_->args_->GetNameList();
47 bool isZip = parameter->GetOpts().IsDumpZip();
48 auto callback = parameter->getClientCallback();
49 if (callback == nullptr) {
50 DUMPER_HILOGE(MODULE_COMMON, "PreExecute error|callback is nullptr");
51 return DumpStatus::DUMP_FAIL;
52 }
53 std::string logDefaultPath_ = callback->GetFolder() + LOG_TXT;
54 if (isZip) {
55 outputFd_ = DumpUtils::FdToWrite(logDefaultPath_);
56 } else {
57 outputFd_ = parameter->getClientCallback()->GetOutputFd();
58 }
59
60 StringVector args = ptrDumpCfg_->args_->GetArgList();
61 if (!args.empty() && names_.size() == 1) {
62 std::transform(args.begin(), args.end(), std::back_inserter(args_), Str8ToStr16);
63 std::stringstream argsStr;
64 for (std::string arg : args) {
65 argsStr << arg << " ";
66 }
67 argsStr_ = argsStr.str();
68 }
69 return DumpStatus::DUMP_OK;
70 }
71
GetData(const std::string & name,const sptr<ISystemAbilityManager> & sam)72 DumpStatus SADumper::GetData(const std::string &name, const sptr<ISystemAbilityManager> &sam)
73 {
74 int id = DumpUtils::StrToId(name);
75 if (id == -1) {
76 DUMPER_HILOGE(MODULE_SERVICE, "no such ability id '%{public}s'\n", name.c_str());
77 return DumpStatus::DUMP_FAIL;
78 }
79 sptr<IRemoteObject> sa = sam->CheckSystemAbility(id);
80 if (sa == nullptr) {
81 DUMPER_HILOGE(MODULE_SERVICE, "no such system ability %{public}s\n", name.c_str());
82 return DumpStatus::DUMP_FAIL;
83 }
84 std::stringstream ss;
85 ss << SEPARATOR_TEMPLATE << DumpUtils::ConvertSaIdToSaName(name) << SEPARATOR_TEMPLATE;
86 std::lock_guard<std::mutex> lock(mutex_);
87 SaveStringToFd(outputFd_, "\n" + ABILITY_LINE + "\n");
88 SaveStringToFd(outputFd_, "\n\n" + ss.str() + "\n");
89 int result = sa->Dump(outputFd_, args_);
90 if (result != ERR_OK) {
91 DUMPER_HILOGE(MODULE_SERVICE, "system ability:%{public}s dump fail!ret:%{public}d\n", name.c_str(), result);
92 }
93 int32_t calllingPid = IPCSkeleton::GetCallingPid();
94 DUMPER_HILOGI(MODULE_COMMON, "SA name:%{public}s dump success, cmd:%{public}s, calllingPid=%{public}d!",
95 name.c_str(), argsStr_.c_str(), calllingPid);
96 return DumpStatus::DUMP_OK;
97 }
98
Execute()99 DumpStatus SADumper::Execute()
100 {
101 sptr<ISystemAbilityManager> sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
102 if (sam == nullptr) {
103 DUMPER_HILOGE(MODULE_SERVICE, "get samgr fail!");
104 return DumpStatus::DUMP_FAIL;
105 }
106 if (names_.empty()) {
107 U16StringVector vct = sam->ListSystemAbilities();
108 std::transform(vct.begin(), vct.end(), std::back_inserter(names_), Str16ToStr8);
109 }
110 for (size_t i = 0; i < names_.size(); ++i) {
111 if (GetData(names_[i], sam) != DumpStatus::DUMP_OK) {
112 DUMPER_HILOGI(MODULE_SERVICE, "system ability:%{public}s execute fail!\n", names_[i].c_str());
113 }
114 }
115 return DumpStatus::DUMP_OK;
116 }
117
AfterExecute()118 DumpStatus SADumper::AfterExecute()
119 {
120 return DumpStatus::DUMP_OK;
121 }
122 } // namespace HiviewDFX
123 } // namespace OHOS
124