Skip to content
This repository has been archived by the owner on Oct 16, 2021. It is now read-only.

Commit

Permalink
v8: add api for aborting on uncaught exception
Browse files Browse the repository at this point in the history
Add v8::Isolate::SetAbortOnUncaughtException() so the user can be
notified when an uncaught exception has bubbled.

PR-URL: joyent#8666
Reviewed-by: Trevor Norris <trev.norris@gmail.com>

Port fbff705 to deps/v8ppc and deps/v8z
  • Loading branch information
richardlau committed Dec 22, 2014
1 parent b73a7f8 commit 453dbc4
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 20 deletions.
11 changes: 11 additions & 0 deletions deps/v8ppc/include/v8.h
Original file line number Diff line number Diff line change
Expand Up @@ -2845,6 +2845,17 @@ class V8EXPORT Isolate {
*/
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)();
void SetAbortOnUncaughtException(abort_on_uncaught_exception_t callback);

/**
* Methods below this point require holding a lock (using Locker) in
* a multi-threaded environment.
Expand Down
5 changes: 5 additions & 0 deletions deps/v8ppc/src/api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5565,6 +5565,11 @@ void Isolate::Enter() {
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() {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
Expand Down
33 changes: 23 additions & 10 deletions deps/v8ppc/src/isolate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1154,18 +1154,26 @@ void Isolate::DoThrow(Object* exception, MessageLocation* location) {
thread_local_top()->pending_message_end_pos_ = location->end_pos();
}

// If the abort-on-uncaught-exception flag is specified, abort on any
// exception not caught by JavaScript, even when an external handler is
// present. This flag is intended for use by JavaScript developers, so
// print a user-friendly stack trace (not an internal one).
// If the abort-on-uncaught-exception flag is specified, and if the
// exception is not caught by JavaScript (even when an external handler is
// present).
if (fatal_exception_depth == 0 &&
FLAG_abort_on_uncaught_exception &&
(report_exception || can_be_caught_externally)) {
fatal_exception_depth++;
fprintf(stderr, "%s\n\nFROM\n",
*MessageHandler::GetLocalizedMessage(message_obj));
PrintCurrentStackTrace(stderr);
OS::Abort();
// If the embedder didn't specify a custom uncaught exception callback,
// or if the custom callback determined that V8 should abort, then
// abort
bool should_abort = !abort_on_uncaught_exception_callback_ ||
abort_on_uncaught_exception_callback_();
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).
fprintf(stderr, "%s\n\nFROM\n",
*MessageHandler::GetLocalizedMessage(message_obj));
PrintCurrentStackTrace(stderr);
OS::Abort();
}
}
} else if (location != NULL && !location->script().is_null()) {
// We are bootstrapping and caught an error where the location is set
Expand Down Expand Up @@ -1341,6 +1349,10 @@ void Isolate::SetCaptureStackTraceForUncaughtExceptions(
stack_trace_for_uncaught_exceptions_options_ = options;
}

void Isolate::SetAbortOnUncaughtException(
v8::Isolate::abort_on_uncaught_exception_t callback) {
abort_on_uncaught_exception_callback_ = callback;
}

bool Isolate::is_out_of_memory() {
if (has_pending_exception()) {
Expand Down Expand Up @@ -1538,7 +1550,8 @@ Isolate::Isolate()
date_cache_(NULL),
context_exit_happened_(false),
deferred_handles_head_(NULL),
optimizing_compiler_thread_(this) {
optimizing_compiler_thread_(this),
abort_on_uncaught_exception_callback_(NULL) {
TRACE_ISOLATE(constructor);

memset(isolate_addresses_, 0,
Expand Down
5 changes: 5 additions & 0 deletions deps/v8ppc/src/isolate.h
Original file line number Diff line number Diff line change
Expand Up @@ -701,6 +701,9 @@ class Isolate {
int frame_limit,
StackTrace::StackTraceOptions options);

typedef bool (*abort_on_uncaught_exception_t)();
void SetAbortOnUncaughtException(abort_on_uncaught_exception_t callback);

// Tells whether the current context has experienced an out of memory
// exception.
bool is_out_of_memory();
Expand Down Expand Up @@ -1305,6 +1308,8 @@ class Isolate {
DeferredHandles* deferred_handles_head_;
OptimizingCompilerThread optimizing_compiler_thread_;

abort_on_uncaught_exception_t abort_on_uncaught_exception_callback_;

friend class ExecutionAccess;
friend class HandleScopeImplementer;
friend class IsolateInitializer;
Expand Down
11 changes: 11 additions & 0 deletions deps/v8z/include/v8.h
Original file line number Diff line number Diff line change
Expand Up @@ -2845,6 +2845,17 @@ class V8EXPORT Isolate {
*/
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)();
void SetAbortOnUncaughtException(abort_on_uncaught_exception_t callback);

