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```