• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 使用JSVM-API接口进行debug操作
2<!--Kit: NDK Development-->
3<!--Subsystem: arkcompiler-->
4<!--Owner: @yuanxiaogou; @string_sz-->
5<!--Designer: @knightaoko-->
6<!--Tester: @test_lzz-->
7<!--Adviser: @fang-jinxu-->
8
9## 简介
10
11JSVM-API中提供接口,可以启用/禁用特定JSVM_Env下的指定debug选项。目前支持的debug选项有JSVM_SCOPE_CHECK。
12 
13## debug选项介绍
14
15debug选项皆为JSVM_DebugOption类型。
16 
17### JSVM_SCOPE_CHECK
18
19- 开发者在开发时,可能会出现在HandleScope结束后,调用上一次HandleScope内的JSVM_Value类型变量,导致程序崩溃。JSVM_SCOPE_CHECK为scope校验手段,校验当前调用的JSVM_Value类型变量是否超出HandleScope作用域,如果超出,则抛出错误“Run in wrong HandleScope”。
20- 开启该debug选项后,若JSVM-API创建了JSVM_Value,则在hilog中有“ADD_VAL_TO_SCOPE_CHECK in function: [函数名]”输出,例如“ADD_VAL_TO_SCOPE_CHECK in function: OH_JSVM_GetBoolean”。若JSVM-API使用了JSVM_Value,则在hilog中有“CHECK_SCOPE in function: [函数名]”输出,表示对使用的JSVM_Value进行了HandleScope校验,例如“CHECK_SCOPE in function: OH_JSVM_IsBoolean”。
21 
22## 接口说明
23
24| 接口                                    | 功能说明                       |
25|-----------------------------------------|-------------------------------|
26| OH_JSVM_SetDebugOption                  | 启用/禁用特定JSVM_Env的指定debug选项。传入的debug选项参数debugOption必须为JSVM_DebugOption类型,布尔值参数isEnabled用于控制是否开启该debug选项。此API仅供debug时使用,开启后可能会带来性能下降。|
27
28 
29## 使用示例
30
31JSVM-API接口开发流程参考[使用JSVM-API实现JS与C/C++语言交互开发流程](use-jsvm-process.md),本文仅对接口对应C++相关代码进行展示。
32
33### JSVM_DebugOption
34
35仅需替换[使用JSVM-API实现JS与C/C++语言交互开发流程](use-jsvm-process.md)示例代码中的“TestJSVM()”函数即可运行。
36
37- 在正确的HandleScope内调用JSVM_Value类型变量。
38```cpp
39static int32_t TestJSVM()
40{
41    JSVM_InitOptions initOptions = {0};
42    JSVM_VM vm;
43    JSVM_Env env = nullptr;
44    JSVM_VMScope vmScope;
45    JSVM_EnvScope envScope;
46    JSVM_HandleScope handleScope;
47
48    // 初始化JavaScript引擎实例
49    if (g_aa == 0) {
50        g_aa++;
51        CHECK(OH_JSVM_Init(&initOptions));
52    }
53    // 创建JSVM环境
54    CHECK(OH_JSVM_CreateVM(nullptr, &vm));
55    CHECK(OH_JSVM_CreateEnv(vm, sizeof(descriptor) / sizeof(descriptor[0]), descriptor, &env));
56    // 打开JSVM_SCOPE_CHECK校验选项
57    CHECK(OH_JSVM_SetDebugOption(env, JSVM_SCOPE_CHECK, true));
58    CHECK(OH_JSVM_OpenVMScope(vm, &vmScope));
59    CHECK_RET(OH_JSVM_OpenEnvScope(env, &envScope));
60    // 打开HandleScope
61    CHECK_RET(OH_JSVM_OpenHandleScope(env, &handleScope));
62
63    // 通过script调用测试函数
64    JSVM_Script script;
65    JSVM_Value jsSrc, result;
66    CHECK_RET(OH_JSVM_CreateStringUtf8(env, srcCallNative, JSVM_AUTO_LENGTH, &jsSrc));
67    CHECK_RET(OH_JSVM_CompileScript(env, jsSrc, nullptr, 0, true, nullptr, &script));
68    CHECK_RET(OH_JSVM_RunScript(env, script, &result));
69
70    bool boolResult = true;
71    // OH_JSVM_IsBoolean接口调用JSVM_Value类型变量result
72    JSVM_Status status = OH_JSVM_IsBoolean(env, result, &boolResult);
73    if (status != JSVM_OK) {
74        OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_IsBoolean: failed");
75    } else {
76        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_IsBoolean: success: %{public}d", boolResult);
77    }
78
79    // 销毁JSVM环境
80    // 关闭HandleScope
81    CHECK_RET(OH_JSVM_CloseHandleScope(env, handleScope));
82    CHECK_RET(OH_JSVM_CloseEnvScope(env, envScope));
83    CHECK(OH_JSVM_CloseVMScope(vm, vmScope));
84    // 关闭JSVM_SCOPE_CHECK校验选项
85    CHECK(OH_JSVM_SetDebugOption(env, JSVM_SCOPE_CHECK, false));
86    CHECK(OH_JSVM_DestroyEnv(env));
87    CHECK(OH_JSVM_DestroyVM(vm));
88    return 0;
89}
90```
91**执行结果**
92
93hilog中有以下结果输出:
94
95```
96ADD_VAL_TO_SCOPE_CHECK in function: NewString
97CHECK_SCOPE in function: OH_JSVM_CompileScript
98ADD_VAL_TO_SCOPE_CHECK in function: OH_JSVM_GetCbInfo
99ADD_VAL_TO_SCOPE_CHECK in function: OH_JSVM_GetCbInfo
100ADD_VAL_TO_SCOPE_CHECK in function: OH_JSVM_GetCbInfo
101CHECK_SCOPE in function: OH_JSVM_StrictEquals
102CHECK_SCOPE in function: OH_JSVM_StrictEquals
103JSVM OH_JSVM_StrictEquals: success: 0
104ADD_VAL_TO_SCOPE_CHECK in function: OH_JSVM_GetBoolean
105ADD_VAL_TO_SCOPE_CHECK in function: OH_JSVM_RunScript
106CHECK_SCOPE in function: OH_JSVM_IsBoolean
107JSVM OH_JSVM_IsBoolean: success: 1
108```
109
110- 在错误的HandleScope内调用JSVM_Value类型变量。
111
112```cpp
113static int32_t TestJSVM()
114{
115    JSVM_InitOptions initOptions = {0};
116    JSVM_VM vm;
117    JSVM_Env env = nullptr;
118    JSVM_VMScope vmScope;
119    JSVM_EnvScope envScope;
120    JSVM_HandleScope handleScope;
121
122    // 初始化JavaScript引擎实例
123    if (g_aa == 0) {
124        g_aa++;
125        CHECK(OH_JSVM_Init(&initOptions));
126    }
127    // 创建JSVM环境
128    CHECK(OH_JSVM_CreateVM(nullptr, &vm));
129    CHECK(OH_JSVM_CreateEnv(vm, sizeof(descriptor) / sizeof(descriptor[0]), descriptor, &env));
130    // 打开JSVM_SCOPE_CHECK校验选项
131    CHECK(OH_JSVM_SetDebugOption(env, JSVM_SCOPE_CHECK, true));
132    CHECK(OH_JSVM_OpenVMScope(vm, &vmScope));
133    CHECK_RET(OH_JSVM_OpenEnvScope(env, &envScope));
134    // 打开HandleScope
135    CHECK_RET(OH_JSVM_OpenHandleScope(env, &handleScope));
136
137    // 通过script调用测试函数
138    JSVM_Script script;
139    JSVM_Value jsSrc, result;
140    CHECK_RET(OH_JSVM_CreateStringUtf8(env, srcCallNative, JSVM_AUTO_LENGTH, &jsSrc));
141    CHECK_RET(OH_JSVM_CompileScript(env, jsSrc, nullptr, 0, true, nullptr, &script));
142    CHECK_RET(OH_JSVM_RunScript(env, script, &result));
143
144    bool boolResult = true;
145
146    // 销毁JSVM环境
147    // 关闭HandleScope
148    CHECK_RET(OH_JSVM_CloseHandleScope(env, handleScope));
149    // OH_JSVM_IsBoolean接口在错误的HandleScope调用JSVM_Value类型变量result
150    JSVM_Status status = OH_JSVM_IsBoolean(env, result, &boolResult);
151    CHECK_RET(OH_JSVM_CloseEnvScope(env, envScope));
152    CHECK(OH_JSVM_CloseVMScope(vm, vmScope));
153    // 关闭JSVM_SCOPE_CHECK校验选项
154    CHECK(OH_JSVM_SetDebugOption(env, JSVM_SCOPE_CHECK, false));
155    CHECK(OH_JSVM_DestroyEnv(env));
156    CHECK(OH_JSVM_DestroyVM(vm));
157    return 0;
158}
159```
160**执行结果**
161
162程序崩溃,有cppcrash日志生成,在hilog中可以检索到类似以下的信息:
163```
164JSVM Fatal Error Position : "../../../../../../../arkcompiler/jsvm/src/js_native_api_v8.cpp":4537
165JSVM Fatal Error Message : "Run in wrong HandleScope"
166```