/**
* Methods below this point require holding a lock (using Locker) in
* a multi-threaded environment.
Expand Down
5 changes: 5 additions & 0 deletions deps/v8z/src/api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5565,6 +5565,11 @@ void Isolate::Enter() {
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() {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
Expand Down
33 changes: 23 additions & 10 deletions deps/v8z/src/isolate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1156,18 +1156,26 @@ void Isolate::DoThrow(Object* exception, MessageLocation* location) {
thread_local_top()->pending_message_end_pos_ = location->end_pos();
}

// If the abort-on-uncaught-exception flag is specified, abort on any
// exception not caught by JavaScript, even when an external handler is
// present. This flag is intended for use by JavaScript developers, so
// print a user-friendly stack trace (not an internal one).
// If the abort-on-uncaught-exception flag is specified, and if the
// exception is not caught by JavaScript (even when an external handler is
// present).
if (fatal_exception_depth == 0 &&
FLAG_abort_on_uncaught_exception &&
(report_exception || can_be_caught_externally)) {
fatal_exception_depth++;
fprintf(stderr, "%s\n\nFROM\n",
*MessageHandler::GetLocalizedMessage(message_obj));
PrintCurrentStackTrace(stderr);
OS::Abort();
// If the embedder didn't specify a custom uncaught exception callback,
// or if the custom callback determined that V8 should abort, then
// abort
bool should_abort = !abort_on_uncaught_exception_callback_ ||
abort_on_uncaught_exception_callback_();
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).
fprintf(stderr, "%s\n\nFROM\n",
*MessageHandler::GetLocalizedMessage(message_obj));
PrintCurrentStackTrace(stderr);
OS::Abort();
}
}
} else if (location != NULL && !location->script().is_null()) {
// We are bootstrapping and caught an error where the location is set
Expand Down Expand Up @@ -1343,6 +1351,10 @@ void Isolate::SetCaptureStackTraceForUncaughtExceptions(
stack_trace_for_uncaught_exceptions_options_ = options;
}

void Isolate::SetAbortOnUncaughtException(
v8::Isolate::abort_on_uncaught_exception_t callback) {
abort_on_uncaught_exception_callback_ = callback;
}

bool Isolate::is_out_of_memory() {
if (has_pending_exception()) {
Expand Down Expand Up @@ -1542,7 +1554,8 @@ Isolate::Isolate()
date_cache_(NULL),
context_exit_happened_(false),
deferred_handles_head_(NULL),
optimizing_compiler_thread_(this) {
optimizing_compiler_thread_(this),
abort_on_uncaught_exception_callback_(NULL) {
TRACE_ISOLATE(constructor);

memset(isolate_addresses_, 0,
Expand Down
5 changes: 5 additions & 0 deletions deps/v8z/src/isolate.h
Original file line number Diff line number Diff line change
Expand Up @@ -705,6 +705,9 @@ class Isolate {
int frame_limit,
StackTrace::StackTraceOptions options);

typedef bool (*abort_on_uncaught_exception_t)();
void SetAbortOnUncaughtException(abort_on_uncaught_exception_t callback);

// Tells whether the current context has experienced an out of memory
// exception.
bool is_out_of_memory();
Expand Down Expand Up @@ -1311,6 +1314,8 @@ class Isolate {
DeferredHandles* deferred_handles_head_;
OptimizingCompilerThread optimizing_compiler_thread_;

abort_on_uncaught_exception_t abort_on_uncaught_exception_callback_;

friend class ExecutionAccess;
friend class HandleScopeImplementer;
friend class IsolateInitializer;
Expand Down

0 comments on commit 453dbc4

Please sign in to comment.