• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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