Search code examples
c++v8embedded-v8

V8 QuickIsUndefined crushes randomly when using IsConstructCall


I have a function:

auto func = v8::FunctionTemplate::New(context,
    [](const v8::FunctionCallbackInfo<v8::Value>& args) {
        auto isolate = args.GetIsolate();
        if (args.IsConstructCall()) { ... }
        ...
    }).ToLocalChecked();

and I exposed this function as following.

global->Set(isolate, "func", func);

I used the function both as a normal function and a constructor,

func();
new func();

and V8 crushed when IsConstructCall is called. I found that IsConstructCall uses QuickIsUndefined to check whether NewTarget is undefined or not. The problem occurs inside ReadRawField, which is called by GetInstanceType, and QuickIsUndefined calls GetInstanceType.

Error in v8-internal.h, line 305

Since T=unsigned short, I added reinterpret_cast<unsigned short*>(addr) to the watch and the result was like this, and it was different from what the exception says.

enter image description here

What makes me more confusing is that sometimes my program runs well without crushing. Instead of IsContructCall, I used v8::Undefined and Value::Equals, and it runs well.

!args.NewTarget()->Equals(isolate->GetCurrentContext(), v8::Undefined(isolate)).ToChecked()

It seems like QuickIsUndefined has some problem, but I can't identify the problem. What may help in this situation? I compiled V8 with MSVC in monolith mode.


Solution

  • I had the same issue: try to compile your code with -DV8_COMPRESS_POINTERS. V8 has compressed pointers as default now.

    v8-internal.h "ReadRawField" can help you to understand the background