| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 74f4435 commit 8b50e95
5 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -5380,6 +5380,19 @@ class V8_EXPORT Isolate { | |||
| 5380 | 5380 | */ | |
| 5381 | 5381 | static Isolate* GetCurrent(); | |
| 5382 | 5382 | ||
| 5383 | + /** | ||
| 5384 | + * Custom callback used by embedders to help V8 determine if it should abort | ||
| 5385 | + * when it throws and no internal handler is predicted to catch the | ||
| 5386 | + * exception. If --abort-on-uncaught-exception is used on the command line, | ||
| 5387 | + * then V8 will abort if either: | ||
| 5388 | + * - no custom callback is set. | ||
| 5389 | + * - the custom callback set returns true. | ||
| 5390 | + * Otherwise, the custom callback will not be called and V8 will not abort. | ||
| 5391 | + */ | ||
| 5392 | + typedef bool (*AbortOnUncaughtExceptionCallback)(Isolate*); | ||
| 5393 | + void SetAbortOnUncaughtExceptionCallback( | ||
| 5394 | + AbortOnUncaughtExceptionCallback callback); | ||
| 5395 | + | ||
| 5383 | 5396 | /** | |
| 5384 | 5397 | * Methods below this point require holding a lock (using Locker) in | |
| 5385 | 5398 | * a multi-threaded environment. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -7176,6 +7176,13 @@ void Isolate::Exit() { | |||
| 7176 | 7176 | } | |
| 7177 | 7177 | ||
| 7178 | 7178 | ||
| 7179 | + void Isolate::SetAbortOnUncaughtExceptionCallback( | ||
| 7180 | + AbortOnUncaughtExceptionCallback callback) { | ||
| 7181 | + i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); | ||
| 7182 | + isolate->SetAbortOnUncaughtExceptionCallback(callback); | ||
| 7183 | + } | ||
| 7184 | + | ||
| 7185 | + | ||
| 7179 | 7186 | Isolate::DisallowJavascriptExecutionScope::DisallowJavascriptExecutionScope( | |
| 7180 | 7187 | Isolate* isolate, | |
| 7181 | 7188 | Isolate::DisallowJavascriptExecutionScope::OnFailure on_failure) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1013,13 +1013,21 @@ Object* Isolate::Throw(Object* exception, MessageLocation* location) { | |||
| 1013 | 1013 | Handle<Object> message_obj = CreateMessage(exception_handle, location); | |
| 1014 | 1014 | thread_local_top()->pending_message_obj_ = *message_obj; | |
| 1015 | 1015 | ||
| 1016 | - // If the abort-on-uncaught-exception flag is specified, abort on any | ||
| 1017 | - // exception not caught by JavaScript, even when an external handler is | ||
| 1018 | - // present. This flag is intended for use by JavaScript developers, so | ||
| 1019 | - // print a user-friendly stack trace (not an internal one). | ||
| 1016 | + // For any exception not caught by JavaScript, even when an external | ||
| 1017 | + // handler is present: | ||
| 1018 | + // If the abort-on-uncaught-exception flag is specified, and if the | ||
| 1019 | + // embedder didn't specify a custom uncaught exception callback, | ||
| 1020 | + // or if the custom callback determined that V8 should abort, then | ||
| 1021 | + // abort. | ||
| 1020 | 1022 | if (FLAG_abort_on_uncaught_exception && | |
| 1021 | - PredictExceptionCatcher() != CAUGHT_BY_JAVASCRIPT) { | ||
| 1022 | - FLAG_abort_on_uncaught_exception = false; // Prevent endless recursion. | ||
| 1023 | + PredictExceptionCatcher() != CAUGHT_BY_JAVASCRIPT && | ||
| 1024 | + (!abort_on_uncaught_exception_callback_ || | ||
| 1025 | + abort_on_uncaught_exception_callback_( | ||
| 1026 | + reinterpret_cast<v8::Isolate*>(this)))) { | ||
| 1027 | + // Prevent endless recursion. | ||
| 1028 | + FLAG_abort_on_uncaught_exception = false; | ||
| 1029 | + // This flag is intended for use by JavaScript developers, so | ||
| 1030 | + // print a user-friendly stack trace (not an internal one). | ||
| 1023 | 1031 | PrintF(stderr, "%s\n\nFROM\n", | |
| 1024 | 1032 | MessageHandler::GetLocalizedMessage(this, message_obj).get()); | |
| 1025 | 1033 | PrintCurrentStackTrace(stderr); | |
@@ -1612,6 +1620,12 @@ void Isolate::SetCaptureStackTraceForUncaughtExceptions( | |||
| 1612 | 1620 | } | |
| 1613 | 1621 | ||
| 1614 | 1622 | ||
| 1623 | + void Isolate::SetAbortOnUncaughtExceptionCallback( | ||
| 1624 | + v8::Isolate::AbortOnUncaughtExceptionCallback callback) { | ||
| 1625 | + abort_on_uncaught_exception_callback_ = callback; | ||
| 1626 | + } | ||
| 1627 | + | ||
| 1628 | + | ||
| 1615 | 1629 | Handle<Context> Isolate::native_context() { | |
| 1616 | 1630 | return handle(context()->native_context()); | |
| 1617 | 1631 | } | |
@@ -1782,7 +1796,8 @@ Isolate::Isolate(bool enable_serializer) | |||
| 1782 | 1796 | next_unique_sfi_id_(0), | |
| 1783 | 1797 | #endif | |
| 1784 | 1798 | use_counter_callback_(NULL), | |
| 1785 | - basic_block_profiler_(NULL) { | ||
| 1799 | + basic_block_profiler_(NULL), | ||
| 1800 | + abort_on_uncaught_exception_callback_(NULL) { | ||
| 1786 | 1801 | { | |
| 1787 | 1802 | base::LockGuard<base::Mutex> lock_guard(thread_data_table_mutex_.Pointer()); | |
| 1788 | 1803 | CHECK(thread_data_table_); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -690,6 +690,9 @@ class Isolate { | |||
| 690 | 690 | int frame_limit, | |
| 691 | 691 | StackTrace::StackTraceOptions options); | |
| 692 | 692 | ||
| 693 | + void SetAbortOnUncaughtExceptionCallback( | ||
| 694 | + v8::Isolate::AbortOnUncaughtExceptionCallback callback); | ||
| 695 | + | ||
| 693 | 696 | enum PrintStackMode { kPrintStackConcise, kPrintStackVerbose }; | |
| 694 | 697 | void PrintCurrentStackTrace(FILE* out); | |
| 695 | 698 | void PrintStack(StringStream* accumulator, | |
@@ -1363,6 +1366,9 @@ class Isolate { | |||
| 1363 | 1366 | ||
| 1364 | 1367 | v8::ArrayBuffer::Allocator* array_buffer_allocator_; | |
| 1365 | 1368 | ||
| 1369 | + v8::Isolate::AbortOnUncaughtExceptionCallback | ||
| 1370 | + abort_on_uncaught_exception_callback_; | ||
| 1371 | + | ||
| 1366 | 1372 | friend class ExecutionAccess; | |
| 1367 | 1373 | friend class HandleScopeImplementer; | |
| 1368 | 1374 | friend class OptimizingCompileDispatcher; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -21880,3 +21880,34 @@ TEST(CompatibleReceiverCheckOnCachedICHandler) { | |||
| 21880 | 21880 | "result;\n", | |
| 21881 | 21881 | 0); | |
| 21882 | 21882 | } | |
| 21883 | + | ||
| 21884 | + | ||
| 21885 | + static int nb_uncaught_exception_callback_calls = 0; | ||
| 21886 | + | ||
| 21887 | + | ||
| 21888 | + bool NoAbortOnUncaughtException(v8::Isolate* isolate) { | ||
| 21889 | + ++nb_uncaught_exception_callback_calls; | ||
| 21890 | + return false; | ||
| 21891 | + } | ||
| 21892 | + | ||
| 21893 | + | ||
| 21894 | + TEST(AbortOnUncaughtExceptionNoAbort) { | ||
| 21895 | + v8::Isolate* isolate = CcTest::isolate(); | ||
| 21896 | + v8::HandleScope handle_scope(isolate); | ||
| 21897 | + v8::Handle<v8::ObjectTemplate> global_template = | ||
| 21898 | + v8::ObjectTemplate::New(isolate); | ||
| 21899 | + LocalContext env(NULL, global_template); | ||
| 21900 | + | ||
| 21901 | + i::FLAG_abort_on_uncaught_exception = true; | ||
| 21902 | + isolate->SetAbortOnUncaughtExceptionCallback(NoAbortOnUncaughtException); | ||
| 21903 | + | ||
| 21904 | + CompileRun("function boom() { throw new Error(\"boom\") }"); | ||
| 21905 | + | ||
| 21906 | + v8::Local<v8::Object> global_object = env->Global(); | ||
| 21907 | + v8::Local<v8::Function> foo = | ||
| 21908 | + v8::Local<v8::Function>::Cast(global_object->Get(v8_str("boom"))); | ||
| 21909 | + | ||
| 21910 | + foo->Call(global_object, 0, NULL); | ||
| 21911 | + | ||
| 21912 | + CHECK_EQ(1, nb_uncaught_exception_callback_calls); | ||
| 21913 | + } | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments