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