簡體   English   中英

V8 Embedded,多次運行迭代后出現分段錯誤

[英]V8 Embedded, Segmentation Fault after more run iteration

我正在嘗試在 C++ 中使用 v8,我想在主線程中編譯 js 代碼,然后將compiled_script傳遞給執行程序(子線程)。 Run執行過程將在線程中運行。

故事:編譯過程很昂貴,我需要性能,因此我會在開始時緩存所有編譯的腳本並將它們傳遞給不同的線程執行。

為了測試這個場景,我只創建了一個線程並將編譯的腳本傳遞給它,在for循環中迭代 1500 次后,程序退出並出現分段錯誤錯誤。

問題與線程有關,如果我將執行移到線程外,它將成功結束。

我進行了更多調查,但找不到任何解決方案。

完整代碼:

#include "include/libplatform/libplatform.h"
#include "include/v8.h"
#include <future>
#include <iostream>
#include <string>
#include <thread>

bool ExecuteScript(v8::Isolate *isolate,
                   v8::MaybeLocal<v8::Script> compiled_script) {

  v8::HandleScope handle_scope(isolate);
  v8::TryCatch try_catch(isolate);
  v8::Local<v8::Context> context(isolate->GetCurrentContext());

  v8::Local<v8::Value> result;
  v8::Local<v8::Script> c = compiled_script.FromMaybe(v8::Local<v8::Script>());
  if (c.IsEmpty())
    std::cout << "Compile Script is Empty" << std::endl;
  if (context.IsEmpty())
    std::cout << "Conetxt is Empty" << std::endl;
  auto x = c->Run(context);
  if (!x.ToLocal(&result)) {
    v8::String::Utf8Value error(isolate, try_catch.Exception());
    std::cout << *error << std::endl;
    return false;
  }
  return true;
}

v8::MaybeLocal<v8::Script> CompileScript(v8::Isolate *isolate,
                                         v8::Local<v8::String> raw_source) {
  v8::ScriptCompiler::Source source(raw_source);
  auto unboundedScript =
      v8::ScriptCompiler::CompileUnboundScript(
          isolate, &source,
          v8::ScriptCompiler::CompileOptions::kNoCompileOptions)
          .ToLocalChecked();

  return unboundedScript->BindToCurrentContext();
}

int main() {
  v8::Isolate::CreateParams create_params;
  v8::Isolate *isolate;
  std::unique_ptr<v8::Platform> platform;
  v8::Global<v8::Context> context_;

  v8::V8::InitializeICUDefaultLocation(".");
  v8::V8::InitializeExternalStartupData(".");
  platform = v8::platform::NewDefaultPlatform();
  v8::V8::InitializePlatform(platform.get());
  v8::V8::Initialize();

  create_params.array_buffer_allocator =
      v8::ArrayBuffer::Allocator::NewDefaultAllocator();
  isolate = v8::Isolate::New(create_params);
  v8::Isolate::Scope isolate_scope(isolate);
  v8::HandleScope scope(isolate);

  v8::Local<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate);

  v8::Local<v8::Context> context = v8::Context::New(isolate, NULL, global);
  context_.Reset(isolate, context);

  {

    auto tt = std::async(std::launch::async, [&]() {
      v8::Locker locker(isolate);
      v8::HandleScope thread_scope(isolate);
      v8::Context::Scope context_scope(context);
      v8::MaybeLocal<v8::Script> compliedScript = CompileScript(
          isolate,
          v8::String::NewFromUtf8Literal(isolate, "var j=0; while(j<5) j++; "));
      for (int i = 0; i < 1000000; i++) {
        std::cout << i << std::endl;
        if (!ExecuteScript(isolate, compliedScript)) {
          std::cout << "Execution Error" << std::endl;
          return;
        }
      }
    });
    tt.wait();
  }

  v8::V8::Dispose();
  v8::V8::ShutdownPlatform();
  delete create_params.array_buffer_allocator;
  std::cout << "Exit Normal" << std::endl;
  return 0;
}

我怎樣才能解決這個問題 ?

編輯1:

  1. 代碼清理
  2. valgrind 內存泄漏結果:
