|
|
0ec089 |
From fbff7054a47551387a99244e2cf0631f30406798 Mon Sep 17 00:00:00 2001
|
|
|
0ec089 |
From: Trevor Norris <trev.norris@gmail.com>
|
|
|
0ec089 |
Date: Tue, 18 Nov 2014 16:37:54 -0800
|
|
|
0ec089 |
Subject: [PATCH] v8: add api for aborting on uncaught exception
|
|
|
0ec089 |
|
|
|
0ec089 |
Add v8::Isolate::SetAbortOnUncaughtException() so the user can be
|
|
|
0ec089 |
notified when an uncaught exception has bubbled.
|
|
|
0ec089 |
|
|
|
0ec089 |
PR-URL: https://github.com/joyent/node/pull/8666
|
|
|
0ec089 |
Reviewed-by: Trevor Norris <trev.norris@gmail.com>
|
|
|
0ec089 |
---
|
|
|
0ec089 |
include/v8.h | 11 +++++++++++
|
|
|
0ec089 |
src/api.cc | 5 +++++
|
|
|
0ec089 |
src/isolate.cc | 33 +++++++++++++++++++++++----------
|
|
|
0ec089 |
src/isolate.h | 5 +++++
|
|
|
0ec089 |
4 files changed, 44 insertions(+), 10 deletions(-)
|
|
|
0ec089 |
|
|
|
0ec089 |
diff --git a/include/v8.h binclude/v8.h
|
|
|
0ec089 |
index 71a0d01..e229ed9 100644
|
|
|
0ec089 |
--- a/include/v8.h
|
|
|
0ec089 |
+++ b/include/v8.h
|
|
|
0ec089 |
@@ -2846,6 +2846,17 @@ class V8EXPORT Isolate {
|
|
|
0ec089 |
static Isolate* GetCurrent();
|
|
|
0ec089 |
|
|
|
0ec089 |
/**
|
|
|
0ec089 |
+ * Custom callback used by embedders to help V8 determine if it should abort
|
|
|
0ec089 |
+ * when it throws and no internal handler can catch the exception.
|
|
|
0ec089 |
+ * If FLAG_abort_on_uncaught_exception is true, then V8 will abort if either:
|
|
|
0ec089 |
+ * - no custom callback is set.
|
|
|
0ec089 |
+ * - the custom callback set returns true.
|
|
|
0ec089 |
+ * Otherwise it won't abort.
|
|
|
0ec089 |
+ */
|
|
|
0ec089 |
+ typedef bool (*abort_on_uncaught_exception_t)();
|
|
|
0ec089 |
+ void SetAbortOnUncaughtException(abort_on_uncaught_exception_t callback);
|
|
|
0ec089 |
+
|
|
|
0ec089 |
+ /**
|
|
|
0ec089 |
* Methods below this point require holding a lock (using Locker) in
|
|
|
0ec089 |
* a multi-threaded environment.
|
|
|
0ec089 |
*/
|
|
|
0ec089 |
diff --git a/src/api.cc b/src/api.cc
|
|
|
0ec089 |
index 96d564f..4b1aa67 100644
|
|
|
0ec089 |
--- a/src/api.cc
|
|
|
0ec089 |
+++ b/src/api.cc
|
|
|
0ec089 |
@@ -5565,6 +5565,11 @@ void Isolate::Enter() {
|
|
|
0ec089 |
isolate->Enter();
|
|
|
0ec089 |
}
|
|
|
0ec089 |
|
|
|
0ec089 |
+void Isolate::SetAbortOnUncaughtException(
|
|
|
0ec089 |
+ abort_on_uncaught_exception_t callback) {
|
|
|
0ec089 |
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
|
|
|
0ec089 |
+ isolate->SetAbortOnUncaughtException(callback);
|
|
|
0ec089 |
+}
|
|
|
0ec089 |
|
|
|
0ec089 |
void Isolate::Exit() {
|
|
|
0ec089 |
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
|
|
|
0ec089 |
diff --git a/src/isolate.cc b/src/isolate.cc
|
|
|
0ec089 |
index 5a5293e..0b38616 100644
|
|
|
0ec089 |
--- a/src/isolate.cc
|
|
|
0ec089 |
+++ b/src/isolate.cc
|
|
|
0ec089 |
@@ -1152,18 +1152,26 @@ void Isolate::DoThrow(Object* exception, MessageLocation* location) {
|
|
|
0ec089 |
thread_local_top()->pending_message_end_pos_ = location->end_pos();
|
|
|
0ec089 |
}
|
|
|
0ec089 |
|
|
|
0ec089 |
- // If the abort-on-uncaught-exception flag is specified, abort on any
|
|
|
0ec089 |
- // exception not caught by JavaScript, even when an external handler is
|
|
|
0ec089 |
- // present. This flag is intended for use by JavaScript developers, so
|
|
|
0ec089 |
- // print a user-friendly stack trace (not an internal one).
|
|
|
0ec089 |
+ // If the abort-on-uncaught-exception flag is specified, and if the
|
|
|
0ec089 |
+ // exception is not caught by JavaScript (even when an external handler is
|
|
|
0ec089 |
+ // present).
|
|
|
0ec089 |
if (fatal_exception_depth == 0 &&
|
|
|
0ec089 |
FLAG_abort_on_uncaught_exception &&
|
|
|
0ec089 |
(report_exception || can_be_caught_externally)) {
|
|
|
0ec089 |
- fatal_exception_depth++;
|
|
|
0ec089 |
- fprintf(stderr, "%s\n\nFROM\n",
|
|
|
0ec089 |
- *MessageHandler::GetLocalizedMessage(message_obj));
|
|
|
0ec089 |
- PrintCurrentStackTrace(stderr);
|
|
|
0ec089 |
- OS::Abort();
|
|
|
0ec089 |
+ // If the embedder didn't specify a custom uncaught exception callback,
|
|
|
0ec089 |
+ // or if the custom callback determined that V8 should abort, then
|
|
|
0ec089 |
+ // abort
|
|
|
0ec089 |
+ bool should_abort = !abort_on_uncaught_exception_callback_ ||
|
|
|
0ec089 |
+ abort_on_uncaught_exception_callback_();
|
|
|
0ec089 |
+ if (should_abort) {
|
|
|
0ec089 |
+ fatal_exception_depth++;
|
|
|
0ec089 |
+ // This flag is intended for use by JavaScript developers, so
|
|
|
0ec089 |
+ // print a user-friendly stack trace (not an internal one).
|
|
|
0ec089 |
+ fprintf(stderr, "%s\n\nFROM\n",
|
|
|
0ec089 |
+ *MessageHandler::GetLocalizedMessage(message_obj));
|
|
|
0ec089 |
+ PrintCurrentStackTrace(stderr);
|
|
|
0ec089 |
+ OS::Abort();
|
|
|
0ec089 |
+ }
|
|
|
0ec089 |
}
|
|
|
0ec089 |
} else if (location != NULL && !location->script().is_null()) {
|
|
|
0ec089 |
// We are bootstrapping and caught an error where the location is set
|
|
|
0ec089 |
@@ -1339,6 +1347,10 @@ void Isolate::SetCaptureStackTraceForUncaughtExceptions(
|
|
|
0ec089 |
stack_trace_for_uncaught_exceptions_options_ = options;
|
|
|
0ec089 |
}
|
|
|
0ec089 |
|
|
|
0ec089 |
+void Isolate::SetAbortOnUncaughtException(
|
|
|
0ec089 |
+ v8::Isolate::abort_on_uncaught_exception_t callback) {
|
|
|
0ec089 |
+ abort_on_uncaught_exception_callback_ = callback;
|
|
|
0ec089 |
+}
|
|
|
0ec089 |
|
|
|
0ec089 |
bool Isolate::is_out_of_memory() {
|
|
|
0ec089 |
if (has_pending_exception()) {
|
|
|
0ec089 |
@@ -1534,7 +1546,8 @@ Isolate::Isolate()
|
|
|
0ec089 |
date_cache_(NULL),
|
|
|
0ec089 |
context_exit_happened_(false),
|
|
|
0ec089 |
deferred_handles_head_(NULL),
|
|
|
0ec089 |
- optimizing_compiler_thread_(this) {
|
|
|
0ec089 |
+ optimizing_compiler_thread_(this),
|
|
|
0ec089 |
+ abort_on_uncaught_exception_callback_(NULL) {
|
|
|
0ec089 |
TRACE_ISOLATE(constructor);
|
|
|
0ec089 |
|
|
|
0ec089 |
memset(isolate_addresses_, 0,
|
|
|
0ec089 |
diff --git a/src/isolate.h b/src/isolate.h
|
|
|
0ec089 |
index 2769ca7..8719aa1 100644
|
|
|
0ec089 |
--- a/src/isolate.h
|
|
|
0ec089 |
+++ b/src/isolate.h
|
|
|
0ec089 |
@@ -692,6 +692,9 @@ class Isolate {
|
|
|
0ec089 |
int frame_limit,
|
|
|
0ec089 |
StackTrace::StackTraceOptions options);
|
|
|
0ec089 |
|
|
|
0ec089 |
+ typedef bool (*abort_on_uncaught_exception_t)();
|
|
|
0ec089 |
+ void SetAbortOnUncaughtException(abort_on_uncaught_exception_t callback);
|
|
|
0ec089 |
+
|
|
|
0ec089 |
// Tells whether the current context has experienced an out of memory
|
|
|
0ec089 |
// exception.
|
|
|
0ec089 |
bool is_out_of_memory();
|
|
|
0ec089 |
@@ -1292,6 +1295,8 @@ class Isolate {
|
|
|
0ec089 |
DeferredHandles* deferred_handles_head_;
|
|
|
0ec089 |
OptimizingCompilerThread optimizing_compiler_thread_;
|
|
|
0ec089 |
|
|
|
0ec089 |
+ abort_on_uncaught_exception_t abort_on_uncaught_exception_callback_;
|
|
|
0ec089 |
+
|
|
|
0ec089 |
friend class ExecutionAccess;
|
|
|
0ec089 |
friend class HandleScopeImplementer;
|
|
|
0ec089 |
friend class IsolateInitializer;
|
|
|
0ec089 |
--
|
|
|
0ec089 |
1.8.3.1
|
|
|
0ec089 |
|