harmony 鸿蒙使用JSVM-API接口进行debug操作

  • 2025-06-12
  • 浏览 (4)

使用JSVM-API接口进行debug操作

简介

JSVM-API中提供接口,可以启用/禁用特定JSVM_Env下的指定debug选项。目前支持的debug选项有JSVM_SCOPE_CHECK。  

debug选项介绍

debug选项皆为JSVM_DebugOption类型。  

JSVM_SCOPE_CHECK

  • 开发者在开发时,可能会出现在HandleScope结束后,调用上一次HandleScope内的JSVM_Value类型变量,导致程序崩溃。JSVM_SCOPE_CHECK为scope校验手段,校验当前调用的JSVM_Value类型变量是否超出HandleScope作用域,如果超出,则抛出错误“Run in wrong HandleScope”。

  • 开启该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”。  

    接口说明

接口 功能说明
OH_JSVM_SetDebugOption 启用/禁用特定JSVM_Env的指定debug选项。传入的debug选项参数debugOption必须为JSVM_DebugOption类型,布尔值参数isEnabled用于控制是否开启该debug选项。此API仅供debug时使用,开启后可能会带来性能下降。

 

使用示例

JSVM-API接口开发流程参考使用JSVM-API实现JS与C/C++语言交互开发流程,本文仅对接口对应C++相关代码进行展示。

JSVM_DebugOption

仅需替换使用JSVM-API实现JS与C/C++语言交互开发流程示例代码中的“TestJSVM()”函数即可运行。

  • 在正确的HandleScope内调用JSVM_Value类型变量。

    static int32_t TestJSVM()
    {
    JSVM_InitOptions initOptions = {0};
    JSVM_VM vm;
    JSVM_Env env = nullptr;
    JSVM_VMScope vmScope;
    JSVM_EnvScope envScope;
    JSVM_HandleScope handleScope;
    
    
    // 初始化JavaScript引擎实例
    if (g_aa == 0) {
        g_aa++;
        CHECK(OH_JSVM_Init(&initOptions));
    }
    // 创建JSVM环境
    CHECK(OH_JSVM_CreateVM(nullptr, &vm));
    CHECK(OH_JSVM_CreateEnv(vm, sizeof(descriptor) / sizeof(descriptor[0]), descriptor, &env));
    // 打开JSVM_SCOPE_CHECK校验选项
    CHECK(OH_JSVM_SetDebugOption(env, JSVM_SCOPE_CHECK, true));
    CHECK(OH_JSVM_OpenVMScope(vm, &vmScope));
    CHECK_RET(OH_JSVM_OpenEnvScope(env, &envScope));
    // 打开HandleScope
    CHECK_RET(OH_JSVM_OpenHandleScope(env, &handleScope));
    
    
    // 通过script调用测试函数
    JSVM_Script script;
    JSVM_Value jsSrc, result;
    CHECK_RET(OH_JSVM_CreateStringUtf8(env, srcCallNative, JSVM_AUTO_LENGTH, &jsSrc));
    CHECK_RET(OH_JSVM_CompileScript(env, jsSrc, nullptr, 0, true, nullptr, &script));
    CHECK_RET(OH_JSVM_RunScript(env, script, &result));
    
    
    bool boolResult = true;
    // OH_JSVM_IsBoolean接口调用JSVM_Value类型变量result
    JSVM_Status status = OH_JSVM_IsBoolean(env, result, &boolResult);
    if (status != JSVM_OK) {
        OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_IsBoolean: failed");
    } else {
        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_IsBoolean: success: %{public}d", boolResult);
    }
    
    
    // 销毁JSVM环境
    // 关闭HandleScope
    CHECK_RET(OH_JSVM_CloseHandleScope(env, handleScope));
    CHECK_RET(OH_JSVM_CloseEnvScope(env, envScope));
    CHECK(OH_JSVM_CloseVMScope(vm, vmScope));
    // 关闭JSVM_SCOPE_CHECK校验选项
    CHECK(OH_JSVM_SetDebugOption(env, JSVM_SCOPE_CHECK, false));
    CHECK(OH_JSVM_DestroyEnv(env));
    CHECK(OH_JSVM_DestroyVM(vm));
    return 0;
    }
    

    执行结果

hilog中有以下结果输出:

