1 /*
2 * Copyright (c) 2022 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 "napi/native_api.h"
17 #include <hidebug/hidebug.h>
18 #include <hidebug/hidebug_type.h>
19 #include <cstdlib>
20 #include "backtrace.h"
21
GetTotalMem(napi_env env,napi_callback_info info)22 static napi_value GetTotalMem(napi_env env, napi_callback_info info)
23 {
24 napi_value totalMem;
25 HiDebug_SystemMemInfo sysMemInfo;
26 OH_HiDebug_GetSystemMemInfo(&sysMemInfo);
27 napi_create_uint32(env, sysMemInfo.totalMem, &totalMem);
28 return totalMem;
29 }
30
GetFreeMem(napi_env env,napi_callback_info info)31 static napi_value GetFreeMem(napi_env env, napi_callback_info info)
32 {
33 napi_value freeMem;
34 HiDebug_SystemMemInfo sysMemInfo;
35 OH_HiDebug_GetSystemMemInfo(&sysMemInfo);
36 napi_create_uint32(env, sysMemInfo.freeMem, &freeMem);
37 return freeMem;
38 }
39
GetAvailableMem(napi_env env,napi_callback_info info)40 static napi_value GetAvailableMem(napi_env env, napi_callback_info info)
41 {
42 napi_value availableMem;
43 HiDebug_SystemMemInfo sysMemInfo;
44 OH_HiDebug_GetSystemMemInfo(&sysMemInfo);
45 napi_create_uint32(env, sysMemInfo.availableMem, &availableMem);
46 return availableMem;
47 }
48
GetPss(napi_env env,napi_callback_info info)49 static napi_value GetPss(napi_env env, napi_callback_info info)
50 {
51 napi_value pss;
52 HiDebug_NativeMemInfo nativeMemInfo;
53 OH_HiDebug_GetAppNativeMemInfo(&nativeMemInfo);
54 napi_create_uint32(env, nativeMemInfo.pss, &pss);
55 return pss;
56 }
57
GetVss(napi_env env,napi_callback_info info)58 static napi_value GetVss(napi_env env, napi_callback_info info)
59 {
60 napi_value vss;
61 HiDebug_NativeMemInfo nativeMemInfo;
62 OH_HiDebug_GetAppNativeMemInfo(&nativeMemInfo);
63 napi_create_uint32(env, nativeMemInfo.vss, &vss);
64 return vss;
65 }
66
GetRss(napi_env env,napi_callback_info info)67 static napi_value GetRss(napi_env env, napi_callback_info info)
68 {
69 napi_value rss;
70 HiDebug_NativeMemInfo nativeMemInfo;
71 OH_HiDebug_GetAppNativeMemInfo(&nativeMemInfo);
72 napi_create_uint32(env, nativeMemInfo.rss, &rss);
73 return rss;
74 }
75
GetSharedDirty(napi_env env,napi_callback_info info)76 static napi_value GetSharedDirty(napi_env env, napi_callback_info info)
77 {
78 napi_value sharedDirty;
79 HiDebug_NativeMemInfo nativeMemInfo;
80 OH_HiDebug_GetAppNativeMemInfo(&nativeMemInfo);
81 napi_create_uint32(env, nativeMemInfo.sharedDirty, &sharedDirty);
82 return sharedDirty;
83 }
84
GetPrivateDirty(napi_env env,napi_callback_info info)85 static napi_value GetPrivateDirty(napi_env env, napi_callback_info info)
86 {
87 napi_value privateDirty;
88 HiDebug_NativeMemInfo nativeMemInfo;
89 OH_HiDebug_GetAppNativeMemInfo(&nativeMemInfo);
90 napi_create_uint32(env, nativeMemInfo.privateDirty, &privateDirty);
91 return privateDirty;
92 }
93
GetSharedClean(napi_env env,napi_callback_info info)94 static napi_value GetSharedClean(napi_env env, napi_callback_info info)
95 {
96 napi_value sharedClean;
97 HiDebug_NativeMemInfo nativeMemInfo;
98 OH_HiDebug_GetAppNativeMemInfo(&nativeMemInfo);
99 napi_create_uint32(env, nativeMemInfo.sharedClean, &sharedClean);
100 return sharedClean;
101 }
102
GetPrivateClean(napi_env env,napi_callback_info info)103 static napi_value GetPrivateClean(napi_env env, napi_callback_info info)
104 {
105 napi_value privateClean;
106 HiDebug_NativeMemInfo nativeMemInfo;
107 OH_HiDebug_GetAppNativeMemInfo(&nativeMemInfo);
108 napi_create_uint32(env, nativeMemInfo.privateClean, &privateClean);
109 return privateClean;
110 }
111
GetRssLimit(napi_env env,napi_callback_info info)112 static napi_value GetRssLimit(napi_env env, napi_callback_info info)
113 {
114 napi_value rssLimit;
115 HiDebug_MemoryLimit memoryLimit;
116 OH_HiDebug_GetAppMemoryLimit(&memoryLimit);
117 napi_create_bigint_uint64(env, memoryLimit.rssLimit, &rssLimit);
118 return rssLimit;
119 }
120
GetVssLimit(napi_env env,napi_callback_info info)121 static napi_value GetVssLimit(napi_env env, napi_callback_info info)
122 {
123 napi_value vssLimit;
124 HiDebug_MemoryLimit memoryLimit;
125 OH_HiDebug_GetAppMemoryLimit(&memoryLimit);
126 napi_create_bigint_uint64(env, memoryLimit.vssLimit, &vssLimit);
127 return vssLimit;
128 }
129
GetSysCpuUsage(napi_env env,napi_callback_info info)130 static napi_value GetSysCpuUsage(napi_env env, napi_callback_info info)
131 {
132 napi_value sysCpuUsage;
133 double cpuUsage = OH_HiDebug_GetSystemCpuUsage();
134 napi_create_double(env, cpuUsage, &sysCpuUsage);
135 return sysCpuUsage;
136 }
137
GetAppThreadCpuUsage(napi_env env,napi_callback_info info)138 static napi_value GetAppThreadCpuUsage(napi_env env, napi_callback_info info)
139 {
140 napi_value res;
141 napi_create_array(env, &res);
142 size_t idx = 0;
143 HiDebug_ThreadCpuUsagePtr threadCpuUsage = OH_HiDebug_GetAppThreadCpuUsage();
144 HiDebug_ThreadCpuUsagePtr curThreadCpuUsage = threadCpuUsage;
145 while (curThreadCpuUsage != nullptr) {
146 napi_value obj = nullptr;
147 napi_create_array(env, &obj);
148 auto threadIdValue = curThreadCpuUsage->threadId;
149 auto cpuUsageValue = curThreadCpuUsage->cpuUsage;
150
151 napi_value threadId;
152 napi_create_uint32(env, threadIdValue, &threadId);
153 napi_set_named_property(env, obj, "threadId", threadId);
154
155 napi_value cpuUsage;
156 napi_create_double(env, cpuUsageValue, &cpuUsage);
157 napi_set_named_property(env, obj, "cpuUsage", cpuUsage);
158
159 napi_set_element(env, res, idx, obj);
160 idx++;
161 curThreadCpuUsage = curThreadCpuUsage->next;
162 }
163 OH_HiDebug_FreeThreadCpuUsage(&threadCpuUsage);
164 return res;
165 }
166
GetAppCpuUsage(napi_env env,napi_callback_info info)167 static napi_value GetAppCpuUsage(napi_env env, napi_callback_info info)
168 {
169 napi_value appCpuUsage;
170 double cpuUsage = OH_HiDebug_GetAppCpuUsage();
171 napi_create_double(env, cpuUsage, &appCpuUsage);
172 return appCpuUsage;
173 }
174
StartAppTraceCapture(napi_env env,napi_callback_info info)175 static napi_value StartAppTraceCapture(napi_env env, napi_callback_info info)
176 {
177 napi_value ret;
178 size_t argc = 3; // arg total:3
179 napi_value args[3] = {nullptr}; // arg total:3
180
181 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
182
183 napi_valuetype valuetype0;
184 napi_typeof(env, args[0], &valuetype0);
185 napi_valuetype valuetype1;
186 napi_typeof(env, args[1], &valuetype1);
187 napi_valuetype valuetype2;
188 napi_typeof(env, args[2], &valuetype2); // arg number:2
189
190 uint32_t flag;
191 napi_get_value_uint32(env, args[0], &flag);
192 uint64_t tags = HIDEBUG_TRACE_TAG_ARK;
193 uint32_t limitSize;
194 napi_get_value_uint32(env, args[1], &limitSize);
195 uint32_t length;
196 napi_get_value_uint32(env, args[2], &length); // arg number:2
197 char fileName[length];
198
199 HiDebug_ErrorCode errorCode = OH_HiDebug_StartAppTraceCapture(HiDebug_TraceFlag(flag),
200 tags, limitSize, fileName, length);
201 napi_create_int32(env, errorCode, &ret);
202 return ret;
203 }
204
GetAppTraceCaptureFile(napi_env env,napi_callback_info info)205 static napi_value GetAppTraceCaptureFile(napi_env env, napi_callback_info info)
206 {
207 napi_value ret;
208 size_t argc = 3; // arg total:3
209 napi_value args[3] = {nullptr}; // arg total:3
210
211 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
212
213 napi_valuetype valuetype0;
214 napi_typeof(env, args[0], &valuetype0);
215 napi_valuetype valuetype1;
216 napi_typeof(env, args[1], &valuetype1);
217 napi_valuetype valuetype2;
218 napi_typeof(env, args[2], &valuetype2); // arg number:2
219
220 uint32_t flag;
221 napi_get_value_uint32(env, args[0], &flag);
222 uint64_t tags = HIDEBUG_TRACE_TAG_ARK;
223 uint32_t limitSize;
224 napi_get_value_uint32(env, args[1], &limitSize);
225 uint32_t length;
226 napi_get_value_uint32(env, args[2], &length); // arg number:2
227 char fileName[length];
228
229 OH_HiDebug_StartAppTraceCapture(HiDebug_TraceFlag(flag), tags, limitSize, fileName, length);
230 napi_create_string_utf8(env, fileName, length, &ret);
231 return ret;
232 }
233
StartAppTraceCaptureTag(napi_env env,napi_callback_info info)234 static napi_value StartAppTraceCaptureTag(napi_env env, napi_callback_info info)
235 {
236 napi_value ret;
237
238 HiDebug_TraceFlag flag = HIDEBUG_TRACE_FLAG_MAIN_THREAD;
239 uint64_t tags = 0;
240 uint32_t limitSize = 1024 * 1024;
241 uint32_t length = 256;
242
243 char fileName[length];
244
245 HiDebug_ErrorCode errorCode = OH_HiDebug_StartAppTraceCapture(flag, tags, limitSize, fileName, length);
246 napi_create_int32(env, errorCode, &ret);
247 return ret;
248 }
249
StopAppTraceCapture(napi_env env,napi_callback_info info)250 static napi_value StopAppTraceCapture(napi_env env, napi_callback_info info)
251 {
252 napi_value ret;
253 HiDebug_ErrorCode errorCode = OH_HiDebug_StopAppTraceCapture();
254 napi_create_int32(env, errorCode, &ret);
255 return ret;
256 }
257
getGraphicsMemory(napi_env env,napi_callback_info info)258 static napi_value getGraphicsMemory(napi_env env, napi_callback_info info)
259 {
260 uint32_t value = 0;
261 napi_value sum;
262 HiDebug_ErrorCode errCode = OH_HiDebug_GetGraphicsMemory(&value);
263 napi_create_double(env, errCode, &sum);
264 return sum;
265 }
266
getGraphicsMemoryArray(napi_env env,napi_callback_info info)267 static napi_value getGraphicsMemoryArray(napi_env env, napi_callback_info info)
268 {
269 uint32_t arr[5] = {1, 2, 3, 4, 5};
270 uint32_t *value = arr;
271 napi_value sum;
272 HiDebug_ErrorCode errCode = OH_HiDebug_GetGraphicsMemory(value);
273 napi_create_double(env, errCode, &sum);
274 return sum;
275 }
276
getGraphicsMemoryNULL(napi_env env,napi_callback_info info)277 static napi_value getGraphicsMemoryNULL(napi_env env, napi_callback_info info)
278 {
279 napi_value sum;
280 HiDebug_ErrorCode errCode = OH_HiDebug_GetGraphicsMemory(NULL);
281 napi_create_double(env, errCode, &sum);
282 return sum;
283 }
284
TestNativeFrames(int i)285 __attribute((noinline)) __attribute((optnone)) void TestNativeFrames(int i)
286 {
287 if (i > 0) {
288 TestNativeFrames(i - 1);
289 return;
290 }
291 auto fp = __builtin_frame_address(0);
292 BackTraceCurrentThread();
293 }
294
GetBacktraceFromFp(napi_env env,napi_callback_info info)295 __attribute((noinline)) __attribute((optnone)) napi_value GetBacktraceFromFp(napi_env env, napi_callback_info info)
296 {
297 TestNativeFrames(1);
298 return nullptr;
299 }
300
TestNativeInvaildFrames(int i)301 __attribute((noinline)) __attribute((optnone)) void TestNativeInvaildFrames(int i)
302 {
303 if (i > 0) {
304 TestNativeFrames(i - 1);
305 return;
306 }
307 InvaildBackTraceCurrentThread();
308 }
309
GetBacktraceInvaildFromFp(napi_env env,napi_callback_info info)310 __attribute((noinline)) __attribute((optnone)) napi_value GetBacktraceInvaildFromFp(napi_env env, napi_callback_info info)
311 {
312 TestNativeFrames(1);
313 return nullptr;
314 }
315
MyMalloc(size_t size)316 static void* MyMalloc(size_t size)
317 {
318 HiDebug_MallocDispatch* original = (HiDebug_MallocDispatch*)OH_HiDebug_GetDefaultMallocDispatchTable();
319 return original->malloc(size);
320 }
321
MyFree(void * ptr)322 static void MyFree(void* ptr)
323 {
324 HiDebug_MallocDispatch* original = (HiDebug_MallocDispatch*)OH_HiDebug_GetDefaultMallocDispatchTable();
325 original->free(ptr);
326 }
327
MyMmap(void * addr,size_t len,int prot,int flags,int fd,off_t offset)328 static void* MyMmap(void* addr, size_t len, int prot, int flags, int fd, off_t offset)
329 {
330 HiDebug_MallocDispatch* original = (HiDebug_MallocDispatch*)OH_HiDebug_GetDefaultMallocDispatchTable();
331 return original->mmap(addr, len, prot, flags, fd, offset);
332 }
333
MyMunmap(void * addr,size_t len)334 static int MyMunmap(void* addr, size_t len)
335 {
336 HiDebug_MallocDispatch* original = (HiDebug_MallocDispatch*)OH_HiDebug_GetDefaultMallocDispatchTable();
337 return original->munmap(addr, len);
338 }
339
MyCalloc(size_t nmemb,size_t size)340 static void* MyCalloc(size_t nmemb, size_t size)
341 {
342 HiDebug_MallocDispatch* original = (HiDebug_MallocDispatch*)OH_HiDebug_GetDefaultMallocDispatchTable();
343 return original->calloc(nmemb, size);
344 }
345
MyRealloc(void * ptr,size_t size)346 static void* MyRealloc(void* ptr, size_t size)
347 {
348 HiDebug_MallocDispatch* original = (HiDebug_MallocDispatch*)OH_HiDebug_GetDefaultMallocDispatchTable();
349 return original->realloc(ptr, size);
350 }
351
GetDefaultMallocDispatchTable(napi_env env,napi_callback_info info)352 static napi_value GetDefaultMallocDispatchTable(napi_env env, napi_callback_info info)
353 {
354 HiDebug_MallocDispatch* original = (HiDebug_MallocDispatch*)OH_HiDebug_GetDefaultMallocDispatchTable();
355 HiDebug_MallocDispatch* current = (HiDebug_MallocDispatch*)original->malloc(sizeof(HiDebug_MallocDispatch));
356 current->malloc = MyMalloc;
357 current->free = MyFree;
358 current->mmap = MyMmap;
359 current->munmap = MyMunmap;
360 current->calloc = MyCalloc;
361 current->realloc = MyRealloc;
362 napi_value sum;
363 int initResult = OH_HiDebug_SetMallocDispatchTable(current);
364 napi_create_int32(env, initResult, &sum);
365 return sum;
366 }
367
RestoreMallocDispatchTable(napi_env env,napi_callback_info info)368 static napi_value RestoreMallocDispatchTable(napi_env env, napi_callback_info info)
369 {
370 HiDebug_MallocDispatch* original = (HiDebug_MallocDispatch*)OH_HiDebug_GetDefaultMallocDispatchTable();
371 HiDebug_MallocDispatch* current = (HiDebug_MallocDispatch*)original->malloc(sizeof(HiDebug_MallocDispatch));
372 current->malloc = MyMalloc;
373 napi_value sum;
374 int initResult = OH_HiDebug_SetMallocDispatchTable(current);
375 napi_create_int32(env, initResult, &sum);
376 OH_HiDebug_RestoreMallocDispatchTable();
377 return sum;
378 }
379
GetInvaildMallocDispatchTable(napi_env env,napi_callback_info info)380 static napi_value GetInvaildMallocDispatchTable(napi_env env, napi_callback_info info)
381 {
382 napi_value sum;
383 int initResult = OH_HiDebug_SetMallocDispatchTable(nullptr);
384 napi_create_int32(env, initResult, &sum);
385 return sum;
386 }
387
388 EXTERN_C_START
Init(napi_env env,napi_value exports)389 static napi_value Init(napi_env env, napi_value exports)
390 {
391 napi_property_descriptor desc[] = {
392 { "getTotalMem", nullptr, GetTotalMem, nullptr, nullptr, nullptr, napi_default, nullptr },
393 { "getFreeMem", nullptr, GetFreeMem, nullptr, nullptr, nullptr, napi_default, nullptr },
394 { "getAvailableMem", nullptr, GetAvailableMem, nullptr, nullptr, nullptr, napi_default, nullptr },
395 { "getPss", nullptr, GetPss, nullptr, nullptr, nullptr, napi_default, nullptr },
396 { "getVss", nullptr, GetVss, nullptr, nullptr, nullptr, napi_default, nullptr },
397 { "getRss", nullptr, GetRss, nullptr, nullptr, nullptr, napi_default, nullptr },
398 { "getSharedDirty", nullptr, GetSharedDirty, nullptr, nullptr, nullptr, napi_default, nullptr },
399 { "getPrivateDirty", nullptr, GetPrivateDirty, nullptr, nullptr, nullptr, napi_default, nullptr },
400 { "getSharedClean", nullptr, GetSharedClean, nullptr, nullptr, nullptr, napi_default, nullptr },
401 { "getPrivateClean", nullptr, GetPrivateClean, nullptr, nullptr, nullptr, napi_default, nullptr },
402 { "getRssLimit", nullptr, GetRssLimit, nullptr, nullptr, nullptr, napi_default, nullptr },
403 { "getVssLimit", nullptr, GetVssLimit, nullptr, nullptr, nullptr, napi_default, nullptr },
404 { "getSysCpuUsage", nullptr, GetSysCpuUsage, nullptr, nullptr, nullptr, napi_default, nullptr },
405 { "getAppThreadCpuUsage", nullptr, GetAppThreadCpuUsage, nullptr, nullptr, nullptr, napi_default, nullptr },
406 { "getAppCpuUsage", nullptr, GetAppCpuUsage, nullptr, nullptr, nullptr, napi_default, nullptr },
407 { "startAppTraceCapture", nullptr, StartAppTraceCapture, nullptr, nullptr, nullptr, napi_default, nullptr },
408 { "getAppTraceCaptureFile", nullptr, GetAppTraceCaptureFile, nullptr, nullptr, nullptr, napi_default, nullptr },
409 { "startAppTraceCaptureTag", nullptr,
410 StartAppTraceCaptureTag, nullptr, nullptr, nullptr, napi_default, nullptr },
411 { "stopAppTraceCapture", nullptr, StopAppTraceCapture, nullptr, nullptr, nullptr, napi_default, nullptr },
412 { "getGraphicsMemory", nullptr, getGraphicsMemory, nullptr, nullptr, nullptr, napi_default, nullptr},
413 { "getGraphicsMemoryNULL", nullptr, getGraphicsMemoryNULL, nullptr, nullptr, nullptr, napi_default, nullptr },
414 { "getGraphicsMemoryArray", nullptr, getGraphicsMemoryArray, nullptr, nullptr, nullptr, napi_default, nullptr },
415 { "getBacktraceFromFp", nullptr, GetBacktraceFromFp, nullptr, nullptr, nullptr, napi_default, nullptr },
416 { "getBacktraceInvaildFromFp", nullptr, GetBacktraceInvaildFromFp, nullptr, nullptr, nullptr, napi_default, nullptr },
417 { "getDefaultMallocDispatchTable", nullptr, GetDefaultMallocDispatchTable, nullptr, nullptr, nullptr, napi_default, nullptr },
418 { "restoreMallocDispatchTable", nullptr, RestoreMallocDispatchTable, nullptr, nullptr, nullptr, napi_default, nullptr },
419 { "getInvaildMallocDispatchTable", nullptr, GetInvaildMallocDispatchTable, nullptr, nullptr, nullptr, napi_default, nullptr },
420 };
421 napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
422 return exports;
423 }
424 EXTERN_C_END
425
426 static napi_module demoModule = {
427 .nm_version = 1,
428 .nm_flags = 0,
429 .nm_filename = nullptr,
430 .nm_register_func = Init,
431 .nm_modname = "hidebug",
432 .nm_priv = ((void*)0),
433 .reserved = { 0 },
434 };
435
RegisterEntryModule(void)436 extern "C" __attribute__((constructor)) void RegisterEntryModule(void)
437 {
438 napi_module_register(&demoModule);
439 }
440