Browse Source

v8: port fbff705 from v0.10 to v0.12

fbff705
Add v8::Isolate::SetAbortOnUncaughtException() so the user can be
notified when an uncaught exception has bubbled.

Fixes: https://github.com/nodejs/node-v0.x-archive/issues/8877
PR-URL: https://github.com/nodejs/node-v0.x-archive/pull/25835
Reviewed-By: misterdjules - Julien Gilli <jgilli@nodejs.org>
v0.12-staging
Jeremy Whitlock 10 years ago
committed by Julien Gilli
parent
commit
1982ed6e63
  1. 11
      deps/v8/include/v8.h
  2. 7
      deps/v8/src/api.cc
  3. 40
      deps/v8/src/isolate.cc
  4. 5
      deps/v8/src/isolate.h

11
deps/v8/include/v8.h

@ -4186,6 +4186,17 @@ class V8_EXPORT Isolate {
*/ */
static Isolate* GetCurrent(); static Isolate* GetCurrent();
/**
* Custom callback used by embedders to help V8 determine if it should abort
* when it throws and no internal handler can catch the exception.
* If FLAG_abort_on_uncaught_exception is true, then V8 will abort if either:
* - no custom callback is set.
* - the custom callback set returns true.
* Otherwise it won't abort.
*/
typedef bool (*abort_on_uncaught_exception_t)(Isolate*);
void SetAbortOnUncaughtException(abort_on_uncaught_exception_t callback);
/** /**
* Methods below this point require holding a lock (using Locker) in * Methods below this point require holding a lock (using Locker) in
* a multi-threaded environment. * a multi-threaded environment.

7
deps/v8/src/api.cc

@ -6556,6 +6556,13 @@ void Isolate::Enter() {
} }
void Isolate::SetAbortOnUncaughtException(
abort_on_uncaught_exception_t callback) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
isolate->SetAbortOnUncaughtException(callback);
}
void Isolate::Exit() { void Isolate::Exit() {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
isolate->Exit(); isolate->Exit();

40
deps/v8/src/isolate.cc

@ -1090,19 +1090,30 @@ void Isolate::DoThrow(Object* exception, MessageLocation* location) {
thread_local_top()->pending_message_end_pos_ = location->end_pos(); thread_local_top()->pending_message_end_pos_ = location->end_pos();
} }
// If the abort-on-uncaught-exception flag is specified, abort on any // If the abort-on-uncaught-exception flag is specified, and if the
// exception not caught by JavaScript, even when an external handler is // exception is not caught by JavaScript (even when an external handler is
// present. This flag is intended for use by JavaScript developers, so // present).
// print a user-friendly stack trace (not an internal one).
if (fatal_exception_depth == 0 && if (fatal_exception_depth == 0 &&
FLAG_abort_on_uncaught_exception && FLAG_abort_on_uncaught_exception &&
(report_exception || can_be_caught_externally)) { (report_exception || can_be_caught_externally)) {
fatal_exception_depth++; // If the embedder didn't specify a custom uncaught exception callback,
PrintF(stderr, // or if the custom callback determined that V8 should abort, then
"%s\n\nFROM\n", // abort
MessageHandler::GetLocalizedMessage(this, message_obj).get()); bool should_abort = !abort_on_uncaught_exception_callback_ ||
PrintCurrentStackTrace(stderr); abort_on_uncaught_exception_callback_(
base::OS::Abort(); reinterpret_cast<v8::Isolate*>(this)
);
if (should_abort) {
fatal_exception_depth++;
// This flag is intended for use by JavaScript developers, so
// print a user-friendly stack trace (not an internal one).
PrintF(stderr,
"%s\n\nFROM\n",
MessageHandler::GetLocalizedMessage(this, message_obj).get());
PrintCurrentStackTrace(stderr);
base::OS::Abort();
}
} }
} else if (location != NULL && !location->script().is_null()) { } else if (location != NULL && !location->script().is_null()) {
// We are bootstrapping and caught an error where the location is set // We are bootstrapping and caught an error where the location is set
@ -1299,6 +1310,12 @@ void Isolate::SetCaptureStackTraceForUncaughtExceptions(
} }
void Isolate::SetAbortOnUncaughtException(
v8::Isolate::abort_on_uncaught_exception_t callback) {
abort_on_uncaught_exception_callback_ = callback;
}
Handle<Context> Isolate::native_context() { Handle<Context> Isolate::native_context() {
return handle(context()->native_context()); return handle(context()->native_context());
} }
@ -1474,7 +1491,8 @@ Isolate::Isolate()
num_sweeper_threads_(0), num_sweeper_threads_(0),
stress_deopt_count_(0), stress_deopt_count_(0),
next_optimization_id_(0), next_optimization_id_(0),
use_counter_callback_(NULL) { use_counter_callback_(NULL),
abort_on_uncaught_exception_callback_(NULL) {
id_ = base::NoBarrier_AtomicIncrement(&isolate_counter_, 1); id_ = base::NoBarrier_AtomicIncrement(&isolate_counter_, 1);
TRACE_ISOLATE(constructor); TRACE_ISOLATE(constructor);

5
deps/v8/src/isolate.h

@ -707,6 +707,9 @@ class Isolate {
int frame_limit, int frame_limit,
StackTrace::StackTraceOptions options); StackTrace::StackTraceOptions options);
typedef bool (*abort_on_uncaught_exception_t)(v8::Isolate*);
void SetAbortOnUncaughtException(abort_on_uncaught_exception_t callback);
void PrintCurrentStackTrace(FILE* out); void PrintCurrentStackTrace(FILE* out);
void PrintStack(StringStream* accumulator); void PrintStack(StringStream* accumulator);
void PrintStack(FILE* out); void PrintStack(FILE* out);
@ -1331,6 +1334,8 @@ class Isolate {
v8::Isolate::UseCounterCallback use_counter_callback_; v8::Isolate::UseCounterCallback use_counter_callback_;
abort_on_uncaught_exception_t abort_on_uncaught_exception_callback_;
friend class ExecutionAccess; friend class ExecutionAccess;
friend class HandleScopeImplementer; friend class HandleScopeImplementer;
friend class IsolateInitializer; friend class IsolateInitializer;

Loading…
Cancel
Save