v8 version : 10.5.0
IDE : vs2022
I am trying to embed v8 in MFC. To test simply, I created a dialog project, initialized v8 on OnInitDialog()
, disposed it OnDestroy()
. And then, I wrote the code to create the context in BN_CLICKED
event and run script("Hello World!)". So, when the button was pressed, I wanted to show "Hello World!". But the crash took place in the code that create the context(v8::Local<v8::Context> context = v8::Context::New(isolate, nullptr);
).
As a result of testing, this only happens in MFC. This crash does not happen in console programs.
Somebody, anybody help me~. there is my whole code below.
cpp
BOOL Cv8TestDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
...
// Initialize V8.
v8::V8::InitializeICUDefaultLocation("");
v8::V8::InitializeExternalStartupData("");
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.
m_create_params.array_buffer_allocator = v8::ArrayBuffer::Allocator::NewDefaultAllocator();
m_isolate = v8::Isolate::New(m_create_params);
return TRUE;
}
void Cv8TestDlg::OnDestroy()
{
CDialogEx::OnDestroy();
m_isolate->Dispose();
v8::V8::Dispose();
v8::V8::DisposePlatform();
delete m_create_params.array_buffer_allocator;
}
void Cv8TestDlg::OnRun()
{
CString text;
v8::Isolate* isolate = m_isolate;
v8::Isolate::Scope isolate_scope(isolate);
// Create a stack-allocated handle scope.
v8::HandleScope handle_scope(isolate);
// Create a new context.
v8::Local<v8::Context> context = v8::Context::New(isolate, nullptr);
// Enter the context for compiling and running the hello world script.
v8::Context::Scope context_scope(context);
{
// Create a string containing the JavaScript source code.
v8::Local<v8::String> source = v8::String::NewFromUtf8Literal(isolate, "'Hello' + ', World!'");
// Compile the source code.
v8::Local<v8::Script> script = v8::Script::Compile(context, source).ToLocalChecked();
// Run the script to get the result.
v8::Local<v8::Value> result = script->Run(context).ToLocalChecked();
// Convert the result to an UTF8 string and print it.
v8::String::Value utf8(isolate, result);
text = (LPCWSTR)*utf8;
}
GetDlgItem(IDC_EDIT1)->SetWindowText(text);
}
h
class Cv8TestDlg : public CDialogEx
{
...
v8::Isolate::CreateParams m_create_params;
v8::Isolate* m_isolate = nullptr;
virtual BOOL OnInitDialog();
...
afx_msg void OnDestroy();
afx_msg void OnRun();
};
crash call stack
v8.dll!v8::internal::tracing::TraceEventHelper::GetTracingController()
v8.dll!v8::NewContext(v8::Isolate * external_isolate, v8::ExtensionConfiguration * extensions, v8::MaybeLocal<v8::ObjectTemplate> global_template, v8::MaybeLocal<v8::Value> global_object, unsigned __int64 context_snapshot_index, v8::DeserializeInternalFieldsCallback embedder_fields_deserializer, v8::MicrotaskQueue * microtask_queue) line 6391 C++
v8.dll!v8::Context::New(v8::Isolate * external_isolate, v8::ExtensionConfiguration * extensions, v8::MaybeLocal<v8::ObjectTemplate> global_template, v8::MaybeLocal<v8::Value> global_object, v8::DeserializeInternalFieldsCallback internal_fields_deserializer, v8::MicrotaskQueue * microtask_queue) line 6413 C++
v8Test.exe!Cv8TestDlg::OnRun() line 198 C++
exception message
(0x00007FFADBB43D53(v8.dll), v8Test.exe): 0xC0000005: 0x0000000000000088 access violation
break position(trace-event.cc)
v8::TracingController* TraceEventHelper::GetTracingController() {
-> return v8::internal::V8::GetCurrentPlatform()->GetTracingController();
}
I think the problem is std::unique_ptr<v8::Platform> platform
in OnInitDialog
. The purpose of a std::unique_ptr
is to destroy the thing it points at when the pointer goes out of scope (i.e. in this case, at the end of the function). The v8::Platform
should be long-lived, all the way until the v8::V8::DisposePlatform()
call.