7761922b创建于 2025年9月26日历史提交

Performing Debug Operations Using JSVM-API

Overview

JSVM-API provides an API to enable or disable a specified debug option in a specific JSVM_Env. Currently, JSVM_SCOPE_CHECK is supported.

Debug Options

All debug options are of the JSVM_DebugOption type.

JSVM_SCOPE_CHECK

  • During development, you may call JSVM_Value variables in the previous HandleScope after it ends, causing application crash. JSVM_SCOPE_CHECK is a method for checking whether the called JSVM_Value variable exceeds the scope of HandleScope. If yes, the error "Run in wrong HandleScope" is reported.
  • After this debug option is enabled, if JSVM-API creates a JSVM_Value, ADD_VAL_TO_SCOPE_CHECK in function: [function name] is output in HiLog logs, for example, ADD_VAL_TO_SCOPE_CHECK in function: OH_JSVM_GetBoolean. If JSVM-API uses JSVM_Value, CHECK_SCOPE in function: [function name] is output in HiLog logs, indicating that HandleScope verification is performed on the used JSVM_Value, for example, CHECK_SCOPE in function: OH_JSVM_IsBoolean.

Available APIs

Name Description
OH_JSVM_SetDebugOption Enables or disables a specified debug option in a specific JSVM_Env. The input debugOption must be of the JSVM_DebugOption type. The Boolean parameter isEnabled is used to control whether to enable the debug option. This API is used only for debugging. Enabling this API may cause performance deterioration.

Sample Code

If you are just starting out with JSVM-API, see JSVM-API Development Process. The following demonstrates only the C++ code involved in using the API.

JSVM_DebugOption

Replace the TestJSVM() function in the sample code of JSVM-API Development Process.

  • Call the JSVM_Value variable in the correct HandleScope.
static int32_t TestJSVM()
{
    JSVM_InitOptions initOptions = {0};
    JSVM_VM vm;
    JSVM_Env env = nullptr;
    JSVM_VMScope vmScope;
    JSVM_EnvScope envScope;
    JSVM_HandleScope handleScope;

    // Initialize the JSVM instance.
    if (g_aa == 0) {
        g_aa++;
        CHECK(OH_JSVM_Init(&initOptions));
    }
    // Create a JSVM environment.
    CHECK(OH_JSVM_CreateVM(nullptr, &vm));
    CHECK(OH_JSVM_CreateEnv(vm, sizeof(descriptor) / sizeof(descriptor[0]), descriptor, &env));
    // Enable the JSVM_SCOPE_CHECK option.
    CHECK(OH_JSVM_SetDebugOption(env, JSVM_SCOPE_CHECK, true));
    CHECK(OH_JSVM_OpenVMScope(vm, &vmScope));
    CHECK_RET(OH_JSVM_OpenEnvScope(env, &envScope));
    // Open HandleScope.
    CHECK_RET(OH_JSVM_OpenHandleScope(env, &handleScope));

    // Call the demo function using the 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;
    // The OH_JSVM_IsBoolean API calls the JSVM_Value variable 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);
    }

    // Destroy the JSVM environment.
    // Close HandleScope.
    CHECK_RET(OH_JSVM_CloseHandleScope(env, handleScope));
    CHECK_RET(OH_JSVM_CloseEnvScope(env, envScope));
    CHECK(OH_JSVM_CloseVMScope(vm, vmScope));
    // Disable the JSVM_SCOPE_CHECK option.
    CHECK(OH_JSVM_SetDebugOption(env, JSVM_SCOPE_CHECK, false));
    CHECK(OH_JSVM_DestroyEnv(env));
    CHECK(OH_JSVM_DestroyVM(vm));
    return 0;
}

Execution result

The following information is displayed in the 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
  • The JSVM_Value variable is called in an incorrect HandleScope.
static int32_t TestJSVM()
{
    JSVM_InitOptions initOptions = {0};
    JSVM_VM vm;
    JSVM_Env env = nullptr;
    JSVM_VMScope vmScope;
    JSVM_EnvScope envScope;
    JSVM_HandleScope handleScope;

    // Initialize the JSVM instance.
    if (g_aa == 0) {
        g_aa++;
        CHECK(OH_JSVM_Init(&initOptions));
    }
    // Create a JSVM environment.
    CHECK(OH_JSVM_CreateVM(nullptr, &vm));
    CHECK(OH_JSVM_CreateEnv(vm, sizeof(descriptor) / sizeof(descriptor[0]), descriptor, &env));
    // Enable the JSVM_SCOPE_CHECK option.
    CHECK(OH_JSVM_SetDebugOption(env, JSVM_SCOPE_CHECK, true));
    CHECK(OH_JSVM_OpenVMScope(vm, &vmScope));
    CHECK_RET(OH_JSVM_OpenEnvScope(env, &envScope));
    // Open HandleScope.
    CHECK_RET(OH_JSVM_OpenHandleScope(env, &handleScope));

    // Call the demo function using the 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;

    // Destroy the JSVM environment.
    // Close HandleScope.
    CHECK_RET(OH_JSVM_CloseHandleScope(env, handleScope));
    // The OH_JSVM_IsBoolean API calls the JSVM_Value variable result in the incorrect HandleScope.
    JSVM_Status status = OH_JSVM_IsBoolean(env, result, &boolResult);
    CHECK_RET(OH_JSVM_CloseEnvScope(env, envScope));
    CHECK(OH_JSVM_CloseVMScope(vm, vmScope));
    // Disable the JSVM_SCOPE_CHECK option.
    CHECK(OH_JSVM_SetDebugOption(env, JSVM_SCOPE_CHECK, false));
    CHECK(OH_JSVM_DestroyEnv(env));
    CHECK(OH_JSVM_DestroyVM(vm));
    return 0;
}

Execution result

The application crashes, the cppcrash log is generated, and the following information is displayed in HiLog:

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