• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 "hidebug_ffi.h"
17 
18 #include <numeric>
19 #include <sys/types.h>
20 #include <sys/stat.h>
21 #include <fcntl.h>
22 #include <memory>
23 #include <unistd.h>
24 #include <malloc.h>
25 #include <codecvt>
26 #include <string>
27 #include <vector>
28 #include <parameters.h>
29 
30 #include "file_ex.h"
31 #include "directory_ex.h"
32 #include "hidebug_native_interface.h"
33 #include "hilog/log.h"
34 #include "hidebug_util.h"
35 #include "system_ability_definition.h"
36 #include "iservice_registry.h"
37 
38 namespace OHOS::HiviewDFX {
39 
40 #undef LOG_DOMAIN
41 #define LOG_DOMAIN 0xD002D0A
42 #undef LOG_TAG
43 #define LOG_TAG "CJ_HiDebug"
44 
45 constexpr auto KEY_HIVIEW_USER_TYPE = "const.logsystem.versiontype";
46 constexpr auto KEY_HIVIEW_DEVELOP_TYPE = "persist.hiview.leak_detector";
47 
48 enum ErrorCode {
49     MEM_ERROR = 1,
50     PERMISSION_ERROR = 201,
51     PARAMETER_ERROR = 401,
52     VERSION_ERROR = 801,
53     SYSTEM_ABILITY_NOT_FOUND = 11400101,
54     HAVA_ALREADY_TRACE = 11400102,
55     WITHOUT_WRITE_PERMISSON = 11400103,
56     SYSTEM_STATUS_ABNORMAL = 11400104,
57     NO_CAPTURE_TRACE_RUNNING = 11400105,
58 };
59 
60 extern "C" {
FfiHidebugGetPss()61     uint64_t FfiHidebugGetPss()
62     {
63         auto natveMemInfoOption = HidebugNativeInterface::GetInstance().GetAppNativeMemInfo(false);
64         return natveMemInfoOption ? static_cast<uint64_t>(natveMemInfoOption->pss) : 0;
65     }
66 
FfiHidebugGetVss()67     uint64_t FfiHidebugGetVss()
68     {
69         auto vssOption = HidebugNativeInterface::GetInstance().GetVss();
70         return vssOption ? vssOption.value() : 0;
71     }
72 
FfiHidebugGetNativeHeapSize()73     uint64_t FfiHidebugGetNativeHeapSize()
74     {
75         struct mallinfo mi = mallinfo();
76         return static_cast<uint64_t>(mi.uordblks + mi.fordblks);
77     }
78 
FfiHidebugGetNativeHeapAllocatedSize()79     uint64_t FfiHidebugGetNativeHeapAllocatedSize()
80     {
81         struct mallinfo mi = mallinfo();
82         return static_cast<uint64_t>(mi.uordblks);
83     }
84 
FfiHidebugGetNativeHeapFreeSize()85     uint64_t FfiHidebugGetNativeHeapFreeSize()
86     {
87         struct mallinfo mi = mallinfo();
88         return static_cast<uint64_t>(mi.fordblks);
89     }
90 
FfiHidebugGetSharedDirty()91     uint64_t FfiHidebugGetSharedDirty()
92     {
93         auto nativeMemInfoOption = HidebugNativeInterface::GetInstance().GetAppNativeMemInfo(false);
94         return nativeMemInfoOption ? static_cast<uint64_t>(nativeMemInfoOption->sharedDirty) : 0;
95     }
96 
FfiHidebugGetPrivateDirty()97     uint64_t FfiHidebugGetPrivateDirty()
98     {
99         auto nativeMemInfoOption = HidebugNativeInterface::GetInstance().GetAppNativeMemInfo(false);
100         return nativeMemInfoOption ? static_cast<uint64_t>(nativeMemInfoOption->privateDirty) : 0;
101     }
102 
FfiHidebugGetCpuUsage()103     double FfiHidebugGetCpuUsage()
104     {
105         return HidebugNativeInterface::GetInstance().GetCpuUsage();
106     }
107 
FfiHidebugGetSystemCpuUsage(int32_t & code)108     double FfiHidebugGetSystemCpuUsage(int32_t &code)
109     {
110         auto cpuUsageOptional = HidebugNativeInterface::GetInstance().GetSystemCpuUsage();
111         if (cpuUsageOptional.has_value()) {
112             return cpuUsageOptional.value();
113         }
114         code = ErrorCode::SYSTEM_STATUS_ABNORMAL;
115         return 0;
116     }
117 
FfiHidebugGetAppThreadCpuUsage(int32_t & code)118     ThreadCpuUsageArr FfiHidebugGetAppThreadCpuUsage(int32_t &code)
119     {
120         ThreadCpuUsageArr arr{ .head = nullptr, .size = 0};
121         std::map<uint32_t, double> threadMap = HidebugNativeInterface::GetInstance().GetAppThreadCpuUsage();
122         auto size = threadMap.size();
123         if (size <= 0) {
124             return arr;
125         }
126         arr.head = static_cast<CThreadCpuUsage *>(malloc(sizeof(CThreadCpuUsage) * size));
127         if (arr.head == nullptr) {
128             code = ErrorCode::MEM_ERROR;
129             return arr;
130         }
131         size_t idx = 0;
132         for (const auto[id, usage] : threadMap) {
133             arr.head[idx] = CThreadCpuUsage{ .threadId = id, .cpuUsage = usage };
134             idx++;
135         }
136         arr.size = static_cast<int64_t>(idx);
137         return arr;
138     }
139 
FfiHidebugGetSystemMemInfo(int32_t & code)140     CSystemMemInfo FfiHidebugGetSystemMemInfo(int32_t &code)
141     {
142         CSystemMemInfo info{.totalMem = 0, .freeMem = 0, .availableMem = 0};
143         auto systemMemInfo = HidebugNativeInterface::GetInstance().GetSystemMemInfo();
144         if (!systemMemInfo) {
145             code = ErrorCode::MEM_ERROR;
146             return info;
147         }
148         info.totalMem = static_cast<uint64_t>(systemMemInfo->totalMem);
149         info.freeMem = static_cast<uint64_t>(systemMemInfo->freeMem);
150         info.availableMem = static_cast<uint64_t>(systemMemInfo->availableMem);
151         return info;
152     }
153 
FfiHidebugGetAppNativeMemInfo(int32_t & code)154     CNativeMemInfo FfiHidebugGetAppNativeMemInfo(int32_t &code)
155     {
156         CNativeMemInfo info{};
157         auto nativeMemInfo = HidebugNativeInterface::GetInstance().GetAppNativeMemInfo();
158         if (!nativeMemInfo) {
159             code = ErrorCode::MEM_ERROR;
160             return info;
161         }
162         info.pss = nativeMemInfo->pss;
163         info.vss = nativeMemInfo->vss;
164         info.rss = nativeMemInfo->rss;
165         info.sharedDirty = nativeMemInfo->sharedDirty;
166         info.privateDirty = nativeMemInfo->privateDirty;
167         info.sharedClean = nativeMemInfo->sharedClean;
168         info.privateClean = nativeMemInfo->privateClean;
169         return info;
170     }
171 
FfiHidebugGetAppMemoryLimit(int32_t & code)172     CMemoryLimit FfiHidebugGetAppMemoryLimit(int32_t &code)
173     {
174         CMemoryLimit limit{.rssLimit = 0, .vssLimit = 0};
175         auto memoryLimit = HidebugNativeInterface::GetInstance().GetAppMemoryLimit();
176         if (!memoryLimit) {
177             code = ErrorCode::MEM_ERROR;
178             return limit;
179         }
180         limit.rssLimit = memoryLimit->rssLimit;
181         limit.vssLimit = memoryLimit->vssLimit;
182         return limit;
183     }
184 
FfiHidebugGetServiceDump(int32_t serviceId,int32_t fd,CArrString args)185     int32_t FfiHidebugGetServiceDump(int32_t serviceId, int32_t fd, CArrString args)
186     {
187         sptr<ISystemAbilityManager> sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
188         if (!sam) {
189             return ErrorCode::MEM_ERROR;
190         }
191         sptr<IRemoteObject> sa = sam->CheckSystemAbility(serviceId);
192         if (sa == nullptr) {
193             return ErrorCode::SYSTEM_ABILITY_NOT_FOUND;
194         }
195         std::vector<std::u16string> cargs;
196         std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> strCnv;
197         for (int64_t i = 0; i < args.size; i++) {
198             cargs.push_back(strCnv.from_bytes(args.head[i]));
199         }
200         int dumpResult = sa->Dump(fd, cargs);
201         HILOG_INFO(LOG_CORE, "Dump result: %{public}d", dumpResult);
202         return 0;
203     }
204 
FfiHidebugStartAppTraceCapture(CArrUnit tags,int32_t flag,uint32_t limitSize,int32_t & code)205     char *FfiHidebugStartAppTraceCapture(CArrUnit tags, int32_t flag, uint32_t limitSize, int32_t &code)
206     {
207         std::vector<uint64_t> taglist;
208         uint64_t *tagPtr = static_cast<uint64_t *>(tags.head);
209         for (int64_t i = 0; i < tags.size; i++) {
210             taglist.push_back(tagPtr[i]);
211         }
212         uint64_t tag = std::accumulate(taglist.begin(), taglist.end(), 0ull,
213             [](uint64_t a, uint64_t b) { return a | b; });
214         std::string file;
215         code = HidebugNativeInterface::GetInstance().StartAppTraceCapture(tag, flag, limitSize, file);
216         if (code != TRACE_SUCCESS || file.empty()) {
217             return nullptr;
218         }
219         auto len = file.length() + 1;
220         char *res = static_cast<char *>(malloc(sizeof(char) * len));
221         if (res == nullptr) {
222             return nullptr;
223         }
224         return std::char_traits<char>::copy(res, file.c_str(), len);
225     }
226 
FfiHidebugStopAppTraceCapture()227     int32_t FfiHidebugStopAppTraceCapture()
228     {
229         return HidebugNativeInterface::GetInstance().StopAppTraceCapture();
230     }
231 
FfiHidebugSetAppResourceLimit(const char * type,int32_t value,bool enableDebugLog)232     int32_t FfiHidebugSetAppResourceLimit(const char *type, int32_t value, bool enableDebugLog)
233     {
234         if (!CheckVersionType("beta", KEY_HIVIEW_USER_TYPE) &&
235             !CheckVersionType("enable", KEY_HIVIEW_DEVELOP_TYPE)) {
236             HILOG_ERROR(LOG_CORE, "SetAppResourceLimit failed. Not developer options or beta versions");
237             return ErrorCode::VERSION_ERROR;
238         }
239         auto abilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
240         if (!abilityManager) {
241             return ErrorCode::MEM_ERROR;
242         }
243         sptr<IRemoteObject> remoteObject = abilityManager->CheckSystemAbility(DFX_SYS_HIVIEW_ABILITY_ID);
244         if (remoteObject == nullptr) {
245             HILOG_ERROR(LOG_CORE, "SetAppResourceLimit failed. No this system ability.");
246             return ErrorCode::SYSTEM_STATUS_ABNORMAL;
247         }
248         if (HidebugNativeInterface::GetInstance().GetMemoryLeakResource(std::string(type), value, enableDebugLog)
249             == NATIVE_SUCCESS) {
250             CreateResourceLimitDir();
251         }
252         return 0;
253     }
254 
FfiHidebugIsDebugState()255     bool FfiHidebugIsDebugState()
256     {
257         return HidebugNativeInterface::GetInstance().IsDebuggerConnected();
258     }
259 }
260 }
261