Created
February 10, 2014 01:21
-
-
Save bnoordhuis/8908704 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// scons mode=debug arch=x64 | |
// g++ -m64 -Wall -ggdb stack-guard.cc -Iinclude libv8_g.a -lpthread && ./a.out; echo "$?" | |
// | |
// gcc version 4.4.5 (Debian 4.4.5-8) | |
// http://v8.googlecode.com/svn/trunk@r6858 | |
// | |
// Repros on x64, does not repro in ia32 | |
#include "v8.h" | |
#include <iostream> | |
#include <assert.h> | |
#include <pthread.h> | |
#include <stdlib.h> | |
using namespace v8; | |
Isolate* isolate; | |
Persistent<Script> script; | |
void* thread_entry(void* arg); | |
int main(int argc, char** argv) { | |
V8::InitializeICU(); | |
V8::SetFlagsFromCommandLine(&argc, argv, true); | |
isolate = Isolate::GetCurrent(); | |
{ | |
Locker locker(isolate); | |
HandleScope scope(isolate); | |
// Compile a function which will keep using the stack until v8 cuts it off | |
Handle<Context> context = Context::New(isolate); | |
context->Enter(); | |
script.Reset(isolate, Script::Compile(String::NewFromUtf8(isolate, "function F() { F(); }; F();"))); | |
TryCatch try_catch; | |
// Run the function once and catch the error to generate machine code | |
Local<Script>::New(isolate, script)->Run(); | |
if (try_catch.HasCaught()) { | |
String::Utf8Value message(Handle<Object>::Cast(try_catch.Exception())->Get(String::NewFromUtf8(isolate, "type"))); | |
std::cerr <<"exception->" <<*message <<"\n"; | |
} | |
context->Exit(); | |
// Create a new thread with 600kb of stack space. v8 snapshot will be <400kb, so this is more than | |
// enough. | |
pthread_attr_t attr; | |
pthread_attr_init(&attr); | |
assert(!pthread_attr_setstacksize(&attr, 1024 * 600)); | |
pthread_t thread; | |
pthread_create(&thread, &attr, &thread_entry, NULL); | |
void* ret; | |
{ | |
// Jump into the new thread and wait for it to finish | |
Unlocker unlocker(isolate); | |
pthread_join(thread, &ret); | |
} | |
script.Reset(); | |
} | |
V8::Dispose(); | |
return 0; | |
} | |
void* thread_entry(void* arg) { | |
Locker locker(isolate); | |
// Give v8 400kb of stack space (which it will duly ignore) | |
ResourceConstraints constraints; | |
constraints.set_stack_limit(reinterpret_cast<uint32_t*>((char*)&constraints - 1024 * 400)); | |
SetResourceConstraints(isolate, &constraints); | |
// Create a new context to run the script from main() | |
HandleScope scope(isolate); | |
Handle<Context> context = Context::New(isolate); | |
context->Enter(); | |
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * | |
// Uncomment this line for a workaround! This will eventually invoke i::Heap::SetStackLimits() | |
// and the heap limits will be correctly set | |
//Script::Compile(String::NewFromUtf8(isolate, "void 0;")); | |
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * | |
// Run the infinite recursion script and try to catch the error | |
TryCatch try_catch; | |
Local<Script>::New(isolate, script)->Run(); | |
if (try_catch.HasCaught()) { | |
String::Utf8Value message(Handle<Object>::Cast(try_catch.Exception())->Get(String::NewFromUtf8(isolate, "type"))); | |
std::cerr <<"exception->" <<*message <<"\n"; | |
} | |
context->Exit(); | |
return NULL; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment