• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved.
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 <algorithm>
17 #include <cerrno>
18 #include <codecvt>
19 #include <fstream>
20 #include <string>
21 #include <memory>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <fcntl.h>
25 #include <malloc.h>
26 #include <parameters.h>
27 #include <unistd.h>
28 
29 #include "application_context.h"
30 #include "context.h"
31 #include "cpu_collector.h"
32 #include "directory_ex.h"
33 #include "dump_usage.h"
34 #include "file_ex.h"
35 #include "hiappevent_util.h"
36 #include "hidebug_native_interface.h"
37 #include "hidebug_util.h"
38 #include "hilog/log.h"
39 #include "iservice_registry.h"
40 #include "memory_collector.h"
41 #include "napi_hidebug_dump.h"
42 #include "napi_hidebug_init.h"
43 #include "napi/native_api.h"
44 #include "napi/native_node_api.h"
45 #include "native_engine/native_engine.h"
46 #include "refbase.h"
47 #include "storage_acl.h"
48 #include "system_ability_definition.h"
49 #include "napi_hidebug_gc.h"
50 #include "napi_util.h"
51 #include "error_code.h"
52 
53 namespace OHOS {
54 namespace HiviewDFX {
55 namespace {
56 #undef LOG_DOMAIN
57 #define LOG_DOMAIN 0xD002D0A
58 #undef LOG_TAG
59 #define LOG_TAG "HiDebug_NAPI"
60 constexpr int ONE_VALUE_LIMIT = 1;
61 constexpr int ARRAY_INDEX_FIRST = 0;
62 constexpr int ARRAY_INDEX_SECOND = 1;
63 constexpr int REMOVE_NAPI_WRAP_PARAM_COUNT = 2;
64 constexpr int NAME_LEN = 128;
65 constexpr int BYTE_2_KB_SHIFT_BITS = 10;
66 constexpr int FIRST_POS = 0;
67 constexpr int SECOND_POS = 1;
68 constexpr int THIRD_POS = 2;
69 constexpr int PSS_MIN = 1024;
70 constexpr int PSS_MAX = 4 * 1024 * 1024;
71 constexpr int JS_MIN = 85;
72 constexpr int JS_MAX = 95;
73 constexpr int FD_MIN = 10;
74 constexpr int FD_MAX = 10000;
75 constexpr int THREAD_MIN = 1;
76 constexpr int THREAD_MAX = 1000;
77 const std::string SLASH_STR = "/";
78 const std::string JSON_FILE = ".json";
79 const std::string KEY_HIVIEW_DEVELOP_TYPE = "persist.hiview.leak_detector";
80 
81 const std::unordered_set<std::string> RESOURCE_TYPE_LIST{
82     "pss_memory",
83     "js_heap",
84     "fd",
85     "thread"
86 };
87 static std::map<std::string, std::pair<int, int>> limitResource = {
88     {{"pss_memory", {PSS_MIN, PSS_MAX}}, {"js_heap", {JS_MIN, JS_MAX}},
89         {"fd", {FD_MIN, FD_MAX}}, {"thread", {THREAD_MIN, THREAD_MAX}}}
90 };
91 }
92 
IsArrayForNapiValue(napi_env env,napi_value param,uint32_t & arraySize)93 static bool IsArrayForNapiValue(napi_env env, napi_value param, uint32_t &arraySize)
94 {
95     bool isArray = false;
96     arraySize = 0;
97     if (napi_is_array(env, param, &isArray) != napi_ok || isArray == false) {
98         return false;
99     }
100     if (napi_get_array_length(env, param, &arraySize) != napi_ok) {
101         return false;
102     }
103     return true;
104 }
105 
GetDumpParam(napi_env env,napi_callback_info info,int & serviceId,int & fd,std::vector<std::u16string> & args)106 static bool GetDumpParam(napi_env env, napi_callback_info info,
107     int& serviceId, int& fd, std::vector<std::u16string>& args)
108 {
109     const int valueNum = 3;
110     size_t argc = valueNum;
111     napi_value argv[valueNum] = {nullptr};
112     napi_value thisVar = nullptr;
113     void *data = nullptr;
114     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
115     if (argc != valueNum) {
116         HILOG_ERROR(LOG_CORE, "invalid number = %{public}d of params.", ONE_VALUE_LIMIT);
117         return false;
118     }
119     int thirdPos = 2;
120     if (!MatchValueType(env, argv[0], napi_number) &&
121         !MatchValueType(env, argv[1], napi_number) &&
122         !MatchValueType(env, argv[thirdPos], napi_object)) {
123         HILOG_ERROR(LOG_CORE, "params type error.");
124         return false;
125     }
126     if (napi_get_value_int32(env, argv[0], &serviceId) != napi_ok) {
127         HILOG_ERROR(LOG_CORE, "Get input serviceId failed.");
128         return false;
129     }
130     if (napi_get_value_int32(env, argv[1], &fd) != napi_ok) {
131         HILOG_ERROR(LOG_CORE, "Get input fd failed.");
132         return false;
133     }
134     uint32_t arraySize = 0;
135     if (!IsArrayForNapiValue(env, argv[thirdPos], arraySize)) {
136         HILOG_ERROR(LOG_CORE, "Get input args failed.");
137         return false;
138     }
139     for (uint32_t i = 0; i < arraySize; i++) {
140         napi_value jsValue = nullptr;
141         if (napi_get_element(env, argv[thirdPos], i, &jsValue) != napi_ok) {
142             HILOG_ERROR(LOG_CORE, "get_element -> Get input args failed.");
143             return false;
144         }
145         const size_t bufSize = 256;
146         size_t bufLen = 0;
147         char buf[bufSize] = {0};
148         if (napi_get_value_string_utf8(env, jsValue, buf, bufSize - 1, &bufLen) != napi_ok) {
149             HILOG_ERROR(LOG_CORE, "get_value -> Get input args failed.");
150             return false;
151         }
152         std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> strCnv;
153         args.push_back(strCnv.from_bytes(buf));
154     }
155     return true;
156 }
157 
GetTraceParam(napi_env env,napi_callback_info info,uint32_t & traceFlag,uint32_t & limitSize,std::vector<uint64_t> & tags)158 static bool GetTraceParam(napi_env env, napi_callback_info info,
159     uint32_t& traceFlag, uint32_t& limitSize, std::vector<uint64_t>& tags)
160 {
161     const int valueNum = 3;
162     size_t argc = valueNum;
163     napi_value argv[valueNum] = {nullptr};
164     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
165     if (argc != valueNum) {
166         HILOG_ERROR(LOG_CORE, "invalid numbers of params!");
167         return false;
168     }
169     if (!MatchValueType(env, argv[FIRST_POS], napi_object) &&
170         !MatchValueType(env, argv[SECOND_POS], napi_number) &&
171         !MatchValueType(env, argv[THIRD_POS], napi_number)) {
172         HILOG_ERROR(LOG_CORE, "params type error.");
173         return false;
174     }
175     uint32_t arraySize = 0;
176     if (!IsArrayForNapiValue(env, argv[FIRST_POS], arraySize)) {
177         HILOG_ERROR(LOG_CORE, "Get input tags failed.");
178         return false;
179     }
180     uint64_t tag = 0;
181     bool lossless = true;
182     for (uint32_t i = 0; i < arraySize; ++i) {
183         napi_value jsValue = nullptr;
184         if (napi_get_element(env, argv[FIRST_POS], i, &jsValue) != napi_ok) {
185             HILOG_ERROR(LOG_CORE, "get_element -> Get input tags failed.");
186             return false;
187         }
188         if (napi_get_value_bigint_uint64(env, jsValue, &tag, &lossless) != napi_ok) {
189             HILOG_ERROR(LOG_CORE, "Get input tags failed.");
190             return false;
191         }
192         tags.push_back(tag);
193     }
194     if (napi_get_value_uint32(env, argv[SECOND_POS], &traceFlag) != napi_ok) {
195         HILOG_ERROR(LOG_CORE, "Get input traceFlag failed.");
196         return false;
197     }
198     if (napi_get_value_uint32(env, argv[THIRD_POS], &limitSize) != napi_ok) {
199         HILOG_ERROR(LOG_CORE, "Get input limitSize failed.");
200         return false;
201     }
202     return true;
203 }
204 
StartProfiling(napi_env env,napi_callback_info info)205 napi_value StartProfiling(napi_env env, napi_callback_info info)
206 {
207     ApiInvokeRecorder apiInvokeRecorder("startProfiling");
208     std::string fileName = GetFileNameParam(env, info);
209     auto context = OHOS::AbilityRuntime::Context::GetApplicationContext();
210     if (context == nullptr) {
211         apiInvokeRecorder.SetErrorCode(ErrorCode::SYSTEM_STATUS_ABNORMAL);
212         return CreateErrorMessage(env, "Get ApplicationContext failed.");
213     }
214     std::string filesDir = context->GetFilesDir();
215     if (filesDir.empty()) {
216         apiInvokeRecorder.SetErrorCode(ErrorCode::SYSTEM_STATUS_ABNORMAL);
217         return CreateErrorMessage(env, "Get App files dir failed.");
218     }
219     std::string filePath = filesDir + SLASH_STR + fileName + JSON_FILE;
220     if (!IsLegalPath(filePath)) {
221         apiInvokeRecorder.SetErrorCode(ErrorCode::SYSTEM_STATUS_ABNORMAL);
222         return CreateErrorMessage(env, "input fileName is illegal.");
223     }
224     if (!CreateFile(filePath)) {
225         apiInvokeRecorder.SetErrorCode(ErrorCode::SYSTEM_STATUS_ABNORMAL);
226         return CreateErrorMessage(env, "file created failed.");
227     }
228     NativeEngine *engine = reinterpret_cast<NativeEngine*>(env);
229     engine->StartCpuProfiler(filePath);
230     return CreateUndefined(env);
231 }
232 
StartJsCpuProfiling(napi_env env,napi_callback_info info)233 napi_value StartJsCpuProfiling(napi_env env, napi_callback_info info)
234 {
235     ApiInvokeRecorder apiInvokeRecorder("startJsCpuProfiling");
236     std::string fileName;
237     if (!GetTheOnlyStringParam(env, info, fileName)) {
238         apiInvokeRecorder.SetErrorCode(ErrorCode::PARAMETER_ERROR);
239         std::string paramErrorMessage = "Invalid parameter, require a string parameter.";
240         napi_throw_error(env, std::to_string(ErrorCode::PARAMETER_ERROR).c_str(), paramErrorMessage.c_str());
241         return CreateUndefined(env);
242     }
243     HILOG_INFO(LOG_CORE, "filename: %{public}s.", fileName.c_str());
244     auto context = OHOS::AbilityRuntime::Context::GetApplicationContext();
245     if (context == nullptr) {
246         apiInvokeRecorder.SetErrorCode(ErrorCode::SYSTEM_STATUS_ABNORMAL);
247         return CreateErrorMessage(env, "Get ApplicationContext failed.");
248     }
249     std::string filesDir = context->GetFilesDir();
250     if (filesDir.empty()) {
251         apiInvokeRecorder.SetErrorCode(ErrorCode::SYSTEM_STATUS_ABNORMAL);
252         return CreateErrorMessage(env, "Get App files dir failed.");
253     }
254     std::string filePath = filesDir + SLASH_STR + fileName + JSON_FILE;
255     if (!IsLegalPath(filePath)) {
256         apiInvokeRecorder.SetErrorCode(ErrorCode::SYSTEM_STATUS_ABNORMAL);
257         return CreateErrorMessage(env, "input fileName is illegal.");
258     }
259     if (!CreateFile(filePath)) {
260         apiInvokeRecorder.SetErrorCode(ErrorCode::SYSTEM_STATUS_ABNORMAL);
261         return CreateErrorMessage(env, "file created failed.");
262     }
263     NativeEngine *engine = reinterpret_cast<NativeEngine*>(env);
264     engine->StartCpuProfiler(filePath);
265     return CreateUndefined(env);
266 }
267 
StopProfiling(napi_env env,napi_callback_info info)268 napi_value StopProfiling(napi_env env, napi_callback_info info)
269 {
270     ApiInvokeRecorder apiInvokeRecorder("stopProfiling");
271     NativeEngine *engine = reinterpret_cast<NativeEngine*>(env);
272     engine->StopCpuProfiler();
273     return CreateUndefined(env);
274 }
275 
StopJsCpuProfiling(napi_env env,napi_callback_info info)276 napi_value StopJsCpuProfiling(napi_env env, napi_callback_info info)
277 {
278     ApiInvokeRecorder apiInvokeRecorder("stopJsCpuProfiling");
279     NativeEngine *engine = reinterpret_cast<NativeEngine*>(env);
280     engine->StopCpuProfiler();
281     return CreateUndefined(env);
282 }
283 
GetPss(napi_env env,napi_callback_info info)284 napi_value GetPss(napi_env env, napi_callback_info info)
285 {
286     napi_value pss;
287     std::shared_ptr<UCollectUtil::MemoryCollector> collector = UCollectUtil::MemoryCollector::Create();
288     if (collector != nullptr) {
289         int pid = getprocpid();
290         auto collectResult = collector->CollectProcessMemory(pid);
291         int32_t pssInfo = collectResult.data.pss + collectResult.data.swapPss;
292         napi_create_bigint_uint64(env, pssInfo, &pss);
293     } else {
294         napi_create_bigint_uint64(env, 0, &pss);
295     }
296     return pss;
297 }
298 
GetSharedDirty(napi_env env,napi_callback_info info)299 napi_value GetSharedDirty(napi_env env, napi_callback_info info)
300 {
301     ApiInvokeRecorder apiInvokeRecorder("getSharedDirty");
302     napi_value sharedDirty;
303     std::shared_ptr<UCollectUtil::MemoryCollector> collector = UCollectUtil::MemoryCollector::Create();
304     if (collector != nullptr) {
305         int pid = getprocpid();
306         auto collectResult = collector->CollectProcessMemory(pid);
307         int32_t sharedDirtyInfo = collectResult.data.sharedDirty;
308         napi_create_bigint_uint64(env, sharedDirtyInfo, &sharedDirty);
309     } else {
310         napi_create_bigint_uint64(env, 0, &sharedDirty);
311     }
312     return sharedDirty;
313 }
314 
GetPrivateDirty(napi_env env,napi_callback_info info)315 napi_value GetPrivateDirty(napi_env env, napi_callback_info info)
316 {
317     ApiInvokeRecorder apiInvokeRecorder("getPrivateDirty");
318     napi_value privateDirtyValue;
319     std::shared_ptr<UCollectUtil::MemoryCollector> collector = UCollectUtil::MemoryCollector::Create();
320     if (collector != nullptr) {
321         pid_t pid = getprocpid();
322         auto collectResult = collector->CollectProcessMemory(pid);
323         int32_t privateDirty = collectResult.data.privateDirty;
324         napi_create_bigint_uint64(env, privateDirty, &privateDirtyValue);
325     } else {
326         napi_create_bigint_uint64(env, 0, &privateDirtyValue);
327     }
328     return privateDirtyValue;
329 }
330 
GetCpuUsage(napi_env env,napi_callback_info info)331 napi_value GetCpuUsage(napi_env env, napi_callback_info info)
332 {
333     constexpr uint32_t reportTimeOutSec = 5 * 60;
334     constexpr uint32_t limitSize = 100;
335     static MultipleRecordReporter multipleRecordReporter(reportTimeOutSec, limitSize);
336     ApiInvokeRecorder apiInvokeRecorder("getCpuUsage", multipleRecordReporter);
337     napi_value cpuUsageValue;
338     std::unique_ptr<DumpUsage> dumpUsage = std::make_unique<DumpUsage>();
339     pid_t pid = getprocpid();
340     double cpuUsage = dumpUsage->GetCpuUsage(pid);
341     napi_create_double(env, cpuUsage, &cpuUsageValue);
342     return cpuUsageValue;
343 }
344 
GetNativeHeapSize(napi_env env,napi_callback_info info)345 napi_value GetNativeHeapSize(napi_env env, napi_callback_info info)
346 {
347     struct mallinfo mi = mallinfo();
348     napi_value nativeHeapSize;
349     napi_create_bigint_uint64(env, uint64_t(mi.uordblks + mi.fordblks), &nativeHeapSize);
350     return nativeHeapSize;
351 }
352 
GetNativeHeapAllocatedSize(napi_env env,napi_callback_info info)353 napi_value GetNativeHeapAllocatedSize(napi_env env, napi_callback_info info)
354 {
355     ApiInvokeRecorder apiInvokeRecorder("getNativeHeapAllocatedSize");
356     struct mallinfo mi = mallinfo();
357     napi_value nativeHeapAllocatedSize;
358     napi_create_bigint_uint64(env, uint64_t(mi.uordblks), &nativeHeapAllocatedSize);
359     return nativeHeapAllocatedSize;
360 }
361 
GetNativeHeapFreeSize(napi_env env,napi_callback_info info)362 napi_value GetNativeHeapFreeSize(napi_env env, napi_callback_info info)
363 {
364     ApiInvokeRecorder apiInvokeRecorder("getNativeHeapFreeSize");
365     struct mallinfo mi = mallinfo();
366     napi_value nativeHeapFreeSize;
367     napi_create_bigint_uint64(env, uint64_t(mi.fordblks), &nativeHeapFreeSize);
368     return nativeHeapFreeSize;
369 }
370 
GetServiceDump(napi_env env,napi_callback_info info)371 static napi_value GetServiceDump(napi_env env, napi_callback_info info)
372 {
373     ApiInvokeRecorder apiInvokeRecorder("getServiceDump");
374     int serviceAbilityId = 0;
375     int fd = 0;
376     std::vector<std::u16string> args;
377     if (!GetDumpParam(env, info, serviceAbilityId, fd, args)) {
378         std::string paramErrorMessage = "The parameter check failed.";
379         napi_throw_error(env, std::to_string(ErrorCode::PARAMETER_ERROR).c_str(), paramErrorMessage.c_str());
380         return CreateUndefined(env);
381     }
382 
383     sptr<ISystemAbilityManager> sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
384     if (!sam) {
385         return CreateUndefined(env);
386     }
387     sptr<IRemoteObject> sa = sam->CheckSystemAbility(serviceAbilityId);
388     if (sa == nullptr) {
389         HILOG_ERROR(LOG_CORE, "no this system ability.");
390         std::string idErrorMessage = "ServiceId invalid. The system ability does not exist.";
391         napi_throw_error(env, std::to_string(ErrorCode::SYSTEM_ABILITY_NOT_FOUND).c_str(), idErrorMessage.c_str());
392         return CreateUndefined(env);
393     }
394     int dumpResult = sa->Dump(fd, args);
395     HILOG_INFO(LOG_CORE, "Dump result: %{public}d", dumpResult);
396     return CreateUndefined(env);
397 }
398 
GetVss(napi_env env,napi_callback_info info)399 napi_value GetVss(napi_env env, napi_callback_info info)
400 {
401     ApiInvokeRecorder apiInvokeRecorder("getVss");
402     napi_value vss;
403     std::shared_ptr<UCollectUtil::MemoryCollector> collector = UCollectUtil::MemoryCollector::Create();
404     if (collector != nullptr) {
405         pid_t pid = getprocpid();
406         auto collectResult = collector->CollectProcessVss(pid);
407         uint64_t vssInfo = collectResult.data;
408         napi_create_bigint_uint64(env, vssInfo, &vss);
409     } else {
410         napi_create_bigint_uint64(env, 0, &vss);
411     }
412     return vss;
413 }
414 
GetSystemCpuUsage(napi_env env,napi_callback_info info)415 static napi_value GetSystemCpuUsage(napi_env env, napi_callback_info info)
416 {
417     constexpr uint32_t reportTimeOutSec = 5 * 60;
418     constexpr uint32_t limitSize = 100;
419     static MultipleRecordReporter multipleRecordReporter(reportTimeOutSec, limitSize);
420     ApiInvokeRecorder apiInvokeRecorder("getSystemCpuUsage", multipleRecordReporter);
421     auto cpuUsageOptional = HidebugNativeInterface::GetInstance().GetSystemCpuUsage();
422     if (!cpuUsageOptional) {
423         std::string paramErrorMessage = "The status of the system CPU usage is abnormal.";
424         napi_throw_error(env, std::to_string(ErrorCode::SYSTEM_STATUS_ABNORMAL).c_str(), paramErrorMessage.c_str());
425         return CreateUndefined(env);
426     }
427     napi_value retMsg = nullptr;
428     napi_create_double(env, cpuUsageOptional.value(),  &retMsg);
429     return retMsg;
430 }
431 
RemoveNapiWrap(napi_env env,napi_callback_info info)432 static napi_value RemoveNapiWrap(napi_env env, napi_callback_info info)
433 {
434     size_t argc = REMOVE_NAPI_WRAP_PARAM_COUNT;
435     napi_value argv[REMOVE_NAPI_WRAP_PARAM_COUNT] = {nullptr};
436     napi_value thisVar = nullptr;
437     void *data = nullptr;
438     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
439     if (argc != REMOVE_NAPI_WRAP_PARAM_COUNT ||
440         (!MatchValueType(env, argv[ARRAY_INDEX_FIRST], napi_object) ||
441         !MatchValueType(env, argv[ARRAY_INDEX_SECOND], napi_boolean))) {
442         HILOG_DEBUG(LOG_CORE, "RemoveNapiWrap Failed to parse parameters, argc %{public}d", (int)argc);
443         std::string paramErrorMessage = "The parameter check failed.";
444         napi_throw_error(env, std::to_string(ErrorCode::PARAMETER_ERROR).c_str(), paramErrorMessage.c_str());
445         return CreateUndefined(env);
446     }
447 
448     // remove jsObj's wrap
449     auto jsObj = argv[ARRAY_INDEX_FIRST];
450     void *nativePtr = nullptr;
451     napi_remove_wrap(env, jsObj, (void **)&nativePtr);
452 
453     // remove jsObj's properties wrap
454     bool needRemoveProperty = false;
455     napi_get_value_bool(env, argv[ARRAY_INDEX_SECOND], &needRemoveProperty);
456     if (needRemoveProperty) {
457         napi_value allPropertyNames = nullptr;
458         napi_object_get_keys(env, jsObj, &allPropertyNames);
459         uint32_t nameCount = 0;
460         napi_get_array_length(env, allPropertyNames, &nameCount);
461         for (size_t i = 0; i < nameCount; ++i) {
462             napi_value propertyName = nullptr;
463             napi_get_element(env, allPropertyNames, i, &propertyName);
464             char name[NAME_LEN] = {0};
465             size_t len = 0;
466             napi_get_value_string_utf8(env, propertyName, name, NAME_LEN, &len);
467             napi_value propertyObj = nullptr;
468             napi_get_named_property(env, jsObj, name, &propertyObj);
469             napi_remove_wrap(env, propertyObj, (void **)&nativePtr);
470         }
471     }
472     return CreateUndefined(env);
473 }
474 
GetAppVMMemoryInfo(napi_env env,napi_callback_info info)475 napi_value GetAppVMMemoryInfo(napi_env env, napi_callback_info info)
476 {
477     ApiInvokeRecorder apiInvokeRecorder("getAppVMMemoryInfo");
478     uint64_t allArraySizeValue{0};
479     uint64_t heapUsedValue{0};
480     uint64_t totalHeapValue{0};
481     NativeEngine *engine = reinterpret_cast<NativeEngine*>(env);
482     if (engine) {
483         allArraySizeValue = engine->GetArrayBufferSize();
484         heapUsedValue = engine->GetHeapUsedSize();
485         totalHeapValue = engine->GetHeapTotalSize();
486     }
487 
488     napi_value vMMemoryInfo;
489     napi_create_object(env, &vMMemoryInfo);
490 
491     napi_value totalHeap;
492     totalHeapValue = totalHeapValue >> BYTE_2_KB_SHIFT_BITS;
493     napi_create_bigint_uint64(env, totalHeapValue, &totalHeap);
494     napi_set_named_property(env, vMMemoryInfo, "totalHeap", totalHeap);
495 
496     napi_value heapUsed;
497     heapUsedValue = heapUsedValue >> BYTE_2_KB_SHIFT_BITS;
498     napi_create_bigint_uint64(env, heapUsedValue, &heapUsed);
499     napi_set_named_property(env, vMMemoryInfo, "heapUsed", heapUsed);
500 
501     napi_value allArraySize;
502     allArraySizeValue = allArraySizeValue >> BYTE_2_KB_SHIFT_BITS;
503     napi_create_bigint_uint64(env, allArraySizeValue, &allArraySize);
504     napi_set_named_property(env, vMMemoryInfo, "allArraySize", allArraySize);
505 
506     return vMMemoryInfo;
507 }
508 
ConvertThreadCpuUsageToJs(napi_env env,napi_value & result,uint32_t threadIdValue,double cpuUsageValue)509 static void ConvertThreadCpuUsageToJs(napi_env env, napi_value &result, uint32_t threadIdValue, double cpuUsageValue)
510 {
511     napi_create_object(env, &result);
512 
513     napi_value threadId;
514     napi_create_uint32(env, threadIdValue, &threadId);
515     napi_set_named_property(env, result, "threadId", threadId);
516 
517     napi_value cpuUsage;
518     napi_create_double(env, cpuUsageValue, &cpuUsage);
519     napi_set_named_property(env, result, "cpuUsage", cpuUsage);
520 }
521 
ConvertThreadCpuUsageMapToJs(napi_env env,napi_value & result,const std::map<uint32_t,double> & threadMap)522 static void ConvertThreadCpuUsageMapToJs(napi_env env, napi_value &result, const std::map<uint32_t, double> &threadMap)
523 {
524     napi_create_array(env, &result);
525     size_t idx = 0;
526     for (const auto[threadId, cpuUsage] : threadMap) {
527         napi_value obj = nullptr;
528         ConvertThreadCpuUsageToJs(env, obj, threadId, cpuUsage);
529         napi_set_element(env, result, idx, obj);
530         idx++;
531     }
532 }
533 
GetAppThreadCpuUsage(napi_env env,napi_callback_info info)534 napi_value GetAppThreadCpuUsage(napi_env env, napi_callback_info info)
535 {
536     ApiInvokeRecorder apiInvokeRecorder("getAppThreadCpuUsage");
537     napi_value result;
538     std::map<uint32_t, double> threadMap = HidebugNativeInterface::GetInstance().GetAppThreadCpuUsage();
539     ConvertThreadCpuUsageMapToJs(env, result, threadMap);
540     return result;
541 }
542 
GetAppMemoryLimit(napi_env env,napi_callback_info info)543 napi_value GetAppMemoryLimit(napi_env env, napi_callback_info info)
544 {
545     ApiInvokeRecorder apiInvokeRecorder("getAppMemoryLimit");
546     napi_value appMemoryLimit;
547     napi_create_object(env, &appMemoryLimit);
548     MemoryLimit memoryLimit{};
549     auto memoryLimitOption = HidebugNativeInterface::GetInstance().GetAppMemoryLimit();
550     if (memoryLimitOption) {
551         memoryLimit = memoryLimitOption.value();
552     }
553     napi_value rssLimit;
554     napi_create_bigint_uint64(env, memoryLimit.rssLimit, &rssLimit);
555     napi_set_named_property(env, appMemoryLimit, "rssLimit", rssLimit);
556 
557     napi_value vssLimit;
558     napi_create_bigint_uint64(env, memoryLimit.vssLimit, &vssLimit);
559     napi_set_named_property(env, appMemoryLimit, "vssLimit", vssLimit);
560     uint64_t vmHeapLimitValue{0};
561     uint64_t vmTotalHeapSizeValue{0};
562     NativeEngine *engine = reinterpret_cast<NativeEngine *>(env);
563     if (engine) {
564         vmHeapLimitValue = engine->GetHeapLimitSize();
565         vmTotalHeapSizeValue = engine->GetProcessHeapLimitSize();
566     }
567     napi_value vmHeapLimit;
568     vmHeapLimitValue = vmHeapLimitValue >> BYTE_2_KB_SHIFT_BITS;
569     napi_create_bigint_uint64(env, vmHeapLimitValue, &vmHeapLimit);
570     napi_set_named_property(env, appMemoryLimit, "vmHeapLimit", vmHeapLimit);
571     napi_value vmTotalHeapSize;
572     vmTotalHeapSizeValue = vmTotalHeapSizeValue >> BYTE_2_KB_SHIFT_BITS;
573     napi_create_bigint_uint64(env, vmTotalHeapSizeValue, &vmTotalHeapSize);
574     napi_set_named_property(env, appMemoryLimit, "vmTotalHeapSize", vmTotalHeapSize);
575     return appMemoryLimit;
576 }
577 
GetAppNativeMemInfo(napi_env env,napi_callback_info info)578 napi_value GetAppNativeMemInfo(napi_env env, napi_callback_info info)
579 {
580     ApiInvokeRecorder apiInvokeRecorder("getAppNativeMemInfo");
581     HiDebug_NativeMemInfo nativeMemInfo{};
582     auto nativeMemInfoOption = HidebugNativeInterface::GetInstance().GetAppNativeMemInfo();
583     if (nativeMemInfoOption) {
584         nativeMemInfo = nativeMemInfoOption.value();
585     }
586     napi_value memInfo;
587     napi_create_object(env, &memInfo);
588 
589     napi_value pss;
590     napi_create_bigint_uint64(env, nativeMemInfo.pss, &pss);
591     napi_set_named_property(env, memInfo, "pss", pss);
592 
593     napi_value rss;
594     napi_create_bigint_uint64(env, nativeMemInfo.rss, &rss);
595     napi_set_named_property(env, memInfo, "rss", rss);
596 
597     napi_value sharedDirty;
598     napi_create_bigint_uint64(env, nativeMemInfo.sharedDirty, &sharedDirty);
599     napi_set_named_property(env, memInfo, "sharedDirty", sharedDirty);
600 
601     napi_value privateDirty;
602     napi_create_bigint_uint64(env, nativeMemInfo.privateDirty, &privateDirty);
603     napi_set_named_property(env, memInfo, "privateDirty", privateDirty);
604 
605     napi_value sharedClean;
606     napi_create_bigint_uint64(env, nativeMemInfo.sharedClean, &sharedClean);
607     napi_set_named_property(env, memInfo, "sharedClean", sharedClean);
608 
609     napi_value privateClean;
610     napi_create_bigint_uint64(env, nativeMemInfo.privateClean, &privateClean);
611     napi_set_named_property(env, memInfo, "privateClean", privateClean);
612 
613     napi_value vss;
614     napi_create_bigint_uint64(env, nativeMemInfo.vss, &vss);
615     napi_set_named_property(env, memInfo, "vss", vss);
616 
617     return memInfo;
618 }
619 
GetSystemMemInfo(napi_env env,napi_callback_info info)620 napi_value GetSystemMemInfo(napi_env env, napi_callback_info info)
621 {
622     ApiInvokeRecorder apiInvokeRecorder("getSystemMemInfo");
623     SysMemory systemMemInfo{};
624     auto systemMemInfoOption = HidebugNativeInterface::GetInstance().GetSystemMemInfo();
625     if (systemMemInfoOption) {
626         systemMemInfo = systemMemInfoOption.value();
627     }
628     napi_value sysMemInfo;
629     napi_create_object(env, &sysMemInfo);
630 
631     napi_value totalMem;
632     napi_create_bigint_uint64(env, systemMemInfo.memTotal, &totalMem);
633     napi_set_named_property(env, sysMemInfo, "totalMem", totalMem);
634 
635     napi_value freeMem;
636     napi_create_bigint_uint64(env, systemMemInfo.memFree, &freeMem);
637     napi_set_named_property(env, sysMemInfo, "freeMem", freeMem);
638 
639     napi_value availableMem;
640     napi_create_bigint_uint64(env, systemMemInfo.memAvailable, &availableMem);
641     napi_set_named_property(env, sysMemInfo, "availableMem", availableMem);
642     return sysMemInfo;
643 }
644 
StartAppTraceCapture(napi_env env,napi_callback_info info)645 napi_value StartAppTraceCapture(napi_env env, napi_callback_info info)
646 {
647     ApiInvokeRecorder apiInvokeRecorder("startAppTraceCapture");
648     napi_value result;
649     uint32_t traceFlag = 0;
650     uint32_t limitSize = 0;
651     std::vector<uint64_t> tags;
652     if (!GetTraceParam(env, info, traceFlag, limitSize, tags)) {
653         std::string paramErrorMessage = "Invalid argument";
654         apiInvokeRecorder.SetErrorCode(ErrorCode::PARAMETER_ERROR);
655         napi_throw_error(env, std::to_string(ErrorCode::PARAMETER_ERROR).c_str(), paramErrorMessage.c_str());
656     }
657     uint64_t tag = std::accumulate(tags.begin(), tags.end(), 0ull, [](uint64_t a, uint64_t b) { return a | b; });
658     std::string file;
659     auto ret = HidebugNativeInterface::GetInstance().StartAppTraceCapture(tag, traceFlag, limitSize, file);
660     if (ret == HIDEBUG_SUCCESS) {
661         napi_create_string_utf8(env, file.c_str(), NAPI_AUTO_LENGTH, &result);
662         return result;
663     }
664     if (ret == HIDEBUG_INVALID_ARGUMENT) {
665         std::string errorMessage = "Invalid argument";
666         apiInvokeRecorder.SetErrorCode(ErrorCode::PARAMETER_ERROR);
667         napi_throw_error(env, std::to_string(ErrorCode::PARAMETER_ERROR).c_str(), errorMessage.c_str());
668     }
669     if (ret == HIDEBUG_TRACE_CAPTURED_ALREADY) {
670         std::string errorMessage = "Capture trace already enabled.";
671         apiInvokeRecorder.SetErrorCode(ErrorCode::HAVA_ALREADY_TRACE);
672         napi_throw_error(env, std::to_string(ErrorCode::HAVA_ALREADY_TRACE).c_str(), errorMessage.c_str());
673     }
674     if (ret == HIDEBUG_NO_PERMISSION) {
675         std::string errorMessage = "No write permission on the file.";
676         apiInvokeRecorder.SetErrorCode(ErrorCode::WITHOUT_WRITE_PERMISSON);
677         napi_throw_error(env, std::to_string(ErrorCode::WITHOUT_WRITE_PERMISSON).c_str(), errorMessage.c_str());
678     }
679     std::string errorMessage = "Abnormal trace status.";
680     apiInvokeRecorder.SetErrorCode(ErrorCode::SYSTEM_STATUS_ABNORMAL);
681     napi_throw_error(env, std::to_string(ErrorCode::SYSTEM_STATUS_ABNORMAL).c_str(), errorMessage.c_str());
682     return CreateUndefined(env);
683 }
684 
StopAppTraceCapture(napi_env env,napi_callback_info info)685 napi_value StopAppTraceCapture(napi_env env, napi_callback_info info)
686 {
687     ApiInvokeRecorder apiInvokeRecorder("stopAppTraceCapture");
688     auto ret = HidebugNativeInterface::GetInstance().StopAppTraceCapture();
689     if (ret == HIDEBUG_TRACE_ABNORMAL) {
690         std::string errorMessage = "The status of the trace is abnormal";
691         apiInvokeRecorder.SetErrorCode(ErrorCode::SYSTEM_STATUS_ABNORMAL);
692         napi_throw_error(env, std::to_string(ErrorCode::SYSTEM_STATUS_ABNORMAL).c_str(), errorMessage.c_str());
693     }
694     if (ret == HIDEBUG_NO_TRACE_RUNNING) {
695         std::string errorMessage = "No capture trace running";
696         apiInvokeRecorder.SetErrorCode(ErrorCode::NO_CAPTURE_TRACE_RUNNING);
697         napi_throw_error(env, std::to_string(ErrorCode::NO_CAPTURE_TRACE_RUNNING).c_str(), errorMessage.c_str());
698     }
699     return CreateUndefined(env);
700 }
701 
GetVMRuntimeStats(napi_env env,napi_callback_info info)702 napi_value GetVMRuntimeStats(napi_env env, napi_callback_info info)
703 {
704     ApiInvokeRecorder apiInvokeRecorder("getVMRuntimeStats");
705     napi_value vmRunTimeStats;
706     napi_create_object(env, &vmRunTimeStats);
707     for (const auto &[k, v] : GC::vmGcMap_) {
708         napi_set_named_property(env, vmRunTimeStats, k.c_str(), v(env));
709     }
710     return vmRunTimeStats;
711 }
712 
GetVMRuntimeStat(napi_env env,napi_callback_info info)713 napi_value GetVMRuntimeStat(napi_env env, napi_callback_info info)
714 {
715     ApiInvokeRecorder apiInvokeRecorder("getVMRuntimeStat");
716     std::string param;
717     if (!GetTheOnlyStringParam(env, info, param)) {
718         std::string paramErrorMessage = "Invalid parameter, a string parameter required.";
719         napi_throw_error(env, std::to_string(ErrorCode::PARAMETER_ERROR).c_str(), paramErrorMessage.c_str());
720         apiInvokeRecorder.SetErrorCode(ErrorCode::PARAMETER_ERROR);
721         return CreateUndefined(env);
722     }
723     if (GC::vmGcMap_.find(param) == GC::vmGcMap_.end()) {
724         std::string paramErrorMessage = "Invalid parameter, unknown property.";
725         napi_throw_error(env, std::to_string(ErrorCode::PARAMETER_ERROR).c_str(), paramErrorMessage.c_str());
726         apiInvokeRecorder.SetErrorCode(ErrorCode::PARAMETER_ERROR);
727         return CreateUndefined(env);
728     }
729     return GC::vmGcMap_.at(param)(env);
730 }
731 
JudgeValueRange(const std::string & type,int32_t value)732 static bool JudgeValueRange(const std::string &type, int32_t value)
733 {
734     if (limitResource.find(type) != limitResource.end()) {
735         auto limitValue = limitResource[type];
736         if (value >= limitValue.first && value <= limitValue.second) {
737             return true;
738         }
739     }
740     return false;
741 }
742 
CheckFilenameParamLength(napi_env env,napi_value * argv,size_t & bufLen)743 static bool CheckFilenameParamLength(napi_env env, napi_value *argv, size_t &bufLen)
744 {
745     napi_status status = napi_get_value_string_utf8(env, argv[FIRST_POS], nullptr, 0, &bufLen);
746     if (status != napi_ok) {
747         HILOG_ERROR(LOG_CORE, "GetAppResourceLimitParam failed. Get input filename param length failed.");
748         return false;
749     }
750     const int bufMax = 128;
751     if (bufLen > bufMax || bufLen == 0) {
752         HILOG_ERROR(LOG_CORE, "GetAppResourceLimitParam failed. input filename param length is illegal.");
753         return false;
754     }
755     return true;
756 }
757 
CheckResourceType(napi_env env,napi_value * argv,size_t & bufLen,std::string & type)758 static bool CheckResourceType(napi_env env, napi_value *argv, size_t &bufLen, std::string &type)
759 {
760     std::vector<char> buf(bufLen + 1, 0);
761     napi_get_value_string_utf8(env, argv[FIRST_POS], buf.data(), bufLen + 1, &bufLen);
762     type = std::string(buf.data());
763     if (type.empty()) {
764         HILOG_ERROR(LOG_CORE, "GetAppResourceLimitParam failed. Resource type is invalid.");
765         return false;
766     }
767     auto findType = std::find(RESOURCE_TYPE_LIST.begin(), RESOURCE_TYPE_LIST.end(), type);
768     if (findType == RESOURCE_TYPE_LIST.end()) {
769         HILOG_ERROR(LOG_CORE, "GetAppResourceLimitParam failed. Resource type is invalid.");
770         return false;
771     }
772     return true;
773 }
774 
CheckInputValue(napi_env env,napi_value * argv,std::string & type,int32_t & value)775 static bool CheckInputValue(napi_env env, napi_value *argv, std::string &type, int32_t &value)
776 {
777     if (napi_get_value_int32(env, argv[SECOND_POS], &value) != napi_ok || value < 0) {
778         HILOG_ERROR(LOG_CORE, "GetAppResourceLimitParam failed. Input value error.");
779         return false;
780     }
781     if (!JudgeValueRange(type, value)) {
782         HILOG_ERROR(LOG_CORE, "GetAppResourceLimitParam failed. The value range is invalid.");
783         return false;
784     }
785     return true;
786 }
787 
GetAppResourceLimitParam(napi_env env,napi_callback_info info,std::string & type,int32_t & value,bool & enabledDebugLog)788 static bool GetAppResourceLimitParam(napi_env env, napi_callback_info info, std::string& type,
789     int32_t& value, bool& enabledDebugLog)
790 {
791     const int valueNum = 3;
792     size_t argc = valueNum;
793     napi_value argv[valueNum] = { nullptr };
794     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
795     if (argc != valueNum) {
796         HILOG_ERROR(LOG_CORE, "GetAppResourceLimitParam failed. Invalid numbers of params!");
797         return false;
798     }
799     if (!MatchValueType(env, argv[FIRST_POS], napi_string) &&
800         !MatchValueType(env, argv[SECOND_POS], napi_number) &&
801         !MatchValueType(env, argv[THIRD_POS], napi_boolean)) {
802         HILOG_ERROR(LOG_CORE, "GetAppResourceLimitParam params type error.");
803         return false;
804     }
805     size_t bufLen = 0;
806     if (!CheckFilenameParamLength(env, argv, bufLen)) {
807         return false;
808     }
809     if (!CheckResourceType(env, argv, bufLen, type)) {
810         return false;
811     }
812     if (!CheckInputValue(env, argv, type, value)) {
813         return false;
814     }
815     if (napi_get_value_bool(env, argv[THIRD_POS], &enabledDebugLog) != napi_ok) {
816         HILOG_ERROR(LOG_CORE, "GetAppResourceLimitParam failed. Get input enabledDebugLog failed.");
817         return false;
818     }
819     return true;
820 }
821 
CreateSanBoxDir()822 static bool CreateSanBoxDir()
823 {
824     constexpr mode_t defaultLogDirMode = 0770;
825     const std::string reourceLimitDir = "/data/storage/el2/log/resourcelimit/";
826     if (!OHOS::FileExists(reourceLimitDir)) {
827         OHOS::ForceCreateDirectory(reourceLimitDir);
828         OHOS::ChangeModeDirectory(reourceLimitDir, defaultLogDirMode);
829     }
830     if (OHOS::StorageDaemon::AclSetAccess(reourceLimitDir, "g:1201:rwx") != 0) {
831         HILOG_ERROR(LOG_CORE, "CreateSanBoxDir Failed to AclSetAccess");
832         return false;
833     }
834     return true;
835 }
836 
CheckVersionType(const std::string & type,const std::string & key)837 static bool CheckVersionType(const std::string& type, const std::string& key)
838 {
839     auto versionType = OHOS::system::GetParameter(key, "unknown");
840     return (versionType.find(type) != std::string::npos);
841 }
842 
SetAppResourceLimit(napi_env env,napi_callback_info info)843 napi_value SetAppResourceLimit(napi_env env, napi_callback_info info)
844 {
845     ApiInvokeRecorder apiInvokeRecorder("setAppResourceLimit");
846     CreateSanBoxDir();
847     if (!IsBetaVersion() && !CheckVersionType("enable", KEY_HIVIEW_DEVELOP_TYPE)) {
848         HILOG_ERROR(LOG_CORE, "SetAppResourceLimit failed. Not developer options or beta versions");
849         apiInvokeRecorder.SetErrorCode(ErrorCode::VERSION_ERROR);
850         return CreateUndefined(env);
851     }
852     std::string type = "";
853     int32_t value = 0;
854     bool enabledDebugLog = false;
855     if (!GetAppResourceLimitParam(env, info, type, value, enabledDebugLog)) {
856         apiInvokeRecorder.SetErrorCode(ErrorCode::PARAMETER_ERROR);
857         return CreateUndefined(env);
858     }
859     if (type == "js_heap") { // js_heap set value
860         NativeEngine *engine = reinterpret_cast<NativeEngine*>(env);
861         engine->SetJsDumpThresholds(value);
862     }
863     auto abilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
864     if (!abilityManager) {
865         apiInvokeRecorder.SetErrorCode(ErrorCode::SYSTEM_ABILITY_NOT_FOUND);
866         return CreateUndefined(env);
867     }
868     sptr<IRemoteObject> remoteObject = abilityManager->CheckSystemAbility(DFX_SYS_HIVIEW_ABILITY_ID);
869     if (remoteObject == nullptr) {
870         HILOG_ERROR(LOG_CORE, "SetAppResourceLimit failed. No this system ability.");
871         std::string idErrorMessage = "system ability is not exist.";
872         napi_throw_error(env, std::to_string(ErrorCode::SYSTEM_STATUS_ABNORMAL).c_str(), idErrorMessage.c_str());
873         apiInvokeRecorder.SetErrorCode(ErrorCode::SYSTEM_STATUS_ABNORMAL);
874         return CreateUndefined(env);
875     }
876     auto result = HidebugNativeInterface::GetInstance().GetMemoryLeakResource(type, value, enabledDebugLog);
877     if (result == MemoryState::MEMORY_FAILED) {
878         apiInvokeRecorder.SetErrorCode(ErrorCode::SYSTEM_STATUS_ABNORMAL);
879         return CreateUndefined(env);
880     }
881     return CreateUndefined(env);
882 }
883 
IsDebugState(napi_env env,napi_callback_info info)884 napi_value IsDebugState(napi_env env, napi_callback_info info)
885 {
886     ApiInvokeRecorder apiInvokeRecorder("isDebugState");
887     NativeEngine *engine = reinterpret_cast<NativeEngine*>(env);
888     bool debugState = (engine && engine->GetIsDebugModeEnabled()) ||
889         HidebugNativeInterface::GetInstance().IsDebuggerConnected();
890     napi_value result = nullptr;
891     napi_get_boolean(env, debugState, &result);
892     return result;
893 }
894 
895 class GraphicAsyncTask : public AsyncTask {
896 public:
GraphicAsyncTask()897     GraphicAsyncTask() : AsyncTask("graphicAsyncTask"), apiInvokeRecorder_("getGraphicsMemory") {}
898 
899 protected:
Work(napi_env env)900     void Work(napi_env env) override
901     {
902         result_ = HidebugNativeInterface::GetInstance().GetGraphicsMemory();
903     }
904 
Done(napi_env env,napi_status status)905     void Done(napi_env env, napi_status status) override
906     {
907         if (result_) {
908             napi_value ret;
909             napi_create_int32(env, result_.value(), &ret);
910             napi_resolve_deferred(env, deferred_, ret);
911         } else {
912             constexpr const char* errMsg = "Failed to get the application memory due to a remote exception";
913             apiInvokeRecorder_.SetErrorCode(ErrorCode::SYSTEM_STATUS_ABNORMAL);
914             napi_reject_deferred(env, deferred_,
915                 CreateErrorMessage(env, std::to_string(ErrorCode::SYSTEM_STATUS_ABNORMAL), errMsg));
916         }
917     }
918 
919 private:
920     std::optional<int> result_{};
921     ApiInvokeRecorder apiInvokeRecorder_;
922 };
923 
GetGraphicsMemory(napi_env env,napi_callback_info info)924 napi_value GetGraphicsMemory(napi_env env, napi_callback_info info)
925 {
926     return AsyncTask::GetPromise<GraphicAsyncTask>(env);
927 }
928 
GetGraphicsMemorySync(napi_env env,napi_callback_info info)929 napi_value GetGraphicsMemorySync(napi_env env, napi_callback_info info)
930 {
931     ApiInvokeRecorder apiInvokeRecorder("getGraphicsMemorySync");
932     std::optional<int32_t> result = HidebugNativeInterface::GetInstance().GetGraphicsMemory();
933     if (result) {
934         napi_value ret;
935         napi_create_int32(env, result.value(), &ret);
936         return ret;
937     }
938     constexpr const char* errMsg = "Failed to get the application memory due to a remote exception";
939     napi_throw_error(env, std::to_string(ErrorCode::SYSTEM_STATUS_ABNORMAL).c_str(), errMsg);
940     apiInvokeRecorder.SetErrorCode(ErrorCode::SYSTEM_STATUS_ABNORMAL);
941     return CreateUndefined(env);
942 }
943 
DeclareHiDebugInterface(napi_env env,napi_value exports)944 napi_value DeclareHiDebugInterface(napi_env env, napi_value exports)
945 {
946     ApiRecordReporter::InitProcessor();
947     napi_property_descriptor desc[] = {
948         DECLARE_NAPI_FUNCTION("startProfiling", StartProfiling),
949         DECLARE_NAPI_FUNCTION("stopProfiling", StopProfiling),
950         DECLARE_NAPI_FUNCTION("dumpHeapData", DumpHeapData),
951         DECLARE_NAPI_FUNCTION("startJsCpuProfiling", StartJsCpuProfiling),
952         DECLARE_NAPI_FUNCTION("stopJsCpuProfiling", StopJsCpuProfiling),
953         DECLARE_NAPI_FUNCTION("dumpJsHeapData", DumpJsHeapData),
954         DECLARE_NAPI_FUNCTION("getPss", GetPss),
955         DECLARE_NAPI_FUNCTION("getSharedDirty", GetSharedDirty),
956         DECLARE_NAPI_FUNCTION("getPrivateDirty", GetPrivateDirty),
957         DECLARE_NAPI_FUNCTION("getCpuUsage", GetCpuUsage),
958         DECLARE_NAPI_FUNCTION("getServiceDump", GetServiceDump),
959         DECLARE_NAPI_FUNCTION("getNativeHeapSize", GetNativeHeapSize),
960         DECLARE_NAPI_FUNCTION("getNativeHeapAllocatedSize", GetNativeHeapAllocatedSize),
961         DECLARE_NAPI_FUNCTION("getNativeHeapFreeSize", GetNativeHeapFreeSize),
962         DECLARE_NAPI_FUNCTION("getVss", GetVss),
963         DECLARE_NAPI_FUNCTION("removeNapiWrap", RemoveNapiWrap),
964         DECLARE_NAPI_FUNCTION("getAppVMMemoryInfo", GetAppVMMemoryInfo),
965         DECLARE_NAPI_FUNCTION("getAppThreadCpuUsage", GetAppThreadCpuUsage),
966         DECLARE_NAPI_FUNCTION("getSystemCpuUsage", GetSystemCpuUsage),
967         DECLARE_NAPI_FUNCTION("getAppMemoryLimit", GetAppMemoryLimit),
968         DECLARE_NAPI_FUNCTION("getAppNativeMemInfo", GetAppNativeMemInfo),
969         DECLARE_NAPI_FUNCTION("getSystemMemInfo", GetSystemMemInfo),
970         DECLARE_NAPI_FUNCTION("startAppTraceCapture", StartAppTraceCapture),
971         DECLARE_NAPI_FUNCTION("stopAppTraceCapture", StopAppTraceCapture),
972         DECLARE_NAPI_FUNCTION("getVMRuntimeStats", GetVMRuntimeStats),
973         DECLARE_NAPI_FUNCTION("getVMRuntimeStat", GetVMRuntimeStat),
974         DECLARE_NAPI_FUNCTION("setAppResourceLimit", SetAppResourceLimit),
975         DECLARE_NAPI_FUNCTION("isDebugState", IsDebugState),
976         DECLARE_NAPI_FUNCTION("getGraphicsMemory", GetGraphicsMemory),
977         DECLARE_NAPI_FUNCTION("getGraphicsMemorySync", GetGraphicsMemorySync),
978         DECLARE_NAPI_FUNCTION("dumpJsRawHeapData", DumpJsRawHeapData),
979     };
980     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
981     InitNapiClass(env, exports);
982     return exports;
983 }
984 
985 static napi_module hidebugModule = {
986     .nm_version = 1,
987     .nm_flags = 0,
988     .nm_filename = nullptr,
989     .nm_register_func = HiviewDFX::DeclareHiDebugInterface,
990     .nm_modname = "hidebug",
991     .nm_priv = ((void *)0),
992     .reserved = {0}
993 };
994 
HiDebugRegisterModule(void)995 extern "C" __attribute__((constructor)) void HiDebugRegisterModule(void)
996 {
997     napi_module_register(&hidebugModule);
998 }
999 } // HiviewDFX
1000 } // OHOS
1001