Skip to content

Commit 1982ed6

Browse files
whitlockjcJulien Gilli
authored and
Julien Gilli
committed
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: nodejs/node-v0.x-archive#8877 PR-URL: nodejs/node-v0.x-archive#25835 Reviewed-By: misterdjules - Julien Gilli <jgilli@nodejs.org>
1 parent e07c86e commit 1982ed6

File tree

4 files changed

+52
-11
lines changed

4 files changed

+52
-11
lines changed

deps/v8/include/v8.h

+11
Original file line numberDiff line numberDiff line change
@@ -4186,6 +4186,17 @@ class V8_EXPORT Isolate {
41864186
*/
41874187
static Isolate* GetCurrent();
41884188

4189+
/**
4190+
* Custom callback used by embedders to help V8 determine if it should abort
4191+
* when it throws and no internal handler can catch the exception.
4192+
* If FLAG_abort_on_uncaught_exception is true, then V8 will abort if either:
4193+
* - no custom callback is set.
4194+
* - the custom callback set returns true.
4195+
* Otherwise it won't abort.
4196+
*/
4197+
typedef bool (*abort_on_uncaught_exception_t)(Isolate*);
4198+
void SetAbortOnUncaughtException(abort_on_uncaught_exception_t callback);
4199+
41894200
/**
41904201
* Methods below this point require holding a lock (using Locker) in
41914202
* a multi-threaded environment.

deps/v8/src/api.cc

+7
Original file line numberDiff line numberDiff line change
@@ -6556,6 +6556,13 @@ void Isolate::Enter() {
65566556
}
65576557

65586558

6559+
void Isolate::SetAbortOnUncaughtException(
6560+
abort_on_uncaught_exception_t callback) {
6561+
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6562+
isolate->SetAbortOnUncaughtException(callback);
6563+
}
6564+
6565+
65596566
void Isolate::Exit() {
65606567
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
65616568
isolate->Exit();

deps/v8/src/isolate.cc

+29-11
Original file line numberDiff line numberDiff line change
@@ -1090,19 +1090,30 @@ void Isolate::DoThrow(Object* exception, MessageLocation* location) {
10901090
thread_local_top()->pending_message_end_pos_ = location->end_pos();
10911091
}
10921092

1093-
// If the abort-on-uncaught-exception flag is specified, abort on any
1094-
// exception not caught by JavaScript, even when an external handler is
1095-
// present. This flag is intended for use by JavaScript developers, so
1096-
// print a user-friendly stack trace (not an internal one).
1093+
// If the abort-on-uncaught-exception flag is specified, and if the
1094+
// exception is not caught by JavaScript (even when an external handler is
1095+
// present).
10971096
if (fatal_exception_depth == 0 &&
10981097
FLAG_abort_on_uncaught_exception &&
10991098
(report_exception || can_be_caught_externally)) {
1100-
fatal_exception_depth++;
1101-
PrintF(stderr,
1102-
"%s\n\nFROM\n",
1103-
MessageHandler::GetLocalizedMessage(this, message_obj).get());
1104-
PrintCurrentStackTrace(stderr);
1105-
base::OS::Abort();
1099+
// If the embedder didn't specify a custom uncaught exception callback,
1100+
// or if the custom callback determined that V8 should abort, then
1101+
// abort
1102+
bool should_abort = !abort_on_uncaught_exception_callback_ ||
1103+
abort_on_uncaught_exception_callback_(
1104+
reinterpret_cast<v8::Isolate*>(this)
1105+
);
1106+
1107+
if (should_abort) {
1108+
fatal_exception_depth++;
1109+
// This flag is intended for use by JavaScript developers, so
1110+
// print a user-friendly stack trace (not an internal one).
1111+
PrintF(stderr,
1112+
"%s\n\nFROM\n",
1113+
MessageHandler::GetLocalizedMessage(this, message_obj).get());
1114+
PrintCurrentStackTrace(stderr);
1115+
base::OS::Abort();
1116+
}
11061117
}
11071118
} else if (location != NULL && !location->script().is_null()) {
11081119
// We are bootstrapping and caught an error where the location is set
@@ -1299,6 +1310,12 @@ void Isolate::SetCaptureStackTraceForUncaughtExceptions(
12991310
}
13001311

13011312

1313+
void Isolate::SetAbortOnUncaughtException(
1314+
v8::Isolate::abort_on_uncaught_exception_t callback) {
1315+
abort_on_uncaught_exception_callback_ = callback;
1316+
}
1317+
1318+
13021319
Handle<Context> Isolate::native_context() {
13031320
return handle(context()->native_context());
13041321
}
@@ -1474,7 +1491,8 @@ Isolate::Isolate()
14741491
num_sweeper_threads_(0),
14751492
stress_deopt_count_(0),
14761493
next_optimization_id_(0),
1477-
use_counter_callback_(NULL) {
1494+
use_counter_callback_(NULL),
1495+
abort_on_uncaught_exception_callback_(NULL) {
14781496
id_ = base::NoBarrier_AtomicIncrement(&isolate_counter_, 1);
14791497
TRACE_ISOLATE(constructor);
14801498

deps/v8/src/isolate.h

+5
Original file line numberDiff line numberDiff line change
@@ -707,6 +707,9 @@ class Isolate {
707707
int frame_limit,
708708
StackTrace::StackTraceOptions options);
709709

710+
typedef bool (*abort_on_uncaught_exception_t)(v8::Isolate*);
711+
void SetAbortOnUncaughtException(abort_on_uncaught_exception_t callback);
712+
710713
void PrintCurrentStackTrace(FILE* out);
711714
void PrintStack(StringStream* accumulator);
712715
void PrintStack(FILE* out);
@@ -1331,6 +1334,8 @@ class Isolate {
13311334

13321335
v8::Isolate::UseCounterCallback use_counter_callback_;
13331336

1337+
abort_on_uncaught_exception_t abort_on_uncaught_exception_callback_;
1338+
13341339
friend class ExecutionAccess;
13351340
friend class HandleScopeImplementer;
13361341
friend class IsolateInitializer;

0 commit comments

Comments
 (0)