ADD_VAL_TO_SCOPE_CHECK in function: NewString
CHECK_SCOPE in function: OH_JSVM_CompileScript
ADD_VAL_TO_SCOPE_CHECK in function: OH_JSVM_GetCbInfo
ADD_VAL_TO_SCOPE_CHECK in function: OH_JSVM_GetCbInfo
ADD_VAL_TO_SCOPE_CHECK in function: OH_JSVM_GetCbInfo
CHECK_SCOPE in function: OH_JSVM_StrictEquals
CHECK_SCOPE in function: OH_JSVM_StrictEquals
JSVM OH_JSVM_StrictEquals: success: 0
ADD_VAL_TO_SCOPE_CHECK in function: OH_JSVM_GetBoolean
ADD_VAL_TO_SCOPE_CHECK in function: OH_JSVM_RunScript
CHECK_SCOPE in function: OH_JSVM_IsBoolean
JSVM OH_JSVM_IsBoolean: success: 1
  • 在错误的HandleScope内调用JSVM_Value类型变量。
static int32_t TestJSVM()
{
    JSVM_InitOptions initOptions = {0};
    JSVM_VM vm;
    JSVM_Env env = nullptr;
    JSVM_VMScope vmScope;
    JSVM_EnvScope envScope;
    JSVM_HandleScope handleScope;

    // 初始化JavaScript引擎实例
    if (g_aa == 0) {
        g_aa++;
        CHECK(OH_JSVM_Init(&initOptions));
    }
    // 创建JSVM环境
    CHECK(OH_JSVM_CreateVM(nullptr, &vm));
    CHECK(OH_JSVM_CreateEnv(vm, sizeof(descriptor) / sizeof(descriptor[0]), descriptor, &env));
    // 打开JSVM_SCOPE_CHECK校验选项
    CHECK(OH_JSVM_SetDebugOption(env, JSVM_SCOPE_CHECK, true));
    CHECK(OH_JSVM_OpenVMScope(vm, &vmScope));
    CHECK_RET(OH_JSVM_OpenEnvScope(env, &envScope));
    // 打开HandleScope
    CHECK_RET(OH_JSVM_OpenHandleScope(env, &handleScope));

    // 通过script调用测试函数
    JSVM_Script script;
    JSVM_Value jsSrc, result;
    CHECK_RET(OH_JSVM_CreateStringUtf8(env, srcCallNative, JSVM_AUTO_LENGTH, &jsSrc));
    CHECK_RET(OH_JSVM_CompileScript(env, jsSrc, nullptr, 0, true, nullptr, &script));
    CHECK_RET(OH_JSVM_RunScript(env, script, &result));

    bool boolResult = true;

    // 销毁JSVM环境
    // 关闭HandleScope
    CHECK_RET(OH_JSVM_CloseHandleScope(env, handleScope));
    // OH_JSVM_IsBoolean接口在错误的HandleScope调用JSVM_Value类型变量result
    JSVM_Status status = OH_JSVM_IsBoolean(env, result, &boolResult);
    CHECK_RET(OH_JSVM_CloseEnvScope(env, envScope));
    CHECK(OH_JSVM_CloseVMScope(vm, vmScope));
    // 关闭JSVM_SCOPE_CHECK校验选项
    CHECK(OH_JSVM_SetDebugOption(env, JSVM_SCOPE_CHECK, false));
    CHECK(OH_JSVM_DestroyEnv(env));
    CHECK(OH_JSVM_DestroyVM(vm));
    return 0;
}

执行结果

程序崩溃,有cppcrash日志生成,在hilog中可以检索到类似以下的信息:

JSVM Fatal Error Position : "../../../../../../../arkcompiler/jsvm/src/js_native_api_v8.cpp":4537
JSVM Fatal Error Message : "Run in wrong HandleScope"

你可能感兴趣的鸿蒙文章

harmony 鸿蒙napi

harmony 鸿蒙使用命令行CMake构建NDK工程

harmony 鸿蒙使用DevEco Studio模板构建NDK工程

harmony 鸿蒙NDK工程构建概述

harmony 鸿蒙在NDK工程中使用预构建库

harmony 鸿蒙C/C++标准库机制概述

harmony 鸿蒙CPU特性

harmony 鸿蒙创建NDK工程

harmony 鸿蒙C/C++内存错误检测

harmony 鸿蒙通过DevEco Studio调试

0  赞