我一直试图将V8 javascript引擎嵌入到我的项目中。在大多数情况下,这是成功的,但有一个问题似乎没有消失,我不知道是什么原因。
当我编写一个简单的for循环来迭代包含数千个条目的数组时,V8分段错误。瓦兰德说:
==38120== Invalid read of size 8
==38120== at 0x525F654: v8::internal::Isolate::main_thread_local_heap() (in /home/ktp/oma/lib/liboma_js.so)
==38120== by 0x53A532A: v8::internal::interpreter::BytecodeArrayIterator::BytecodeArrayIterator(v8::internal::Handle<v8::internal::BytecodeArray>, int) (in /home/ktp/oma/lib/liboma_js.so)
==38120== by 0x5C01534: v8::internal::baseline::BaselineCompiler::BaselineCompiler(v8::internal::LocalIsolate*, v8::internal::Handle<v8::internal::SharedFunctionInfo>, v8::internal::Handle<v8::internal::BytecodeArray>) (in /home/ktp/oma/lib/liboma_js.so)
==38120== by 0x5C143E9: v8::internal::GenerateBaselineCode(v8::internal::Isolate*, v8::internal::Handle<v8::internal::SharedFunctionInfo>) (in /home/ktp/oma/lib/liboma_js.so)
==38120== by 0x51D796E: v8::internal::Compiler::CompileSharedWithBaseline(v8::internal::Isolate*, v8::internal::Handle<v8::internal::SharedFunctionInfo>, v8::internal::Compiler::ClearExceptionFlag, v8::internal::IsCompiledScope*) (in /home/ktp/oma/lib/liboma_js.so)
==38120== by 0x51D7CF5: v8::internal::Compiler::CompileBaseline(v8::internal::Isolate*, v8::internal::Handle<v8::internal::JSFunction>, v8::internal::Compiler::ClearExceptionFlag, v8::internal::IsCompiledScope*) (in /home/ktp/oma/lib/liboma_js.so)
==38120== by 0x5BFF355: v8::internal::baseline::BaselineBatchCompiler::CompileBatch(v8::internal::Handle<v8::internal::JSFunction>) (in /home/ktp/oma/lib/liboma_js.so)
==38120== by 0x5BFEF8E: v8::internal::baseline::BaselineBatchCompiler::EnqueueFunction(v8::internal::Handle<v8::internal::JSFunction>) (in /home/ktp/oma/lib/liboma_js.so)
==38120== by 0x5276501: v8::internal::TieringManager::OnInterruptTick(v8::internal::Handle<v8::internal::JSFunction>) (in /home/ktp/oma/lib/liboma_js.so)
==38120== by 0x5D8BA69: v8::internal::Runtime_BytecodeBudgetInterruptWithStackCheck(int, unsigned long*, v8::internal::Isolate*) (in /home/ktp/oma/lib/liboma_js.so)
==38120== by 0x5AEA9F7: Builtins_CEntry_Return1_DontSaveFPRegs_ArgvOnStack_NoBuiltinExit (in /home/ktp/oma/lib/liboma_js.so)
==38120== by 0x5B98E62: Builtins_JumpLoopHandler (in /home/ktp/oma/lib/liboma_js.so)
==38120== Address 0xf100 is not stack'd, malloc'd or (recently) free'd
我的绑定和设置很大程度上是基于v8.dev的嵌入指南中的示例,尽管它封装在一个类中,并且使用V8:platform::PumpMessageLoop()调用了epoll循环中运行在与V8相同线程中的timerfd。
JS代码导致val差利消息是这样的:
var g = new Array(1024*16);
g.fill(0);
for(var i in g)
{
i+i;
}
当数组的大小为最大1024*7时,JS代码工作,当我打印迭代计数时,它在7500左右崩溃。
编辑:这个C++代码提供了相同的错误,并且是我使用的代码的缩短版本:
#include <v8.h>
#include <v8-context.h>
#include <v8-isolate.h>
#include <v8-local-handle.h>
#include <v8-primitive.h>
#include <v8-script.h>
#include <v8-json.h>
#include <libplatform/libplatform.h>
int main(int argc, char *argv[])
{
// Initialize V8.
v8::V8::InitializeICUDefaultLocation(argv[0]);
v8::V8::InitializeExternalStartupData(argv[0]);
std::unique_ptr<v8::Platform> platform = v8::platform::NewDefaultPlatform();
v8::V8::InitializePlatform(platform.get());
v8::V8::Initialize();
// Create a new Isolate and make it the current one.
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = v8::ArrayBuffer::Allocator::NewDefaultAllocator();
v8::Isolate* isolate = v8::Isolate::New(create_params);
std::string src = R"(
for(var i=0;i<1024*8;i++)
{
}
)";
{
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> ctx = v8::Context::New(isolate);
v8::Context::Scope context_scope(ctx);
v8::MaybeLocal<v8::String> vsrc = v8::String::NewFromUtf8(isolate, src.c_str(), v8::NewStringType::kNormal, static_cast<int>(src.size()));
v8::MaybeLocal<v8::Script> script = v8::Script::Compile(ctx, vsrc.ToLocalChecked()).ToLocalChecked();
if(script.IsEmpty())
{
printf("error0\n");
}
v8::MaybeLocal<v8::Value> result = script.ToLocalChecked()->Run(ctx);
if(result.IsEmpty())
{
printf("error1\n");
}
}
isolate->Dispose();
v8::V8::Dispose();
v8::V8::DisposePlatform();
delete create_params.array_buffer_allocator;
return 0;
}
示例是用以下命令编译的:
g++ -c /home/ktp/oma/src/jx.cpp -DV8_COMPRESS_POINTERS -DV8_ENABLE_SANDBOX -I/home/ktp/v8/v8/include/ -fPIC -Wall -g -std=c++17
g++ -o /home/ktp/oma/bin/jx jx.o -DV8_COMPRESS_POINTERS -DV8_ENABLE_SANDBOX -lv8_monolith -ldl -lpthread -L/home/ktp/v8/v8/out.gn/x64.release.sample/obj/
我不完全确定V8版本,但我在30.8上构建了它。d8控制台显示V8版本为10.7.0。
V8是根据v8.dev和https://v8.dev/docs/source-code#using-git上的说明构建的:
tools/dev/v8gen.py x64.release.sample
ninja -C out.gn/x64.release.sample v8_monolith
gn args说:
dcheck_always_on = false
is_component_build = false
is_debug = false
target_cpu = "x64"
use_custom_libcxx = false
v8_enable_sandbox = true
v8_monolithic = true
v8_use_external_startup_data = false
发布于 2022-09-19 19:02:05
您需要输入Isolate
。您可以使用isolate->Enter()
和isolate->Exit()
,也可以使用v8::Isolate::Scope isolate_scope(isolate)
(这是这两个步骤的方便包装器),介于创建隔离和创建HandleScope之间。
帮助你自己:
gn args out/x64.release.sample
)更改为is_debug = true
,以获得调试版本,并重新编译。gdb -args /home/ktp/oma/bin/jx
(或您喜欢使用的调试器)。Debug check failed: (isolate) != nullptr
。如果您请求回溯跟踪,您将看到这发生在V8内部的某个地方;幸运的是,在这种情况下,细节并不重要。Isolate::Scope
显然是一个潜在的嫌疑人。https://stackoverflow.com/questions/73774024
复制相似问题