From cf081a471205345abeebc5ee06ed02493c6dbdf1 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Sat, 21 Mar 2015 13:41:16 +0100 Subject: [PATCH] vm: fix crash on fatal error in debug context Ensure that the debug context has an Environment assigned in case a fatal error is raised. The fatal exception handler in node.cc is not equipped to deal with contexts that don't have one and can't easily be taught that due to a deficiency in the V8 API: there is no way for the embedder to tell if the data index is in use. Fixes: https://github.com/iojs/io.js/issues/1190 PR-URL: https://github.com/iojs/io.js/pull/1229 Reviewed-By: Fedor Indutny --- src/env.h | 6 ++---- src/node_contextify.cc | 24 +++++++++++++++++++++++- test/fixtures/vm-run-in-debug-context.js | 4 ++++ test/parallel/test-vm-debug-context.js | 23 +++++++++++++++++++++++ 4 files changed, 52 insertions(+), 5 deletions(-) create mode 100644 test/fixtures/vm-run-in-debug-context.js diff --git a/src/env.h b/src/env.h index 73940ad0d4..cad03c4531 100644 --- a/src/env.h +++ b/src/env.h @@ -474,6 +474,8 @@ class Environment { inline HandleWrapQueue* handle_wrap_queue() { return &handle_wrap_queue_; } inline ReqWrapQueue* req_wrap_queue() { return &req_wrap_queue_; } + static const int kContextEmbedderDataIndex = NODE_CONTEXT_EMBEDDER_DATA_INDEX; + private: static const int kIsolateSlot = NODE_ISOLATE_SLOT; @@ -482,10 +484,6 @@ class Environment { inline ~Environment(); inline IsolateData* isolate_data() const; - enum ContextEmbedderDataIndex { - kContextEmbedderDataIndex = NODE_CONTEXT_EMBEDDER_DATA_INDEX - }; - v8::Isolate* const isolate_; IsolateData* const isolate_data_; uv_check_t immediate_check_handle_; diff --git a/src/node_contextify.cc b/src/node_contextify.cc index 6985a33982..81d0388a35 100644 --- a/src/node_contextify.cc +++ b/src/node_contextify.cc @@ -233,10 +233,32 @@ class ContextifyContext { static void RunInDebugContext(const FunctionCallbackInfo& args) { + // Ensure that the debug context has an Environment assigned in case + // a fatal error is raised. The fatal exception handler in node.cc + // is not equipped to deal with contexts that don't have one and + // can't easily be taught that due to a deficiency in the V8 API: + // there is no way for the embedder to tell if the data index is + // in use. + struct ScopedEnvironment { + ScopedEnvironment(Local context, Environment* env) + : context_(context) { + const int index = Environment::kContextEmbedderDataIndex; + context->SetAlignedPointerInEmbedderData(index, env); + } + ~ScopedEnvironment() { + const int index = Environment::kContextEmbedderDataIndex; + context_->SetAlignedPointerInEmbedderData(index, nullptr); + } + Local context_; + }; + Local script_source(args[0]->ToString(args.GetIsolate())); if (script_source.IsEmpty()) return; // Exception pending. - Context::Scope context_scope(Debug::GetDebugContext()); + Local debug_context = Debug::GetDebugContext(); + Environment* env = Environment::GetCurrent(args); + ScopedEnvironment env_scope(debug_context, env); + Context::Scope context_scope(debug_context); Local