Skip to content

Instantly share code, notes, and snippets.

@bnoordhuis
Created February 10, 2014 01:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bnoordhuis/8908704 to your computer and use it in GitHub Desktop.
Save bnoordhuis/8908704 to your computer and use it in GitHub Desktop.
// 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