Re: [v8-users] Totally stumped with crash, potentially thread related
Thanks for the asan tip Jochen, that's just the sort of thing I was looking for but didn't know existed I believe i've fixed it! Although I don't fully understand the cause. It seems to be to related to Java Native Interface and v8 not playing well together Here's what worked, in case someone else has this issue: I was using JNI's NewStringUTF function to allocate a java string to pass into a java function call, once the call had been made I was using ReleaseStringUTFChars, which would let the java GC free the memory. The fix seemed to be forcing Java to trash the string before the function exits using DeleteLocalRef. Full corrected function: void AndroidMediaPlayer::setDataSource(const v8::FunctionCallbackInfo& p___args) { v8::Locker locker(p___args.GetIsolate()); v8::HandleScope scope(p___args.GetIsolate()); node::commons* com = node::commons::getInstanceIso(p___args.GetIsolate()); v8::Isolate * __contextORisolate = p___args.GetIsolate(); jxcore::PArguments args(p___args); if(com->expects_reset) RETURN(); v8::Local jsPath = args.GetAsString(0); const char* cPath = STRING_TO_STD(jsPath); jstring jPath = env->NewStringUTF(cPath); env->CallVoidMethod(AndroidMediaPlayer::GetNative(args.Holder())->jniMediaPlayer, setDataSourceId, jPath); HANDLE_JNI_EXCEPTIONS(env); //we _must_ deleteLocalRef rather than release, not deleting immediately causes crash in v8 env->DeleteLocalRef(jPath); } (The crash would occur the same way with or without the v8::String code and the java function call, the only thing required to trigger it was calling NewStringUTF and ReleaseStringUTFChars) On Friday, March 11, 2016 at 7:04:53 AM UTC, Jochen Eisinger wrote: > > It's really difficult to even begin guessing what could cause this: > without the source, and more information about the crash like a call stack > and values of local variables, there's not much I can do. > > In general, compiling the code with asan might provide additional insights > as to what corrupts the memory. > > Best > Jochen > > On Thu, Mar 10, 2016, 10:22 PM George Corney <haxi...@gmail.com > > wrote: > >> Hey, >> >> I'm hoping someone with more experience than me can shed some light on my >> issue. >> >> v8 is being run on a separate thread to the main thread, all interactions >> with v8 occur on this thread >> >> The problem is that when an action (playing/pausing a film in android's >> MediaPlayer) occurs on the main thread, the app has a high chance of >> crashing either straight away or after a short period (can be as high as >> 600ms). >> >> The crash is always the same (with differing address(: >> >> signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0x45524854 >> Although occasionally SEGV_ACCERR might be SEGV_MAPERR. >> >> Stack frame #00 pc 0061d3ec /[...]/lib/arm/libnative_webgl.so >> (v8::internal::AstValueFactory::Internalize(v8::internal::Isolate*)+56) >> >> SEGV_ACCERR and SEGV_MAPERR surely imply that the v8 thread is accessing >> data on another thread, but as far as my code is concerned, nothing >> interesting is happening when the crash occurs and if there are any calls >> to js land they're happening on the thread v8 was created with. >> >> The code for AstValueFactory::Internalize is >> void AstValueFactory::Internalize(Isolate* isolate) { >> if (isolate_) { >> // Everything is already internalized. >> return; >> } >> // Strings need to be internalized before values, because values refer >> to >> // strings. >> for (int i = 0; i < strings_.length(); ++i) { >> strings_[i]->Internalize(isolate); >> } >> for (int i = 0; i < values_.length(); ++i) { >> values_[i]->Internalize(isolate); >> } >> isolate_ = isolate; >> } >> >> >> Do you have any thoughts about what could cause this? If the media player >> action is corrupting memory in some way, is there some reason that it >> always crashes on this particular function? >> >> I'm using v8 3.2.8 on Android (via NDK). (unfortunately upgrading to more >> recent v8 isn't an option). >> >> v8::Locker is used before every handle_scope, should I be doing something >> else to ensure thread safety? >> >> Been on this problem for a long time now, any insight someone might have >> will be useful. >> >> Thanks, >> George Corney >> >> -- >> -- >> v8-users mailing list >> v8-u...@googlegroups.com >> http://groups.google.com/group/v8-users >> --- >> You received this message because you are subscribed to the Google Groups >> "v8-use
[v8-users] Totally stumped with crash, potentially thread related
Hey, I'm hoping someone with more experience than me can shed some light on my issue. v8 is being run on a separate thread to the main thread, all interactions with v8 occur on this thread The problem is that when an action (playing/pausing a film in android's MediaPlayer) occurs on the main thread, the app has a high chance of crashing either straight away or after a short period (can be as high as 600ms). The crash is always the same (with differing address(: signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0x45524854 Although occasionally SEGV_ACCERR might be SEGV_MAPERR. Stack frame #00 pc 0061d3ec /[...]/lib/arm/libnative_webgl.so (v8::internal::AstValueFactory::Internalize(v8::internal::Isolate*)+56) SEGV_ACCERR and SEGV_MAPERR surely imply that the v8 thread is accessing data on another thread, but as far as my code is concerned, nothing interesting is happening when the crash occurs and if there are any calls to js land they're happening on the thread v8 was created with. The code for AstValueFactory::Internalize is void AstValueFactory::Internalize(Isolate* isolate) { if (isolate_) { // Everything is already internalized. return; } // Strings need to be internalized before values, because values refer to // strings. for (int i = 0; i < strings_.length(); ++i) { strings_[i]->Internalize(isolate); } for (int i = 0; i < values_.length(); ++i) { values_[i]->Internalize(isolate); } isolate_ = isolate; } Do you have any thoughts about what could cause this? If the media player action is corrupting memory in some way, is there some reason that it always crashes on this particular function? I'm using v8 3.2.8 on Android (via NDK). (unfortunately upgrading to more recent v8 isn't an option). v8::Locker is used before every handle_scope, should I be doing something else to ensure thread safety? Been on this problem for a long time now, any insight someone might have will be useful. Thanks, George Corney -- -- v8-users mailing list v8-users@googlegroups.com http://groups.google.com/group/v8-users --- You received this message because you are subscribed to the Google Groups "v8-users" group. To unsubscribe from this group and stop receiving emails from it, send an email to v8-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [v8-users] v8 3.28, getting data from typed arrays, I'm unsure if this approach is correct (and doesn't leak)
*Correction, free(dataPtr) should be replaced with a call to your ArrayBufferAllocator's .Free(ptr, length) call On Friday, February 26, 2016 at 1:22:26 PM UTC, George Corney wrote: > > *For the next person trying to do this:* > > It turns the approach in the post above doesn't completely work because > GetIndexedPropertiesExternalArrayData is only supported on > ArrayBufferViews and not ArrayBuffers. My solution now is to grab the > Contents::Data() pointer provided when ArrayBuffer::Externalize() is called > and store it on the ArrayBuffer in a hidden field (as well as creating a > weak persistent handle to free it later). My implementation is provided: > > struct WeakCallbackData{ > v8::Persistent* persistent; > uintptr_t dataPtrValue; > }; > > //when we get typed array data we take responsibility for freeing the data > void ArrayBufferWeakCallback(const v8::WeakCallbackData<v8::ArrayBuffer, > WeakCallbackData>& info){ > WeakCallbackData* callbackData = info.GetParameter(); > v8::Persistent* persistent = callbackData->persistent; > void* dataPtr = (void*) info.GetParameter()->dataPtrValue; > > Print::Debug("ArrayBufferWeakCallback fired (byte length: %d, dataPtr*: > %p)", info.GetValue()->ByteLength(), dataPtr); > > //dealloc > info.GetValue().Clear(); > persistent->Reset(); > delete callbackData; > free(dataPtr); > } > > void AttachPointerObject(v8::Isolate* isolate, > v8::Handle& buffer, void* dataPtr){ > v8::Local ptrObjTmpl = > v8::ObjectTemplate::New(isolate); > ptrObjTmpl->SetInternalFieldCount(1); > v8::Local ptrObj = ptrObjTmpl->NewInstance(); > ptrObj->SetAlignedPointerInInternalField(0, dataPtr); > buffer->SetHiddenValue(v8::String::NewFromUtf8(isolate, "ptrObj"), ptrObj); > } > > //Public API > > const void SafelyExternalizeArrayBuffer(v8::Isolate* isolate, > v8::Handle& buffer){ > if(!buffer->IsExternal()){ > v8::ArrayBuffer::Contents contents = buffer->Externalize(); > RegisterExternalData(isolate, buffer, contents.Data()); > } > } > > void RegisterExternalData(v8::Isolate* isolate, > v8::Handle& buffer, void* dataPtr){ > Print::Debug("RegisterExternalData (byte length: %d, dataPtr*: %p)", > buffer->ByteLength(), dataPtr); > > AttachPointerObject(isolate, buffer, dataPtr); > > v8::Persistent* persistent = new > v8::Persistent(); > persistent->Reset(isolate, buffer); > > WeakCallbackData* callbackData = new WeakCallbackData(); > callbackData->persistent = persistent; > callbackData->dataPtrValue = (uintptr_t)(void *)dataPtr; > > persistent->SetWeak(callbackData, > ArrayBufferWeakCallback); > } > > const unsigned char* GetArrayBufferBytes(v8::Isolate* isolate, > v8::Handle& buffer){ > SafelyExternalizeArrayBuffer(isolate, buffer); > > v8::Local v = > buffer->GetHiddenValue(v8::String::NewFromUtf8(isolate, "ptrObj")); > > if(!v->IsObject()){ > Print::Error("%s: Internal data pointer not found on ArrayBuffer, ensure > RegisterExternalData was at initialization", __FUNCTION__); > return NULL; > } > > v8::Local ptrObj = v8::Local::Cast(v); > const void* dataPtr = ptrObj->GetAlignedPointerFromInternalField(0); > const unsigned char* bytePtr = static_cast(dataPtr); > return bytePtr; > } > > > const unsigned char* GetArrayBufferViewBytes(v8::Isolate* isolate, > v8::Handle& bufferView){ > v8::Local buffer = bufferView->Buffer(); > SafelyExternalizeArrayBuffer(isolate, buffer); > const void* dataPtr = bufferView->GetIndexedPropertiesExternalArrayData(); > const unsigned char* bytePtr = static_cast(dataPtr) > + bufferView->ByteOffset(); > return bytePtr; > } > > > (You'll need to replace the Print:: functions with whatever system you're > using for logging) > > - If the TypedArrays are coming from JS land, you'll only need > *GetArrayBufferBytes* and *GetArrayBufferViewBytes* (depending on if > you're using an ArrayBufferView or ArrayBuffer) to access the data safely > - If the TypedArray is created in C++ land and the data buffer is provided > to it so it's already external, then you need to use > *RegisterExternalData* for to make the ArrayBuffer safe to access with > these functions (the buffer will be freed with the WeakCallback) > - If you want to externalize without accessing the data, you need to use > *SafelyExternalizeArrayBuffer* *and not* *ArrayBuffer::Externalize()* > > > All the best, > George Corney > > On Monday, February 22, 2016 at 3:38:08 PM UTC, George Corney wrote: >> >> Thanks for the tips >> >> I agree regarding upgrading from 3.
Re: [v8-users] v8 3.28, getting data from typed arrays, I'm unsure if this approach is correct (and doesn't leak)
*For the next person trying to do this:* It turns the approach in the post above doesn't completely work because GetIndexedPropertiesExternalArrayData is only supported on ArrayBufferViews and not ArrayBuffers. My solution now is to grab the Contents::Data() pointer provided when ArrayBuffer::Externalize() is called and store it on the ArrayBuffer in a hidden field (as well as creating a weak persistent handle to free it later). My implementation is provided: struct WeakCallbackData{ v8::Persistent* persistent; uintptr_t dataPtrValue; }; //when we get typed array data we take responsibility for freeing the data void ArrayBufferWeakCallback(const v8::WeakCallbackData<v8::ArrayBuffer, WeakCallbackData>& info){ WeakCallbackData* callbackData = info.GetParameter(); v8::Persistent* persistent = callbackData->persistent; void* dataPtr = (void*) info.GetParameter()->dataPtrValue; Print::Debug("ArrayBufferWeakCallback fired (byte length: %d, dataPtr*: %p)", info.GetValue()->ByteLength(), dataPtr); //dealloc info.GetValue().Clear(); persistent->Reset(); delete callbackData; free(dataPtr); } void AttachPointerObject(v8::Isolate* isolate, v8::Handle& buffer, void* dataPtr){ v8::Local ptrObjTmpl = v8::ObjectTemplate::New(isolate); ptrObjTmpl->SetInternalFieldCount(1); v8::Local ptrObj = ptrObjTmpl->NewInstance(); ptrObj->SetAlignedPointerInInternalField(0, dataPtr); buffer->SetHiddenValue(v8::String::NewFromUtf8(isolate, "ptrObj"), ptrObj); } //Public API const void SafelyExternalizeArrayBuffer(v8::Isolate* isolate, v8::Handle& buffer){ if(!buffer->IsExternal()){ v8::ArrayBuffer::Contents contents = buffer->Externalize(); RegisterExternalData(isolate, buffer, contents.Data()); } } void RegisterExternalData(v8::Isolate* isolate, v8::Handle& buffer, void* dataPtr){ Print::Debug("RegisterExternalData (byte length: %d, dataPtr*: %p)", buffer->ByteLength(), dataPtr); AttachPointerObject(isolate, buffer, dataPtr); v8::Persistent* persistent = new v8::Persistent(); persistent->Reset(isolate, buffer); WeakCallbackData* callbackData = new WeakCallbackData(); callbackData->persistent = persistent; callbackData->dataPtrValue = (uintptr_t)(void *)dataPtr; persistent->SetWeak(callbackData, ArrayBufferWeakCallback); } const unsigned char* GetArrayBufferBytes(v8::Isolate* isolate, v8::Handle& buffer){ SafelyExternalizeArrayBuffer(isolate, buffer); v8::Local v = buffer->GetHiddenValue(v8::String::NewFromUtf8(isolate, "ptrObj")); if(!v->IsObject()){ Print::Error("%s: Internal data pointer not found on ArrayBuffer, ensure RegisterExternalData was at initialization", __FUNCTION__); return NULL; } v8::Local ptrObj = v8::Local::Cast(v); const void* dataPtr = ptrObj->GetAlignedPointerFromInternalField(0); const unsigned char* bytePtr = static_cast(dataPtr); return bytePtr; } const unsigned char* GetArrayBufferViewBytes(v8::Isolate* isolate, v8::Handle& bufferView){ v8::Local buffer = bufferView->Buffer(); SafelyExternalizeArrayBuffer(isolate, buffer); const void* dataPtr = bufferView->GetIndexedPropertiesExternalArrayData(); const unsigned char* bytePtr = static_cast(dataPtr) + bufferView->ByteOffset(); return bytePtr; } (You'll need to replace the Print:: functions with whatever system you're using for logging) - If the TypedArrays are coming from JS land, you'll only need *GetArrayBufferBytes* and *GetArrayBufferViewBytes* (depending on if you're using an ArrayBufferView or ArrayBuffer) to access the data safely - If the TypedArray is created in C++ land and the data buffer is provided to it so it's already external, then you need to use *RegisterExternalData* for to make the ArrayBuffer safe to access with these functions (the buffer will be freed with the WeakCallback) - If you want to externalize without accessing the data, you need to use *SafelyExternalizeArrayBuffer* *and not* *ArrayBuffer::Externalize()* All the best, George Corney On Monday, February 22, 2016 at 3:38:08 PM UTC, George Corney wrote: > > Thanks for the tips > > I agree regarding upgrading from 3.28, unfortunately for the time being > I'm stuck with it as a consequence of various trade offs (I'm using JXcore > which is built on 3.28 and I can't migrate away because of time constraints) > > I'm trying the externalize + weak persistent handle method, here's my code > now > > //weak callback, frees the raw data and handle > void ArrayBufferWeakCallback(const v8::WeakCallbackData<v8::ArrayBuffer, > v8::Persistent>& info){ > Print::Debug("ArrayBufferWeakCallback fired"); > void* rawData = info.GetValue()->GetIndexedPropertiesExternalArrayData(); > info.GetValue().Clear(); > info.GetParameter()->Reset(); > free(rawData); > free(info.GetParameter()); > } > > > //... > > &
Re: [v8-users] v8 3.28, getting data from typed arrays, I'm unsure if this approach is correct (and doesn't leak)
Thanks for the tips I agree regarding upgrading from 3.28, unfortunately for the time being I'm stuck with it as a consequence of various trade offs (I'm using JXcore which is built on 3.28 and I can't migrate away because of time constraints) I'm trying the externalize + weak persistent handle method, here's my code now //weak callback, frees the raw data and handle void ArrayBufferWeakCallback(const v8::WeakCallbackData<v8::ArrayBuffer, v8 ::Persistent>& info){ Print::Debug("ArrayBufferWeakCallback fired"); void* rawData = info.GetValue()->GetIndexedPropertiesExternalArrayData(); info.GetValue().Clear(); info.GetParameter()->Reset(); free(rawData); free(info.GetParameter()); } //... v8::Local bufferView = dataArg.As(); size_t byteLength = bufferView->ByteLength(); size_t byteOffset = bufferView->ByteOffset(); bufferView->Buffer()->Externalize(); //create weak persistent handle with callback to above code v8::Persistent* persistent = new v8::Persistent(); persistent->Reset(isolate, buffer); persistent->SetWeak<v8::Persistent>(persistent, ArrayBufferWeakCallback); const void* rawData = bufferView->GetIndexedPropertiesExternalArrayData(); const unsigned char* bytePtr = static_cast(rawData); glBufferData(target, byteLength, bytePtr + byteOffset, usage); REPORT_GL_ERRORS(); The callback seems to fire as expected and there's no segfaults so I think this might be the solution! Could you have a quick read to see I'm not setting myself up for failure by rolling this approach out across my code? Many thanks, George On Monday, February 22, 2016 at 7:59:15 AM UTC, Jochen Eisinger wrote: > > Please note that 3.28 is a really old version of V8 which is full of known > issues and no longer maintained. > > In general, you'll wait to externalize the buffer and keep a weak > persistent handle to the buffer - once the weak callback was triggered, you > know that you can free the backing store (if you no longer need it > otherwise). > > More current versions of V8 also have a method > ArrayBufferView::CopyContents that allows you to access the backing store > without externalizing the underlying buffer. > > On Sun, Feb 21, 2016 at 11:27 PM George Corney <haxi...@gmail.com > > wrote: > >> Hello, >> >> I'm working with typed arrays in v8 3.28, I've got a native function that >> takes a Float32Array from javascript and passes the float* data off to a gl >> call (glBufferData). >> >> I discovered that using just >> const void* rawData = bufferView->GetIndexedPropertiesExternalArrayData >> (); >> works, but not reliably, the data gets passes to glBufferData correctly >> most of the time, but not always! >> >> I've found creating a persistent handle before getting the data pointer, >> and then reseting handle after the glBufferData solves the problem, but is >> it the right approach? Am I leaking memory / risking sending incorrect data >> to glBufferData? Here's the snippet >> >> v8::Local bufferView = >> dataArg.As(); >> size_t byteLength = bufferView->ByteLength(); >> size_t byteOffset = bufferView->ByteOffset(); >> >> v8::Persistent persistent; >> persistent.Reset(__contextORisolate, bufferView->Buffer()); >> >> const void* rawData = bufferView->GetIndexedPropertiesExternalArrayData(); >> const unsigned char* bytePtr = static_cast(rawData); >> >> glBufferData(target, byteLength, bytePtr + byteOffset, usage); >> REPORT_GL_ERRORS(); >> >> persistent.Reset(); >> >> >> --- >> >> If this the wrong approach, I think the next thing is to use >> bufferView->Buffer()->Externalize(); >> before getting the data pointer. In this case I'm then responsible for >> freeing the data - If this is necessary, could you explain how to do this? >> Can it be done without altering the ArrayBufferAllocator? >> >> >> Many thanks! >> George Corney >> >> -- >> -- >> v8-users mailing list >> v8-u...@googlegroups.com >> http://groups.google.com/group/v8-users >> --- >> You received this message because you are subscribed to the Google Groups >> "v8-users" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to v8-users+u...@googlegroups.com . >> For more options, visit https://groups.google.com/d/optout. >> > -- -- v8-users mailing list v8-users@googlegroups.com http://groups.google.com/group/v8-users --- You received this message because you are subscribed to the Google Groups "v8-users" group. To unsubscribe from this group and stop receiving emails from it, send an email to v8-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[v8-users] v8 3.28, getting data from typed arrays, I'm unsure if this approach is correct (and doesn't leak)
Hello, I'm working with typed arrays in v8 3.28, I've got a native function that takes a Float32Array from javascript and passes the float* data off to a gl call (glBufferData). I discovered that using just const void* rawData = bufferView->GetIndexedPropertiesExternalArrayData(); works, but not reliably, the data gets passes to glBufferData correctly most of the time, but not always! I've found creating a persistent handle before getting the data pointer, and then reseting handle after the glBufferData solves the problem, but is it the right approach? Am I leaking memory / risking sending incorrect data to glBufferData? Here's the snippet v8::Local bufferView = dataArg.As(); size_t byteLength = bufferView->ByteLength(); size_t byteOffset = bufferView->ByteOffset(); v8::Persistent persistent; persistent.Reset(__contextORisolate, bufferView->Buffer()); const void* rawData = bufferView->GetIndexedPropertiesExternalArrayData(); const unsigned char* bytePtr = static_cast(rawData); glBufferData(target, byteLength, bytePtr + byteOffset, usage); REPORT_GL_ERRORS(); persistent.Reset(); --- If this the wrong approach, I think the next thing is to use bufferView->Buffer()->Externalize(); before getting the data pointer. In this case I'm then responsible for freeing the data - If this is necessary, could you explain how to do this? Can it be done without altering the ArrayBufferAllocator? Many thanks! George Corney -- -- v8-users mailing list v8-users@googlegroups.com http://groups.google.com/group/v8-users --- You received this message because you are subscribed to the Google Groups "v8-users" group. To unsubscribe from this group and stop receiving emails from it, send an email to v8-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [v8-users] Isolate->Dispose() causes crash only when Math.random() is used
Yep, that was it! Thanks for your help Jochen! On Tuesday, February 2, 2016 at 8:48:56 AM UTC, Jochen Eisinger wrote: > > you stack-allocate the ArrayBufferAllocator, so it'll get destructed at > the end of the Initialize() method. > > You should allocate it on the heap instead, so it outlives that method. > > best > -jochen > > On Mon, Feb 1, 2016 at 10:17 PM George Corney <haxi...@gmail.com > > wrote: > >> Hey, >> >> I'm struggling to get to the bottom of this one >> >> The crash occurs with a slightly modified version of the *hello-world.cc* >> sample, I've separated the initialization and execution into one function >> and the dispose calls into another. If the executed javascript contains >> Math.random(), the app crashes with '*Segmentation fault: 11*' when >> isolate->Dispose() is called. If isolate->Dispose() is called from within >> the initialization function then there is no crash. >> >> Here's the code https://gist.github.com/haxiomic/502227a9f0c606cd6117 >> >> The crash log is in a comment below >> >> I'm keen to know if i'm doing something wrong in how I'm separating >> the initialization and dispose calls or if this is a bug with Math.random() >> >> I'm running OS X 10.11.3 and building with V8 with hash e709aa2 >> >> -- >> -- >> v8-users mailing list >> v8-u...@googlegroups.com >> http://groups.google.com/group/v8-users >> --- >> You received this message because you are subscribed to the Google Groups >> "v8-users" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to v8-users+u...@googlegroups.com . >> For more options, visit https://groups.google.com/d/optout. >> > -- -- v8-users mailing list v8-users@googlegroups.com http://groups.google.com/group/v8-users --- You received this message because you are subscribed to the Google Groups "v8-users" group. To unsubscribe from this group and stop receiving emails from it, send an email to v8-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[v8-users] Isolate->Dispose() causes crash only when Math.random() is used
Hey, I'm struggling to get to the bottom of this one The crash occurs with a slightly modified version of the *hello-world.cc* sample, I've separated the initialization and execution into one function and the dispose calls into another. If the executed javascript contains Math.random(), the app crashes with '*Segmentation fault: 11*' when isolate->Dispose() is called. If isolate->Dispose() is called from within the initialization function then there is no crash. Here's the code https://gist.github.com/haxiomic/502227a9f0c606cd6117 The crash log is in a comment below I'm keen to know if i'm doing something wrong in how I'm separating the initialization and dispose calls or if this is a bug with Math.random() I'm running OS X 10.11.3 and building with V8 with hash e709aa2 -- -- v8-users mailing list v8-users@googlegroups.com http://groups.google.com/group/v8-users --- You received this message because you are subscribed to the Google Groups "v8-users" group. To unsubscribe from this group and stop receiving emails from it, send an email to v8-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.