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