v8 - Crash in HeapObject::GetHeap() - 未初始化的值

v8 - Crash in HeapObject::GetHeap() - uninitialized value

本文关键字:初始化 GetHeap Crash in HeapObject v8      更新时间:2023-10-16

从JS中,我调用了一个像这样的C++函数:

var req = new IO.HttpRequest(IO.RequestType.get);
req.data({ i: 'jTKvNf9w' }).send('http://pastebin.com/raw.php', function (content) { console.log(content); });

请求被异步处理,一旦完成,就会调用回调。在C++中,发送函数如下所示:

void XmlHttpRequest::open(const Utils::String& str, ::JS::FunctionObjPtr callback) {
    mCallback = callback;
    mRequest->open(str);
}

稍后,如果请求完成:

void XmlHttpRequest::onComplete(Utils::String content) {
    sUIMgr->getDispatcher()->pushFrame(Gl::Dispatcher::Priority::Low, [this, content]() {
        ::JS::FunctionObjPtr f = mCallback;
        f->callVoid(content);
    });
}

推送帧将函数放入队列中,以便在设置所有脚本的主线程中执行。

现在问题出在 HeapObject::GetHeap() 调用 MemoryChunk::FromAddress(reinterpret_cast<Address>(this))->heap(); 时我收到访问冲突callVoid。这些是 v8 函数。问题是,堆对象中的this指针是0xCCCCCCCC这意味着它是一个未初始化的值。this -Pointer 来自存储在 JS::FunctionObjPtr 中的句柄(一个 std::shared_ptr 的 typedef)。

起初我以为我的FunctionObj有问题.我通过以下方式获得此内容:

template<typename T>
static TYPE_RET(FunctionObjPtr) ObjectWrap::unwrap(v8::Handle<v8::Value>& value) {
    if (value->IsFunction() == false) {
        TYPE_ERR("Value is not a function");
    }
    return std::make_shared<FunctionObj>(value);
}

TYPE_RET只是在做一些模板元编程的东西。FunctionObj如下所示:

class FunctionObj
{
    v8::Handle<v8::Value> mHandle;
public:
    FunctionObj(v8::Handle<v8::Value>& fun) {
        mHandle = fun;
    }
    FunctionObj() { }
    operator bool () {
        return mHandle.IsEmpty() == false;
    }
    template<typename... Args>
    void callVoid(const Args&... args) {
        std::vector<v8::Handle<v8::Value>> arguments;
        addArgument(arguments, args...);
        v8::TryCatch tc;
        v8::Handle<v8::Function>::Cast(mHandle)->Call(mHandle, arguments.size(), arguments.data());
        if (tc.HasCaught()) {
            throw JS::Exception(tc.Exception(), tc.StackTrace());
        }
    }
};

当我在"注册"的XmlHttpRequest::open调用该函数时,它可以工作。所以起初我认为对象被gc'ed了,但为了确保它永远不会被收集到FunctionObj::FunctionObj中,我从句柄创建了一个v8::P ersistent。它仍然崩溃。我什至将 v8::P ersistent 设置为弱,看看它是否真的被收集,但弱回调从未被调用。

我在通话前检查过的其他事项:

  1. v8::隔离::获取电流() -> 返回正确的、输入的隔离
  2. v8::上下文::GetCurrent() -> 相同
  3. 全局句柄范围未离开
  4. XmlHttpRequest::open 和带有调用的 lambda 在同一线程中调用

更多信息:这不仅限于 v8::Handle<v8::Function>。如果我尝试存储一个对象并稍后访问其属性之一,也会发生这种情况。我只是不能找到使用句柄的 lambda 中的任何东西。

正如我在尝试过的事情中所说,我看了一下v8::Persistent。原来我用错了。

我做了什么:

class FunctionObj
{
    v8::Handle<v8::Value> mHandle;
    v8::Persistent<v8::Value> mPersistent;
public:
    FunctionObj(v8::Handle<v8::Value>& fun) {
        mPersistent.Reset(v8::Isolate::GetCurrent(), fun);
        mHandle = fun;
    }
    FunctionObj() { }
    operator bool () {
        return mHandle.IsEmpty() == false;
    }
    template<typename... Args>
    void callVoid(const Args&... args) {
        std::vector<v8::Handle<v8::Value>> arguments;
        addArgument(arguments, args...);
        v8::TryCatch tc;
        v8::Handle<v8::Function>::Cast(mHandle)->Call(mHandle, arguments.size(), arguments.data());
        if (tc.HasCaught()) {
            throw JS::Exception(tc.Exception(), tc.StackTrace());
        }
    }
};

我应该做什么

class FunctionObj
{
    v8::Persistent<v8::Value> mPersistent;
public:
    FunctionObj(v8::Handle<v8::Value>& fun) {
        mPersistent.Reset(v8::Isolate::GetCurrent(), fun);
    }
    FunctionObj() { if(mPersistent) { mPersistent.Dispose(); } }
    operator bool () {
        return mHandle.IsEmpty() == false;
    }
    template<typename... Args>
    void callVoid(const Args&... args) {
        std::vector<v8::Handle<v8::Value>> arguments;
        addArgument(arguments, args...);
        v8::Local<v8::Function> fun = v8::Local<v8::Function>::New(v8::Isolate::GetCurrent(), mPersistent.As<v8::Function>());
        v8::TryCatch tc;
        fun->Call(fun, arguments.size(), arguments.data());
        if (tc.HasCaught()) {
            throw JS::Exception(tc.Exception(), tc.StackTrace());
        }
    }
};

创建的持久性并不意味着我存储的句柄不会被销毁,而只是以后可以查询对象的新句柄并且不会删除该对象。

现在一切都像魅力一样工作!