從JS我所說的C++ - 功能是這樣的:V8 - 碰撞在HeapObject :: GetHeap() - 未初始化值
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);
});
}
推框架放功能在隊列在主線程中執行,其中所有腳本被設置。
現在問題出在callVoid
當HeapObject :: GetHeap()調用MemoryChunk::FromAddress(reinterpret_cast<Address>(this))->heap();
時,出現訪問衝突。這些是v8功能。問題是,this
-HeapObject中的指針是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化了,但爲了確保它不會被收集在FunctionObj :: FunctionObj中,我從句柄創建了一個v8 :: Persistent。它仍然崩潰。我甚至讓v8 :: Persistent弱一點,看它是否真的被收集,但弱回調永遠不會被調用。
我在呼叫前右側檢查了其他的事情:
- V8 ::隔離:: GetCurrent() - >返回正確的,進入分離
- V8 ::語境:: GetCurrent() - >同
- 全球HandleScope不剩
- 的XmlHttpRequest ::開放,與呼叫拉姆達被稱爲在同一個線程
更多信息: 這不僅限於v8 :: Handle < v8 :: Function> only。如果我嘗試存儲對象並稍後訪問其中一個屬性,也會發生這種情況。我只是不能使用那個使用句柄的lambda中的任何東西。
不知道這是否有幫助,但如果您存儲對象並希望稍後訪問其屬性,請嘗試使用持久指針類型。例如 持久
它有幫助。這不是直接導致問題的直接原因(因爲我已經嘗試了持久的解決方案),但它讓我繼續走下去,這是一條正確的路,請參閱我的答案。 – Muepe