• 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/hidebug.h"
17 
18 #include <memory>
19 #include <string>
20 
21 #include "hidebug/hidebug_type.h"
22 #include "hidebug_native_interface.h"
23 #include "securec.h"
24 #ifdef HOOK_ENABLE
25 #include "musl_preinit_common.h"
26 static volatile struct MallocDispatchType *g_lastDispatchTable = nullptr;
27 static struct HiDebug_MallocDispatch g_defaultDispatchDatable = {
28     .malloc = __libc_malloc_default_dispatch.malloc,
29     .calloc = __libc_malloc_default_dispatch.calloc,
30     .realloc = __libc_malloc_default_dispatch.realloc,
31     .free = __libc_malloc_default_dispatch.free,
32     .mmap = __libc_malloc_default_dispatch.mmap,
33     .munmap = __libc_malloc_default_dispatch.munmap,
34 };
35 static struct MallocDispatchType g_currentDispatchDatable = __libc_malloc_default_dispatch;
36 #endif
OH_HiDebug_GetAppCpuUsage()37 double OH_HiDebug_GetAppCpuUsage()
38 {
39     return OHOS::HiviewDFX::HidebugNativeInterface::GetInstance().GetCpuUsage();
40 }
41 
OH_HiDebug_GetSystemCpuUsage()42 double OH_HiDebug_GetSystemCpuUsage()
43 {
44     auto cpuUsageOptional = OHOS::HiviewDFX::HidebugNativeInterface::GetInstance().GetSystemCpuUsage();
45     if (cpuUsageOptional) {
46         return cpuUsageOptional.value();
47     }
48     return 0;
49 }
50 
OH_HiDebug_GetAppThreadCpuUsage()51 HiDebug_ThreadCpuUsagePtr OH_HiDebug_GetAppThreadCpuUsage()
52 {
53     auto threadMap = OHOS::HiviewDFX::HidebugNativeInterface::GetInstance().GetAppThreadCpuUsage();
54     HiDebug_ThreadCpuUsagePtr head = nullptr;
55     HiDebug_ThreadCpuUsagePtr prev = nullptr;
56     for (const auto[threadId, cpuUsage] : threadMap) {
57         HiDebug_ThreadCpuUsagePtr node = (HiDebug_ThreadCpuUsagePtr) malloc(sizeof(HiDebug_ThreadCpuUsage));
58         if (node == nullptr) {
59             continue;
60         }
61         node->threadId = threadId;
62         node->cpuUsage = cpuUsage;
63         node->next = nullptr;
64         if (prev == nullptr) {
65             head = node;
66         } else {
67             prev->next = node;
68         }
69         prev = node;
70     }
71     return head;
72 }
73 
OH_HiDebug_FreeThreadCpuUsage(HiDebug_ThreadCpuUsagePtr * threadCpuUsage)74 void OH_HiDebug_FreeThreadCpuUsage(HiDebug_ThreadCpuUsagePtr *threadCpuUsage)
75 {
76     if (threadCpuUsage == nullptr || *threadCpuUsage == nullptr) {
77         return;
78     }
79     HiDebug_ThreadCpuUsagePtr node = *threadCpuUsage;
80     while (node != nullptr) {
81         HiDebug_ThreadCpuUsagePtr next = node->next;
82         free(node);
83         node = next;
84     }
85     *threadCpuUsage = nullptr;
86 }
87 
OH_HiDebug_GetAppMemoryLimit(HiDebug_MemoryLimit * memoryLimit)88 void OH_HiDebug_GetAppMemoryLimit(HiDebug_MemoryLimit *memoryLimit)
89 {
90     if (!memoryLimit) {
91         return;
92     }
93     auto memoryLimitOption = OHOS::HiviewDFX::HidebugNativeInterface::GetInstance().GetAppMemoryLimit();
94     if (memoryLimitOption) {
95         memoryLimit->vssLimit = memoryLimitOption->vssLimit;
96         memoryLimit->rssLimit = memoryLimitOption->rssLimit;
97     }
98 }
99 
OH_HiDebug_GetAppNativeMemInfoWithCache(HiDebug_NativeMemInfo * nativeMemInfo,bool forceRefresh)100 void OH_HiDebug_GetAppNativeMemInfoWithCache(HiDebug_NativeMemInfo *nativeMemInfo, bool forceRefresh)
101 {
102     if (!nativeMemInfo) {
103         return;
104     }
105     auto memInfoOption = OHOS::HiviewDFX::HidebugNativeInterface::GetInstance().GetAppNativeMemInfo(!forceRefresh);
106     if (memInfoOption) {
107         nativeMemInfo->pss = memInfoOption->pss;
108         nativeMemInfo->rss = memInfoOption->rss;
109         nativeMemInfo->sharedDirty = memInfoOption->sharedDirty;
110         nativeMemInfo->privateDirty = memInfoOption->privateDirty;
111         nativeMemInfo->sharedClean = memInfoOption->sharedClean;
112         nativeMemInfo->privateClean = memInfoOption->privateClean;
113         nativeMemInfo->vss = memInfoOption->vss;
114     }
115 }
116 
OH_HiDebug_GetAppNativeMemInfo(HiDebug_NativeMemInfo * nativeMemInfo)117 void OH_HiDebug_GetAppNativeMemInfo(HiDebug_NativeMemInfo *nativeMemInfo)
118 {
119     OH_HiDebug_GetAppNativeMemInfoWithCache(nativeMemInfo, true);
120 }
121 
OH_HiDebug_GetSystemMemInfo(HiDebug_SystemMemInfo * systemMemInfo)122 void OH_HiDebug_GetSystemMemInfo(HiDebug_SystemMemInfo *systemMemInfo)
123 {
124     if (!systemMemInfo) {
125         return;
126     }
127     auto sysMemInfo = OHOS::HiviewDFX::HidebugNativeInterface::GetInstance().GetSystemMemInfo();
128     if (sysMemInfo) {
129         systemMemInfo->totalMem = sysMemInfo->totalMem;
130         systemMemInfo->freeMem = sysMemInfo->freeMem;
131         systemMemInfo->availableMem = sysMemInfo->availableMem;
132     }
133 }
134 
ConvertTraceErrorCode(OHOS::HiviewDFX::TraceErrorCode traceErrorCode)135 HiDebug_ErrorCode ConvertTraceErrorCode(OHOS::HiviewDFX::TraceErrorCode traceErrorCode)
136 {
137     switch (traceErrorCode) {
138         case OHOS::HiviewDFX::TRACE_SUCCESS:
139             return HIDEBUG_SUCCESS;
140         case OHOS::HiviewDFX::TRACE_INVALID_ARGUMENT:
141             return HIDEBUG_INVALID_ARGUMENT;
142         case OHOS::HiviewDFX::TRACE_CAPTURED_ALREADY:
143             return HIDEBUG_TRACE_CAPTURED_ALREADY;
144         case OHOS::HiviewDFX::TRACE_NO_PERMISSION:
145             return HIDEBUG_NO_PERMISSION;
146         case OHOS::HiviewDFX::NO_TRACE_RUNNING:
147             return HIDEBUG_NO_TRACE_RUNNING;
148         default:
149             return HIDEBUG_TRACE_ABNORMAL;
150     }
151 }
152 
OH_HiDebug_StartAppTraceCapture(HiDebug_TraceFlag flag,uint64_t tags,uint32_t limitSize,char * fileName,uint32_t length)153 HiDebug_ErrorCode OH_HiDebug_StartAppTraceCapture(HiDebug_TraceFlag flag,
154     uint64_t tags, uint32_t limitSize, char* fileName, uint32_t length)
155 {
156     if (fileName == nullptr) {
157         return HIDEBUG_INVALID_ARGUMENT;
158     }
159     auto& nativeInterface = OHOS::HiviewDFX::HidebugNativeInterface::GetInstance();
160     std::string file;
161     auto ret = nativeInterface.StartAppTraceCapture(tags, flag, limitSize, file);
162     if (ret != OHOS::HiviewDFX::TRACE_SUCCESS) {
163         return ConvertTraceErrorCode(ret);
164     }
165     if (strcpy_s(fileName, length, file.c_str()) != EOK) {
166         nativeInterface.StopAppTraceCapture();
167         return HIDEBUG_INVALID_ARGUMENT;
168     }
169     return HIDEBUG_SUCCESS;
170 }
171 
OH_HiDebug_StopAppTraceCapture()172 HiDebug_ErrorCode OH_HiDebug_StopAppTraceCapture()
173 {
174     return ConvertTraceErrorCode(OHOS::HiviewDFX::HidebugNativeInterface::GetInstance().StopAppTraceCapture());
175 }
176 
OH_HiDebug_GetGraphicsMemory(uint32_t * value)177 HiDebug_ErrorCode OH_HiDebug_GetGraphicsMemory(uint32_t *value)
178 {
179     if (value == nullptr) {
180         return HIDEBUG_INVALID_ARGUMENT;
181     }
182     std::optional<int32_t> ret = OHOS::HiviewDFX::HidebugNativeInterface::GetInstance().GetGraphicsMemory();
183     if (!ret || ret < 0) {
184         return HIDEBUG_TRACE_ABNORMAL;
185     }
186     *value = static_cast<uint32_t>(ret.value());
187     return HIDEBUG_SUCCESS;
188 }
189 
OH_HiDebug_SetMallocDispatchTable(struct HiDebug_MallocDispatch * newDispatchTable)190 HiDebug_ErrorCode OH_HiDebug_SetMallocDispatchTable(struct HiDebug_MallocDispatch *newDispatchTable)
191 {
192 #ifdef HOOK_ENABLE
193     if (newDispatchTable == nullptr) {
194         return HIDEBUG_INVALID_ARGUMENT;
195     }
196     volatile struct MallocDispatchType *lastDispatchTable = (struct MallocDispatchType *)atomic_load_explicit(
197         &__musl_libc_globals.current_dispatch_table, memory_order_acquire);
198     if (lastDispatchTable != nullptr) {
199         g_lastDispatchTable = lastDispatchTable;
200     }
201     if (newDispatchTable->malloc != nullptr) {
202         g_currentDispatchDatable.malloc = newDispatchTable->malloc;
203     }
204     if (newDispatchTable->free != nullptr) {
205         g_currentDispatchDatable.free = newDispatchTable->free;
206     }
207     if (newDispatchTable->mmap != nullptr) {
208         g_currentDispatchDatable.mmap = newDispatchTable->mmap;
209     }
210     if (newDispatchTable->munmap != nullptr) {
211         g_currentDispatchDatable.munmap = newDispatchTable->munmap;
212     }
213     if (newDispatchTable->calloc != nullptr) {
214         g_currentDispatchDatable.calloc = newDispatchTable->calloc;
215     }
216     if (newDispatchTable->realloc != nullptr) {
217         g_currentDispatchDatable.realloc = newDispatchTable->realloc;
218     }
219     atomic_store_explicit(&__custom_hook_flag, (volatile bool)true, memory_order_seq_cst);
220     atomic_exchange_explicit(&__musl_libc_globals.current_dispatch_table,
221                              (volatile const long long)&g_currentDispatchDatable, memory_order_acq_rel);
222     return HIDEBUG_SUCCESS;
223 #else
224     return HIDEBUG_INVALID_ARGUMENT;
225 #endif
226 }
227 
OH_HiDebug_GetDefaultMallocDispatchTable(void)228 HiDebug_MallocDispatch* OH_HiDebug_GetDefaultMallocDispatchTable(void)
229 {
230 #ifdef HOOK_ENABLE
231     return &g_defaultDispatchDatable;
232 #else
233     return nullptr;
234 #endif
235 }
236 
OH_HiDebug_RestoreMallocDispatchTable(void)237 void OH_HiDebug_RestoreMallocDispatchTable(void)
238 {
239 #ifdef HOOK_ENABLE
240     atomic_store_explicit(&__custom_hook_flag, (volatile bool)false, memory_order_seq_cst);
241     atomic_store_explicit(&__musl_libc_globals.current_dispatch_table, (volatile const long long)g_lastDispatchTable,
242                           memory_order_seq_cst);
243     g_currentDispatchDatable = __libc_malloc_default_dispatch;
244     g_lastDispatchTable = nullptr;
245 #endif
246 }