I am embedding V8 (version 8.1.307) into an application. I am using the API reference made available by node source.com, alongside Google's embedding guide.
I am hitting a road block while trying to do a seemingly simple thing: to generate an error object in response to an invalid call to a C++ function from Javascript.
The docs indicate that it should be as simple as constructing a v8::Local <v8::String>
and passing it to v8::Exception::RangeError()
or similar function, but this triggers a segfault inside of V8.
I have pored over the available samples, but they only offer demonstrations of how to throw raw strings as exceptions, which I'd rather not do if at all possible. Am I missing something simple, or is this really broken or unsupported?
//Note: ErrorFactory is defined as:
typedef v8::Local <v8::Value>(*ErrorFactory)(v8::Local <v8::String>);
void ScriptManager::ConvertNativeExceptionToJavascriptError(ErrorFactory NewError, std::exception& exception)
{
v8::Local <v8::String> errstr = v8::String::NewFromUtf8(mIsolate, exception.what(), v8::NewStringType::kNormal).ToLocalChecked();
mIsolate->ThrowException(NewError(errstr));
}
Later invoked as follows:
catch(std::exception& e)
{
//Just pick RangeError for demonstration's sake.
engine->ConvertNativeExceptionToJavascriptError(v8::Exception::RangeError, e);
}
It crashes inside of V8 during the RangeError call:
AddressSanitizer:DEADLYSIGNAL
=================================================================
==7680==ERROR: AddressSanitizer: SEGV on unknown address 0x00000000a058 (pc 0x00010e07c771 bp 0x7ffee1c0baf0 sp 0x7ffee1c0ba90 T0)
==7680==The signal is caused by a READ memory access.
#0 0x10e07c770 in v8::Exception::RangeError(v8::Local<v8::String>) api.cc:9199
#1 0x10dff9904 in ScriptManager::ConvertNativeExceptionToJavascriptError(v8::Local<v8::Value> (*)(v8::Local<v8::String>), std::exception&) javascript.cpp:316
#2 0x10dff7cca in CallFunction(v8::FunctionCallbackInfo<v8::Value> const&) javascript.cpp:66
#3 0x10e0bce80 in v8::internal::FunctionCallbackArguments::Call(v8::internal::CallHandlerInfo) api-arguments-inl.h:158
#4 0x10e0bc353 in v8::internal::MaybeHandle<v8::internal::Object> v8::internal::(anonymous namespace)::HandleApiCallHelper<false>(v8::internal::Isolate*, v8::internal::Handle<v8::internal::HeapObject>, v8::internal::Handle<v8::internal::HeapObject>, v8::internal::Handle<v8::internal::FunctionTemplateInfo>, v8::internal::Handle<v8::internal::Object>, v8::internal::BuiltinArguments) builtins-api.cc:111
#5 0x10e0bb932 in v8::internal::Builtin_Impl_HandleApiCall(v8::internal::BuiltinArguments, v8::internal::Isolate*) builtins-api.cc:141
#6 0x10ec9ac38 in Builtins_CEntry_Return1_DontSaveFPRegs_ArgvOnStack_BuiltinExit (test:x86_64+0x100ca8c38)
#7 0x10ec33452 in Builtins_InterpreterEntryTrampoline (test:x86_64+0x100c41452)
#8 0x10ec310b9 in Builtins_JSEntryTrampoline (test:x86_64+0x100c3f0b9)
#9 0x10ec30e97 in Builtins_JSEntry (test:x86_64+0x100c3ee97)
#10 0x10e180f90 in v8::internal::(anonymous namespace)::Invoke(v8::internal::Isolate*, v8::internal::(anonymous namespace)::InvokeParams const&) execution.cc:372
#11 0x10e180297 in v8::internal::Execution::Call(v8::internal::Isolate*, v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Object>, int, v8::internal::Handle<v8::internal::Object>*) execution.cc:466
#12 0x10e051399 in v8::Script::Run(v8::Local<v8::Context>) api.cc:2158
#13 0x10e004b55 in ScriptContext::ExecuteString(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) javascript.cpp:448
#14 0x10e00572c in ScriptContext::ExecuteFile(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >) javascript.cpp:466
#15 0x10dff3b23 in main test.cpp:28
#16 0x7fff6a527cc8 in start (libdyld.dylib:x86_64+0x1acc8)
==7680==Register values:
rax = 0x0000000000000000 rbx = 0x0000000000000000 rcx = 0x0000000000000000 rdx = 0x0000100000000000
rdi = 0x000062500000c9d0 rsi = 0x00007ffee1c0bb40 rbp = 0x00007ffee1c0baf0 rsp = 0x00007ffee1c0ba90
r8 = 0x000062500000c9d0 r9 = 0xffffebffffff7748 r10 = 0x0000000000000043 r11 = 0x0000000000000060
r12 = 0x000060e000000520 r13 = 0x00007ffee1c0d7e0 r14 = 0x000062500000c9d0 r15 = 0x00001fffdc381afd
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV api.cc:9199 in v8::Exception::RangeError(v8::Local<v8::String>)
==7680==ABORTING
Abort trap: 6