• 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 
16 #include "hdf_dump.h"
17 
18 #include "ipc_payload_statistics.h"
19 
20 #include "file_ex.h"
21 #include "string_ex.h"
22 #include "unistd.h"
23 
24 #include "hdf_base.h"
25 #include "hdf_dump_reg.h"
26 #include "hdf_core_log.h"
27 #include "hdf_sbuf.h"
28 #include "securec.h"
29 
30 #define HDF_LOG_TAG hdf_dump
31 
32 using namespace OHOS;
33 
34 static DevHostDumpFunc g_dump = nullptr;
35 
36 const char *HDF_DUMP_SUCCESS_STR = " success\n";
37 const char *HDF_DUMP_FAIL_STR = " fail\n";
38 
39 // The maximum parameter is the parameter sent to the host, including public(num=2) and private(mux_num=20) parameters
40 static constexpr int32_t MAX_PARA_NUM = 22;
41 
HdfDumpIpcStatStart(std::string & result)42 static void HdfDumpIpcStatStart(std::string& result)
43 {
44     result = std::string("HdfDumpIpcStatStart pid:") + std::to_string(getpid());
45     bool ret = IPCPayloadStatistics::StartStatistics();
46     result += ret ? HDF_DUMP_SUCCESS_STR : HDF_DUMP_FAIL_STR;
47     return;
48 }
49 
HdfDumpIpcStatStop(std::string & result)50 static void HdfDumpIpcStatStop(std::string& result)
51 {
52     result = std::string("HdfDumpIpcStatStop pid:") + std::to_string(getpid());
53     bool ret = IPCPayloadStatistics::StopStatistics();
54     result += ret ? HDF_DUMP_SUCCESS_STR : HDF_DUMP_FAIL_STR;
55     return;
56 }
57 
HdfDumpIpcStatGet(std::string & result)58 static void HdfDumpIpcStatGet(std::string& result)
59 {
60     result += "********************************GlobalStatisticsInfo********************************";
61     result += "\nCurrentPid:";
62     result += std::to_string(getpid());
63     result += "\nTotalCount:";
64     result += std::to_string(IPCPayloadStatistics::GetTotalCount());
65     result += "\nTotalTimeCost:";
66     result += std::to_string(IPCPayloadStatistics::GetTotalCost());
67 
68     std::vector<int32_t> pids;
69     pids = IPCPayloadStatistics::GetPids();
70     for (unsigned int i = 0; i < pids.size(); i++) {
71         int32_t pid = pids[i];
72         result += "\n--------------------------------ProcessStatisticsInfo-------------------------------";
73         result += "\nCallingPid:";
74         result += std::to_string(pid);
75         result += "\nCallingPidTotalCount:";
76         result += std::to_string(IPCPayloadStatistics::GetCount(pid));
77         result += "\nCallingPidTotalTimeCost:";
78         result += std::to_string(IPCPayloadStatistics::GetCost(pid));
79 
80         std::vector<IPCInterfaceInfo> intfs;
81         intfs = IPCPayloadStatistics::GetDescriptorCodes(pid);
82         for (unsigned int j = 0; j < intfs.size(); j++) {
83             IPCInterfaceInfo intf = intfs[j];
84             result += "\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~InterfaceStatisticsInfo~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
85             result += "\nDescriptorCode:";
86             result += Str16ToStr8(intf.desc) + std::string("_") + std::to_string(intf.code);
87             result += "\nDescriptorCodeCount:";
88             result += std::to_string(
89                 IPCPayloadStatistics::GetDescriptorCodeCount(pid, intf.desc, intf.code));
90 
91             result += "\nDescriptorCodeTimeCost:";
92             result += "\nTotal:";
93             result += std::to_string(
94                 IPCPayloadStatistics::GetDescriptorCodeCost(pid, intf.desc, intf.code).totalCost);
95             result += " | Max:";
96             result += std::to_string(
97                 IPCPayloadStatistics::GetDescriptorCodeCost(pid, intf.desc, intf.code).maxCost);
98             result += " | Min:";
99             result += std::to_string(
100                 IPCPayloadStatistics::GetDescriptorCodeCost(pid, intf.desc, intf.code).minCost);
101             result += " | Avg:";
102             result += std::to_string(
103                 IPCPayloadStatistics::GetDescriptorCodeCost(pid, intf.desc, intf.code).averCost);
104             result += "\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
105         }
106         result += "\n------------------------------------------------------------------------------------";
107     }
108     result += "\n************************************************************************************\n";
109 
110     return;
111 }
112 
HdfDumpIpcStat(int32_t fd,const char * cmd)113 void HdfDumpIpcStat(int32_t fd, const char *cmd)
114 {
115     if (fd < 0) {
116         HDF_LOGE("invalid fd %{public}d", fd);
117         return;
118     }
119 
120     if (cmd == nullptr) {
121         HDF_LOGE("%{public}s cmd is null", __func__);
122         return;
123     }
124 
125     std::string result;
126     HDF_LOGI("%{public}s %{public}d", cmd, fd);
127     if (strcmp(cmd, "--start-stat") == 0) {
128         HdfDumpIpcStatStart(result);
129     } else if (strcmp(cmd, "--stop-stat") == 0) {
130         HdfDumpIpcStatStop(result);
131     } else if (strcmp(cmd, "--stat") == 0) {
132         HdfDumpIpcStatGet(result);
133     } else {
134         HDF_LOGE("%{public}s invalid param", __func__);
135         return;
136     }
137 
138     if (!OHOS::SaveStringToFd(fd, result)) {
139         HDF_LOGE("%{public}s SaveStringToFd failed", __func__);
140     }
141 
142     return;
143 }
144 
HdfRegisterDumpFunc(DevHostDumpFunc dump)145 void HdfRegisterDumpFunc(DevHostDumpFunc dump)
146 {
147     g_dump = dump;
148 }
149 
HdfDump(int32_t fd,const std::vector<std::u16string> & args)150 int32_t HdfDump(int32_t fd, const std::vector<std::u16string> &args)
151 {
152     if (g_dump == nullptr || fd < 0) {
153         HDF_LOGE("%{public}s g_dump fd:%{public}d",  __func__, fd);
154         return HDF_FAILURE;
155     }
156 
157     uint32_t argv = args.size();
158     HDF_LOGI("%{public}s argv:%{public}u", __func__, argv);
159 
160     if (argv > MAX_PARA_NUM) {
161         HDF_LOGE("%{public}s argv %{public}u is invalid",  __func__, argv);
162         return HDF_FAILURE;
163     }
164 
165     struct HdfSBuf *data = HdfSbufTypedObtain(SBUF_IPC);
166     if (data == nullptr) {
167         return HDF_FAILURE;
168     }
169 
170     int32_t ret = HDF_SUCCESS;
171     std::string result;
172     const char *value = nullptr;
173 
174     struct HdfSBuf *reply = HdfSbufTypedObtain(SBUF_IPC);
175     if (reply == nullptr) {
176         goto FINISHED;
177     }
178 
179     if (!HdfSbufWriteFileDescriptor(data, fd)) {
180         goto FINISHED;
181     }
182 
183     if (!HdfSbufWriteUint32(data, argv)) {
184         goto FINISHED;
185     }
186 
187     // Convert vector to sbuf structure
188     for (uint32_t i = 0; i < argv; i++) {
189         HDF_LOGI("%{public}s para:%{public}s", __func__, OHOS::Str16ToStr8(args.at(i)).data());
190         if (!HdfSbufWriteString(data, OHOS::Str16ToStr8(args.at(i)).data())) {
191             goto FINISHED;
192         }
193     }
194 
195     (void)g_dump(data, reply);
196 
197     value = HdfSbufReadString(reply);
198     while (value != nullptr) {
199         HDF_LOGI("%{public}s reply:%{public}s", __func__, value);
200         result.append(value);
201         value = HdfSbufReadString(reply);
202     }
203 
204     if (!OHOS::SaveStringToFd(fd, result)) {
205         ret = HDF_FAILURE;
206     }
207 
208 FINISHED:
209     HdfSbufRecycle(data);
210     HdfSbufRecycle(reply);
211     return ret;
212 }