]>
Commit | Line | Data |
---|---|---|
f8f77d43 ER |
1 | # Fix issues with abort on uncaught exception |
2 | # https://github.com/joyent/node/pull/8666 | |
3 | # https://github.com/joyent/node/issues/8631 | |
4 | # https://github.com/joyent/node/issues/8630 | |
5 | From fbff7054a47551387a99244e2cf0631f30406798 Mon Sep 17 00:00:00 2001 | |
6 | From: Trevor Norris <trev.norris@gmail.com> | |
7 | Date: Tue, 18 Nov 2014 16:37:54 -0800 | |
8 | Subject: [PATCH] v8: add api for aborting on uncaught exception | |
9 | ||
10 | Add v8::Isolate::SetAbortOnUncaughtException() so the user can be | |
11 | notified when an uncaught exception has bubbled. | |
12 | ||
13 | PR-URL: https://github.com/joyent/node/pull/8666 | |
14 | Reviewed-by: Trevor Norris <trev.norris@gmail.com> | |
15 | --- | |
16 | include/v8.h | 11 +++++++++++ | |
17 | src/api.cc | 5 +++++ | |
18 | src/isolate.cc | 33 +++++++++++++++++++++++---------- | |
19 | src/isolate.h | 5 +++++ | |
20 | 4 files changed, 44 insertions(+), 10 deletions(-) | |
21 | ||
22 | diff --git a/include/v8.h b/include/v8.h | |
23 | index 71a0d01..e229ed9 100644 | |
24 | --- a/include/v8.h | |
25 | +++ b/include/v8.h | |
26 | @@ -2842,6 +2842,17 @@ class V8EXPORT Isolate { | |
27 | static Isolate* GetCurrent(); | |
28 | ||
29 | /** | |
30 | + * Custom callback used by embedders to help V8 determine if it should abort | |
31 | + * when it throws and no internal handler can catch the exception. | |
32 | + * If FLAG_abort_on_uncaught_exception is true, then V8 will abort if either: | |
33 | + * - no custom callback is set. | |
34 | + * - the custom callback set returns true. | |
35 | + * Otherwise it won't abort. | |
36 | + */ | |
37 | + typedef bool (*abort_on_uncaught_exception_t)(); | |
38 | + void SetAbortOnUncaughtException(abort_on_uncaught_exception_t callback); | |
39 | + | |
40 | + /** | |
41 | * Methods below this point require holding a lock (using Locker) in | |
42 | * a multi-threaded environment. | |
43 | */ | |
44 | diff --git a/src/api.cc b/src/api.cc | |
45 | index 96d564f..4b1aa67 100644 | |
46 | --- a/src/api.cc | |
47 | +++ b/src/api.cc | |
48 | @@ -5550,6 +5550,11 @@ void Isolate::Enter() { | |
49 | isolate->Enter(); | |
50 | } | |
51 | ||
52 | +void Isolate::SetAbortOnUncaughtException( | |
53 | + abort_on_uncaught_exception_t callback) { | |
54 | + i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); | |
55 | + isolate->SetAbortOnUncaughtException(callback); | |
56 | +} | |
57 | ||
58 | void Isolate::Exit() { | |
59 | i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); | |
196df260 ER |
60 | --- v8-3.15.11.18/src/isolate.cc 2013-05-07 21:00:06.000000000 +0300 |
61 | +++ v8-3.15.11.18/src/isolate.cc 2015-10-17 22:30:21.746915216 +0300 | |
62 | @@ -1250,6 +1250,28 @@ | |
63 | thread_local_top()->pending_message_start_pos_ = location->start_pos(); | |
f8f77d43 ER |
64 | thread_local_top()->pending_message_end_pos_ = location->end_pos(); |
65 | } | |
196df260 | 66 | + |
f8f77d43 ER |
67 | + // If the abort-on-uncaught-exception flag is specified, and if the |
68 | + // exception is not caught by JavaScript (even when an external handler is | |
69 | + // present). | |
196df260 ER |
70 | + if (fatal_exception_depth == 0 && |
71 | + FLAG_abort_on_uncaught_exception && | |
72 | + (report_exception || can_be_caught_externally)) { | |
f8f77d43 ER |
73 | + // If the embedder didn't specify a custom uncaught exception callback, |
74 | + // or if the custom callback determined that V8 should abort, then | |
75 | + // abort | |
76 | + bool should_abort = !abort_on_uncaught_exception_callback_ || | |
77 | + abort_on_uncaught_exception_callback_(); | |
78 | + if (should_abort) { | |
79 | + fatal_exception_depth++; | |
80 | + // This flag is intended for use by JavaScript developers, so | |
81 | + // print a user-friendly stack trace (not an internal one). | |
82 | + fprintf(stderr, "%s\n\nFROM\n", | |
83 | + *MessageHandler::GetLocalizedMessage(message_obj)); | |
84 | + PrintCurrentStackTrace(stderr); | |
85 | + OS::Abort(); | |
86 | + } | |
196df260 | 87 | + } |
f8f77d43 ER |
88 | } else if (location != NULL && !location->script().is_null()) { |
89 | // We are bootstrapping and caught an error where the location is set | |
196df260 | 90 | // and we have a script for the location. |
f8f77d43 ER |
91 | @@ -1339,6 +1347,10 @@ void Isolate::SetCaptureStackTraceForUncaughtExceptions( |
92 | stack_trace_for_uncaught_exceptions_options_ = options; | |
93 | } | |
94 | ||
95 | +void Isolate::SetAbortOnUncaughtException( | |
96 | + v8::Isolate::abort_on_uncaught_exception_t callback) { | |
97 | + abort_on_uncaught_exception_callback_ = callback; | |
98 | +} | |
99 | ||
100 | bool Isolate::is_out_of_memory() { | |
101 | if (has_pending_exception()) { | |
102 | @@ -1534,7 +1546,8 @@ Isolate::Isolate() | |
103 | date_cache_(NULL), | |
104 | context_exit_happened_(false), | |
105 | deferred_handles_head_(NULL), | |
106 | - optimizing_compiler_thread_(this) { | |
107 | + optimizing_compiler_thread_(this), | |
108 | + abort_on_uncaught_exception_callback_(NULL) { | |
109 | TRACE_ISOLATE(constructor); | |
110 | ||
111 | memset(isolate_addresses_, 0, | |
112 | diff --git a/src/isolate.h b/src/isolate.h | |
113 | index 2769ca7..8719aa1 100644 | |
114 | --- a/src/isolate.h | |
115 | +++ b/src/isolate.h | |
116 | @@ -692,6 +692,9 @@ class Isolate { | |
117 | int frame_limit, | |
118 | StackTrace::StackTraceOptions options); | |
119 | ||
120 | + typedef bool (*abort_on_uncaught_exception_t)(); | |
121 | + void SetAbortOnUncaughtException(abort_on_uncaught_exception_t callback); | |
122 | + | |
123 | // Tells whether the current context has experienced an out of memory | |
124 | // exception. | |
125 | bool is_out_of_memory(); | |
126 | @@ -1292,6 +1295,8 @@ class Isolate { | |
127 | DeferredHandles* deferred_handles_head_; | |
128 | OptimizingCompilerThread optimizing_compiler_thread_; | |
129 | ||
130 | + abort_on_uncaught_exception_t abort_on_uncaught_exception_callback_; | |
131 | + | |
132 | friend class ExecutionAccess; | |
133 | friend class HandleScopeImplementer; | |
134 | friend class IsolateInitializer; |