Skip to content
This repository was archived by the owner on Apr 22, 2023. It is now read-only.

Commit fbff705

Browse files
committed
v8: add api for aborting on uncaught exception
Add v8::Isolate::SetAbortOnUncaughtException() so the user can be notified when an uncaught exception has bubbled. PR-URL: #8666 Reviewed-by: Trevor Norris <[email protected]>
1 parent 8032a21 commit fbff705

File tree

4 files changed

+44
-10
lines changed

4 files changed

+44
-10
lines changed

deps/v8/include/v8.h

+11
Original file line numberDiff line numberDiff line change
@@ -2845,6 +2845,17 @@ class V8EXPORT Isolate {
28452845
*/
28462846
static Isolate* GetCurrent();
28472847

2848+
/**
2849+
* Custom callback used by embedders to help V8 determine if it should abort
2850+
* when it throws and no internal handler can catch the exception.
2851+
* If FLAG_abort_on_uncaught_exception is true, then V8 will abort if either:
2852+
* - no custom callback is set.
2853+
* - the custom callback set returns true.
2854+
* Otherwise it won't abort.
2855+
*/
2856+
typedef bool (*abort_on_uncaught_exception_t)();
2857+
void SetAbortOnUncaughtException(abort_on_uncaught_exception_t callback);
2858+
28482859
/**
28492860
* Methods below this point require holding a lock (using Locker) in
28502861
* a multi-threaded environment.

deps/v8/src/api.cc

+5
Original file line numberDiff line numberDiff line change
@@ -5565,6 +5565,11 @@ void Isolate::Enter() {
55655565
isolate->Enter();
55665566
}
55675567

5568+
void Isolate::SetAbortOnUncaughtException(
5569+
abort_on_uncaught_exception_t callback) {
5570+
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
5571+
isolate->SetAbortOnUncaughtException(callback);
5572+
}
55685573

55695574
void Isolate::Exit() {
55705575
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);

deps/v8/src/isolate.cc

+23-10
Original file line numberDiff line numberDiff line change
@@ -1152,18 +1152,26 @@ void Isolate::DoThrow(Object* exception, MessageLocation* location) {
11521152
thread_local_top()->pending_message_end_pos_ = location->end_pos();
11531153
}
11541154

1155-
// If the abort-on-uncaught-exception flag is specified, abort on any
1156-
// exception not caught by JavaScript, even when an external handler is
1157-
// present. This flag is intended for use by JavaScript developers, so
1158-
// print a user-friendly stack trace (not an internal one).
1155+
// If the abort-on-uncaught-exception flag is specified, and if the
1156+
// exception is not caught by JavaScript (even when an external handler is
1157+
// present).
11591158
if (fatal_exception_depth == 0 &&
11601159
FLAG_abort_on_uncaught_exception &&
11611160
(report_exception || can_be_caught_externally)) {
1162-
fatal_exception_depth++;
1163-
fprintf(stderr, "%s\n\nFROM\n",
1164-
*MessageHandler::GetLocalizedMessage(message_obj));
1165-
PrintCurrentStackTrace(stderr);
1166-
OS::Abort();
1161+
// If the embedder didn't specify a custom uncaught exception callback,
1162+
// or if the custom callback determined that V8 should abort, then
1163+
// abort
1164+
bool should_abort = !abort_on_uncaught_exception_callback_ ||
1165+
abort_on_uncaught_exception_callback_();
1166+
if (should_abort) {
1167+
fatal_exception_depth++;
1168+
// This flag is intended for use by JavaScript developers, so
1169+
// print a user-friendly stack trace (not an internal one).
1170+
fprintf(stderr, "%s\n\nFROM\n",
1171+
*MessageHandler::GetLocalizedMessage(message_obj));
1172+
PrintCurrentStackTrace(stderr);
1173+
OS::Abort();
1174+
}
11671175
}
11681176
} else if (location != NULL && !location->script().is_null()) {
11691177
// We are bootstrapping and caught an error where the location is set
@@ -1339,6 +1347,10 @@ void Isolate::SetCaptureStackTraceForUncaughtExceptions(
13391347
stack_trace_for_uncaught_exceptions_options_ = options;
13401348
}
13411349

1350+
void Isolate::SetAbortOnUncaughtException(
1351+
v8::Isolate::abort_on_uncaught_exception_t callback) {
1352+
abort_on_uncaught_exception_callback_ = callback;
1353+
}
13421354

13431355
bool Isolate::is_out_of_memory() {
13441356
if (has_pending_exception()) {
@@ -1534,7 +1546,8 @@ Isolate::Isolate()
15341546
date_cache_(NULL),
15351547
context_exit_happened_(false),
15361548
deferred_handles_head_(NULL),
1537-
optimizing_compiler_thread_(this) {
1549+
optimizing_compiler_thread_(this),
1550+
abort_on_uncaught_exception_callback_(NULL) {
15381551
TRACE_ISOLATE(constructor);
15391552

15401553
memset(isolate_addresses_, 0,

deps/v8/src/isolate.h

+5
Original file line numberDiff line numberDiff line change
@@ -692,6 +692,9 @@ class Isolate {
692692
int frame_limit,
693693
StackTrace::StackTraceOptions options);
694694

695+
typedef bool (*abort_on_uncaught_exception_t)();
696+
void SetAbortOnUncaughtException(abort_on_uncaught_exception_t callback);
697+
695698
// Tells whether the current context has experienced an out of memory
696699
// exception.
697700
bool is_out_of_memory();
@@ -1292,6 +1295,8 @@ class Isolate {
12921295
DeferredHandles* deferred_handles_head_;
12931296
OptimizingCompilerThread optimizing_compiler_thread_;
12941297

1298+
abort_on_uncaught_exception_t abort_on_uncaught_exception_callback_;
1299+
12951300
friend class ExecutionAccess;
12961301
friend class HandleScopeImplementer;
12971302
friend class IsolateInitializer;

0 commit comments

Comments
 (0)