==2588106== Warning: set address range perms: large range [0x2bf200000000, 0x2bf400000000) (noaccess)
==2588106== Warning: set address range perms: large range [0x2bf200000000, 0x2bf400000000) (noaccess)
==2588106== Warning: set address range perms: large range [0x2bf200000000, 0x2bf300000000) (noaccess)==2588106== Thread 9:
==2588106== Invalid read of size 8
==2588106==    at 0x2D7B24: v8::internal::Isolate::main_thread_local_heap() (in /home/linux/v8)
==2588106==    by 0x3F07EA: v8::internal::interpreter::BytecodeArrayIterator::BytecodeArrayIterator(v8::internal::Handle<v8::internal::BytecodeArray>, int) (in /home/linux/v8)
==2588106==    by 0xD7EC2B: v8::internal::compiler::BytecodeGraphBuilder::BytecodeGraphBuilder(v8::internal::compiler::JSHeapBroker*, v8::internal::Zone*, v8::internal::compiler::NativeContextRef const&, v8::internal::compiler::SharedFunctionInfoRef const&, v8::internal::compiler::FeedbackCellRef const&, v8::internal::BytecodeOffset, v8::internal::compiler::JSGraph*, v8::internal::compiler::CallFrequency const&, v8::internal::compiler::SourcePositionTable*, int, v8::internal::CodeKind, v8::base::Flags<v8::internal::compiler::BytecodeGraphBuilderFlag, int>, v8::internal::TickCounter*, v8::internal::compiler::ObserveNodeInfo const&) (in /home/linux/v8)
==2588106==    by 0xD92621: v8::internal::compiler::BuildGraphFromBytecode(v8::internal::compiler::JSHeapBroker*, v8::internal::Zone*, v8::internal::compiler::SharedFunctionInfoRef const&, v8::internal::compiler::FeedbackCellRef const&, v8::internal::BytecodeOffset, v8::internal::compiler::JSGraph*, v8::internal::compiler::CallFrequency const&, v8::internal::compiler::SourcePositionTable*, int, v8::internal::CodeKind, v8::base::Flags<v8::internal::compiler::BytecodeGraphBuilderFlag, int>, v8::internal::TickCounter*, v8::internal::compiler::ObserveNodeInfo const&) (in /home/linux/v8)
==2588106==    by 0x80E6FD: v8::internal::compiler::GraphBuilderPhase::Run(v8::internal::compiler::PipelineData*, v8::internal::Zone*) (in /home/linux/v8)
==2588106==    by 0x7FFE81: void v8::internal::compiler::PipelineImpl::Run<v8::internal::compiler::GraphBuilderPhase>() (in /home/linux/v8)
==2588106==    by 0x7FC747: v8::internal::compiler::PipelineImpl::CreateGraph() (in /home/linux/v8)
==2588106==    by 0x7FC10F: v8::internal::compiler::PipelineCompilationJob::PrepareJobImpl(v8::internal::Isolate*) (in /home/linux/v8)
==2588106==    by 0x253924: v8::internal::OptimizedCompilationJob::PrepareJob(v8::internal::Isolate*) (in /home/linux/v8)
==2588106==    by 0x25F4E5: v8::internal::(anonymous namespace)::GetOptimizedCodeLater(std::unique_ptr<v8::internal::OptimizedCompilationJob, std::default_delete<v8::internal::OptimizedCompilationJob> >, v8::internal::Isolate*, v8::internal::OptimizedCompilationInfo*, v8::internal::CodeKind, v8::internal::Handle<v8::internal::JSFunction>) (in /home/linux/v8)
==2588106==    by 0x25862D: v8::internal::(anonymous namespace)::GetOptimizedCode(v8::internal::Handle<v8::internal::JSFunction>, v8::internal::ConcurrencyMode, v8::internal::CodeKind, v8::internal::BytecodeOffset, v8::internal::JavaScriptFrame*) (in /home/linux/v8)
==2588106==    by 0x259905: v8::internal::Compiler::CompileOptimized(v8::internal::Isolate*, v8::internal::Handle<v8::internal::JSFunction>, v8::internal::ConcurrencyMode, v8::internal::CodeKind) (in /home/linux/v8)
==2588106==  Address 0xc1f8 is not stack'd, malloc'd or (recently) free'd
==2588106==
==2588106==
==2588106==  Access not within mapped region at address 0xC1F8
==2588106==    at 0x2D7B24: v8::internal::Isolate::main_thread_local_heap() (in /home/linux/v8)
==2588106==    by 0x3F07EA: v8::internal::interpreter::BytecodeArrayIterator::BytecodeArrayIterator(v8::internal::Handle<v8::internal::BytecodeArray>, int) (in /home/linux/v8)
==2588106==    by 0xD7EC2B: v8::internal::compiler::BytecodeGraphBuilder::BytecodeGraphBuilder(v8::internal::compiler::JSHeapBroker*, v8::internal::Zone*, v8::internal::compiler::NativeContextRef const&, v8::internal::compiler::SharedFunctionInfoRef const&, v8::internal::compiler::FeedbackCellRef const&, v8::internal::BytecodeOffset, v8::internal::compiler::JSGraph*, v8::internal::compiler::CallFrequency const&, v8::internal::compiler::SourcePositionTable*, int, v8::internal::CodeKind, v8::base::Flags<v8::internal::compiler::BytecodeGraphBuilderFlag, int>, v8::internal::TickCounter*, v8::internal::compiler::ObserveNodeInfo const&) (in /home/linux/v8)
==2588106==    by 0xD92621: v8::internal::compiler::BuildGraphFromBytecode(v8::internal::compiler::JSHeapBroker*, v8::internal::Zone*, v8::internal::compiler::SharedFunctionInfoRef const&, v8::internal::compiler::FeedbackCellRef const&, v8::internal::BytecodeOffset, v8::internal::compiler::JSGraph*, v8::internal::compiler::CallFrequency const&, v8::internal::compiler::SourcePositionTable*, int, v8::internal::CodeKind, v8::base::Flags<v8::internal::compiler::BytecodeGraphBuilderFlag, int>, v8::internal::TickCounter*, v8::internal::compiler::ObserveNodeInfo const&) (in /home/linux/v8)
==2588106==    by 0x80E6FD: v8::internal::compiler::GraphBuilderPhase::Run(v8::internal::compiler::PipelineData*, v8::internal::Zone*) (in /home/linux/v8)
==2588106==    by 0x7FFE81: void v8::internal::compiler::PipelineImpl::Run<v8::internal::compiler::GraphBuilderPhase>() (in /home/linux/v8)
==2588106==    by 0x7FC747: v8::internal::compiler::PipelineImpl::CreateGraph() (in /home/linux/v8)
==2588106==    by 0x7FC10F: v8::internal::compiler::PipelineCompilationJob::PrepareJobImpl(v8::internal::Isolate*) (in /home/linux/v8)
==2588106==    by 0x253924: v8::internal::OptimizedCompilationJob::PrepareJob(v8::internal::Isolate*) (in /home/linux/v8)
==2588106==    by 0x25F4E5: v8::internal::(anonymous namespace)::GetOptimizedCodeLater(std::unique_ptr<v8::internal::OptimizedCompilationJob, std::default_delete<v8::internal::OptimizedCompilationJob> >, v8::internal::Isolate*, v8::internal::OptimizedCompilationInfo*, v8::internal::CodeKind, v8::internal::Handle<v8::internal::JSFunction>) (in /home/linux/v8)
==2588106==    by 0x25862D: v8::internal::(anonymous namespace)::GetOptimizedCode(v8::internal::Handle<v8::internal::JSFunction>, v8::internal::ConcurrencyMode, v8::internal::CodeKind, v8::internal::BytecodeOffset, v8::internal::JavaScriptFrame*) (in /home/linux/v8)
==2588106==    by 0x259905: v8::internal::Compiler::CompileOptimized(v8::internal::Isolate*, v8::internal::Handle<v8::internal::JSFunction>, v8::internal::ConcurrencyMode, v8::internal::CodeKind) (in /home/linux/v8)
==2588106==  If you believe this happened as a result of a stack
==2588106==  overflow in your program's main thread (unlikely but
==2588106==  possible), you can try to increase the size of the
==2588106==  main thread stack using the --main-stacksize= flag.
==2588106==  The main thread stack size used in this run was 8388608.
==2588106==
==2588106== HEAP SUMMARY:
==2588106==     in use at exit: 541,595 bytes in 1,411 blocks
==2588106==   total heap usage: 2,072 allocs, 661 frees, 1,155,883 bytes allocated
==2588106==
==2588106== Thread 1:
==2588106== 1 bytes in 1 blocks are still reachable in loss record 1 of 1,252
==2588106==    at 0x483CFE3: operator new(unsigned long) (vg_replace_malloc.c:417)
==2588106==    by 0x330BFC: v8::internal::Heap::SetUpSpaces() (in /home/linux/v8)
==2588106==    by 0x2D60B7: v8::internal::Isolate::Init(v8::internal::SnapshotData*, v8::internal::SnapshotData*, bool) (in /home/linux/v8)
==2588106==    by 0x2D6C88: v8::internal::Isolate::InitWithSnapshot(v8::internal::SnapshotData*, v8::internal::SnapshotData*, bool) (in /home/linux/v8)
==2588106==    by 0x5F789D: v8::internal::Snapshot::Initialize(v8::internal::Isolate*) (in /home/linux/v8)
==2588106==    by 0x245612: v8::Isolate::Initialize(v8::Isolate*, v8::Isolate::CreateParams const&) (in /home/linux/v8)
==2588106==    by 0x24581C: v8::Isolate::New(v8::Isolate::CreateParams const&) (in /home/linux/v8)
==2588106==    by 0x2074BB: main (in /home/linux/v8)
==2588106==
==2588106== 1 bytes in 1 blocks are still reachable in loss record 2 of 1,252
==2588106==    at 0x483CFE3: operator new(unsigned long) (vg_replace_malloc.c:417)
==2588106==    by 0x330F6A: v8::internal::Heap::SetUpSpaces() (in /home/linux/v8)
==2588106==    by 0x2D60B7: v8::internal::Isolate::Init(v8::internal::SnapshotData*, v8::internal::SnapshotData*, bool) (in /home/linux/v8)
==2588106==    by 0x2D6C88: v8::internal::Isolate::InitWithSnapshot(v8::internal::SnapshotData*, v8::internal::SnapshotData*, bool) (in /home/linux/v8)
==2588106==    by 0x5F789D: v8::internal::Snapshot::Initialize(v8::internal::Isolate*) (in /home/linux/v8)
==2588106==    by 0x245612: v8::Isolate::Initialize(v8::Isolate*, v8::Isolate::CreateParams const&) (in /home/linux/v8)
==2588106==    by 0x24581C: v8::Isolate::New(v8::Isolate::CreateParams const&) (in /home/linux/v8)
==2588106==    by 0x2074BB: main (in /home/linux/v8)
==2588106==
==2588106== 1 bytes in 1 blocks are still reachable in loss record 3 of 1,252
==2588106==    at 0x483EA5D: operator new[](unsigned long, std::nothrow_t const&) (vg_replace_malloc.c:658)
==2588106==    by 0x53082E: v8::internal::String::ToCString(v8::internal::AllowNullsFlag, v8::internal::RobustnessFlag, int, int, int*) (in /home/linux/v8)
==2588106==    by 0x530C0A: v8::internal::String::ToCString(v8::internal::AllowNullsFlag, v8::internal::RobustnessFlag, int*) (in /home/linux/v8)
==2588106==    by 0x51AE2F: v8::internal::SharedFunctionInfo::DebugNameCStr() (in /home/linux/v8)
==2588106==    by 0x27839C: v8::internal::OptimizedCompilationInfo::GetDebugName() const (in /home/linux/v8)
==2588106==    by 0x7FB419: v8::internal::compiler::PipelineData::PipelineData(v8::internal::compiler::ZoneStats*, v8::internal::Isolate*, v8::internal::OptimizedCompilationInfo*, v8::internal::compiler::PipelineStatistics*, bool) (in /home/linux/v8)
==2588106==    by 0x7FB1FF: v8::internal::compiler::PipelineCompilationJob::PipelineCompilationJob(v8::internal::Isolate*, v8::internal::Handle<v8::internal::SharedFunctionInfo>, v8::internal::Handle<v8::internal::JSFunction>, v8::internal::BytecodeOffset, v8::internal::JavaScriptFrame*, v8::internal::CodeKind) (in /home/linux/v8)
==2588106==    by 0x807EDA: v8::internal::compiler::Pipeline::NewCompilationJob(v8::internal::Isolate*, v8::internal::Handle<v8::internal::JSFunction>, v8::internal::CodeKind, bool, v8::internal::BytecodeOffset, v8::internal::JavaScriptFrame*) (in /home/linux/v8)
==2588106==    by 0x2585F8: v8::internal::(anonymous namespace)::GetOptimizedCode(v8::internal::Handle<v8::internal::JSFunction>, v8::internal::ConcurrencyMode, v8::internal::CodeKind, v8::internal::BytecodeOffset, v8::internal::JavaScriptFrame*) (in /home/linux/v8)
==2588106==    by 0x259905: v8::internal::Compiler::CompileOptimized(v8::internal::Isolate*, v8::internal::Handle<v8::internal::JSFunction>, v8::internal::ConcurrencyMode, v8::internal::CodeKind) (in /home/linux/v8)
==2588106==    by 0xB2C785: v8::internal::(anonymous namespace)::CompileOptimized(v8::internal::Isolate*, v8::internal::Handle<v8::internal::JSFunction>, v8::internal::ConcurrencyMode) (in /home/linux/v8)
==2588106==    by 0xB28ACB: v8::internal::Runtime_CompileOptimized_Concurrent(int, unsigned long*, v8::internal::Isolate*) (in /home/linux/v8)
==2588106==
==2588106== 2 bytes in 1 blocks are still reachable in loss record 4 of 1,252
==2588106==    at 0x483EA5D: operator new[](unsigned long, std::nothrow_t const&) (vg_replace_malloc.c:658)
==2588106==    by 0x261383: v8::internal::CallDescriptors::InitializeOncePerProcess() (in /home/linux/v8)
==2588106==    by 0x3F0386: v8::internal::V8::InitializeOncePerProcessImpl() (in /home/linux/v8)
==2588106==    by 0x9ED455: v8::base::CallOnceImpl(std::atomic<unsigned char>*, std::function<void ()>) (in /home/linux/v8)
==2588106==    by 0x3EFFFD: v8::internal::V8::Initialize() (in /home/linux/v8)
==2588106==    by 0x23634A: v8::V8::Initialize(int) (in /home/linux/v8)
==2588106==    by 0x2074A2: main (in /home/linux/v8)
==2588106==
==2588106== 2 bytes in 1 blocks are still reachable in loss record 5 of 1,252
==2588106==    at 0x483EA5D: operator new[](unsigned long, std::nothrow_t const&) (vg_replace_malloc.c:658)
==2588106==    by 0x2620B0: v8::internal::CallDescriptors::InitializeOncePerProcess() (in /home/linux/v8)
==2588106==    by 0x3F0386: v8::internal::V8::InitializeOncePerProcessImpl() (in /home/linux/v8)
==2588106==    by 0x9ED455: v8::base::CallOnceImpl(std::atomic<unsigned char>*, std::function<void ()>) (in /home/linux/v8)
==2588106==    by 0x3EFFFD: v8::internal::V8::Initialize() (in /home/linux/v8)
==2588106==    by 0x23634A: v8::V8::Initialize(int) (in /home/linux/v8)
==2588106==    by 0x2074A2: main (in /home/linux/v8)

編輯2:編譯命令:

g++ sample.cpp libv8_monolith.a -I/usr/local/include/v8/ -I/usr/local/include/v8/include/ -lpthread -o v8 -DV8_COMPRESS_POINTERS

這是 V8 9.1 版本中的一個錯誤,已由 google 修復。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM