| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent dc09bbe commit edfc8cd
5 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -5377,6 +5377,19 @@ class V8_EXPORT Isolate { | |||
| 5377 | 5377 | */ | |
| 5378 | 5378 | static Isolate* GetCurrent(); | |
| 5379 | 5379 | ||
| 5380 | + /** | ||
| 5381 | + * Custom callback used by embedders to help V8 determine if it should abort | ||
| 5382 | + * when it throws and no internal handler is predicted to catch the | ||
| 5383 | + * exception. If --abort-on-uncaught-exception is used on the command line, | ||
| 5384 | + * then V8 will abort if either: | ||
| 5385 | + * - no custom callback is set. | ||
| 5386 | + * - the custom callback set returns true. | ||
| 5387 | + * Otherwise, the custom callback will not be called and V8 will not abort. | ||
| 5388 | + */ | ||
| 5389 | + typedef bool (*AbortOnUncaughtExceptionCallback)(Isolate*); | ||
| 5390 | + void SetAbortOnUncaughtExceptionCallback( | ||
| 5391 | + AbortOnUncaughtExceptionCallback callback); | ||
| 5392 | + | ||
| 5380 | 5393 | /** | |
| 5381 | 5394 | * Methods below this point require holding a lock (using Locker) in | |
| 5382 | 5395 | * a multi-threaded environment. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -7105,6 +7105,13 @@ void Isolate::Exit() { | |||
| 7105 | 7105 | } | |
| 7106 | 7106 | ||
| 7107 | 7107 | ||
| 7108 | + void Isolate::SetAbortOnUncaughtExceptionCallback( | ||
| 7109 | + AbortOnUncaughtExceptionCallback callback) { | ||
| 7110 | + i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); | ||
| 7111 | + isolate->SetAbortOnUncaughtExceptionCallback(callback); | ||
| 7112 | + } | ||
| 7113 | + | ||
| 7114 | + | ||
| 7108 | 7115 | Isolate::DisallowJavascriptExecutionScope::DisallowJavascriptExecutionScope( | |
| 7109 | 7116 | Isolate* isolate, | |
| 7110 | 7117 | Isolate::DisallowJavascriptExecutionScope::OnFailure on_failure) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1008,13 +1008,21 @@ Object* Isolate::Throw(Object* exception, MessageLocation* location) { | |||
| 1008 | 1008 | Handle<Object> message_obj = CreateMessage(exception_handle, location); | |
| 1009 | 1009 | thread_local_top()->pending_message_obj_ = *message_obj; | |
| 1010 | 1010 | ||
| 1011 | - // If the abort-on-uncaught-exception flag is specified, abort on any | ||
| 1012 | - // exception not caught by JavaScript, even when an external handler is | ||
| 1013 | - // present. This flag is intended for use by JavaScript developers, so | ||
| 1014 | - // print a user-friendly stack trace (not an internal one). | ||
| 1011 | + // For any exception not caught by JavaScript, even when an external | ||
| 1012 | + // handler is present: | ||
| 1013 | + // If the abort-on-uncaught-exception flag is specified, and if the | ||
| 1014 | + // embedder didn't specify a custom uncaught exception callback, | ||
| 1015 | + // or if the custom callback determined that V8 should abort, then | ||
| 1016 | + // abort. | ||
| 1015 | 1017 | if (FLAG_abort_on_uncaught_exception && | |
| 1016 | - PredictExceptionCatcher() != CAUGHT_BY_JAVASCRIPT) { | ||
| 1017 | - FLAG_abort_on_uncaught_exception = false; // Prevent endless recursion. | ||
| 1018 | + PredictExceptionCatcher() != CAUGHT_BY_JAVASCRIPT && | ||
| 1019 | + (!abort_on_uncaught_exception_callback_ || | ||
| 1020 | + abort_on_uncaught_exception_callback_( | ||
| 1021 | + reinterpret_cast<v8::Isolate*>(this)))) { | ||
| 1022 | + // Prevent endless recursion. | ||
| 1023 | + FLAG_abort_on_uncaught_exception = false; | ||
| 1024 | + // This flag is intended for use by JavaScript developers, so | ||
| 1025 | + // print a user-friendly stack trace (not an internal one). | ||
| 1018 | 1026 | PrintF(stderr, "%s\n\nFROM\n", | |
| 1019 | 1027 | MessageHandler::GetLocalizedMessage(this, message_obj).get()); | |
| 1020 | 1028 | PrintCurrentStackTrace(stderr); | |
@@ -1602,6 +1610,12 @@ void Isolate::SetCaptureStackTraceForUncaughtExceptions( | |||
| 1602 | 1610 | } | |
| 1603 | 1611 | ||
| 1604 | 1612 | ||
| 1613 | + void Isolate::SetAbortOnUncaughtExceptionCallback( | ||
| 1614 | + v8::Isolate::AbortOnUncaughtExceptionCallback callback) { | ||
| 1615 | + abort_on_uncaught_exception_callback_ = callback; | ||
| 1616 | + } | ||
| 1617 | + | ||
| 1618 | + | ||
| 1605 | 1619 | Handle<Context> Isolate::native_context() { | |
| 1606 | 1620 | return handle(context()->native_context()); | |
| 1607 | 1621 | } | |
@@ -1770,7 +1784,8 @@ Isolate::Isolate(bool enable_serializer) | |||
| 1770 | 1784 | next_unique_sfi_id_(0), | |
| 1771 | 1785 | #endif | |
| 1772 | 1786 | use_counter_callback_(NULL), | |
| 1773 | - basic_block_profiler_(NULL) { | ||
| 1787 | + basic_block_profiler_(NULL), | ||
| 1788 | + abort_on_uncaught_exception_callback_(NULL) { | ||
| 1774 | 1789 | { | |
| 1775 | 1790 | base::LockGuard<base::Mutex> lock_guard(thread_data_table_mutex_.Pointer()); | |
| 1776 | 1791 | CHECK(thread_data_table_); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -655,6 +655,9 @@ class Isolate { | |||
| 655 | 655 | int frame_limit, | |
| 656 | 656 | StackTrace::StackTraceOptions options); | |
| 657 | 657 | ||
| 658 | + void SetAbortOnUncaughtExceptionCallback( | ||
| 659 | + v8::Isolate::AbortOnUncaughtExceptionCallback callback); | ||
| 660 | + | ||
| 658 | 661 | enum PrintStackMode { kPrintStackConcise, kPrintStackVerbose }; | |
| 659 | 662 | void PrintCurrentStackTrace(FILE* out); | |
| 660 | 663 | void PrintStack(StringStream* accumulator, | |
@@ -1325,6 +1328,9 @@ class Isolate { | |||
| 1325 | 1328 | ||
| 1326 | 1329 | std::set<Cancelable*> cancelable_tasks_; | |
| 1327 | 1330 | ||
| 1331 | + v8::Isolate::AbortOnUncaughtExceptionCallback | ||
| 1332 | + abort_on_uncaught_exception_callback_; | ||
| 1333 | + | ||
| 1328 | 1334 | friend class ExecutionAccess; | |
| 1329 | 1335 | friend class HandleScopeImplementer; | |
| 1330 | 1336 | friend class OptimizingCompileDispatcher; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -21863,3 +21863,34 @@ TEST(EstimatedContextSize) { | |||
| 21863 | 21863 | LocalContext env; | |
| 21864 | 21864 | CHECK(50000 < env->EstimatedSize()); | |
| 21865 | 21865 | } | |
| 21866 | + | ||
| 21867 | + | ||
| 21868 | + static int nb_uncaught_exception_callback_calls = 0; | ||
| 21869 | + | ||
| 21870 | + | ||
| 21871 | + bool NoAbortOnUncaughtException(v8::Isolate* isolate) { | ||
| 21872 | + ++nb_uncaught_exception_callback_calls; | ||
| 21873 | + return false; | ||
| 21874 | + } | ||
| 21875 | + | ||
| 21876 | + | ||
| 21877 | + TEST(AbortOnUncaughtExceptionNoAbort) { | ||
| 21878 | + v8::Isolate* isolate = CcTest::isolate(); | ||
| 21879 | + v8::HandleScope handle_scope(isolate); | ||
| 21880 | + v8::Handle<v8::ObjectTemplate> global_template = | ||
| 21881 | + v8::ObjectTemplate::New(isolate); | ||
| 21882 | + LocalContext env(NULL, global_template); | ||
| 21883 | + | ||
| 21884 | + i::FLAG_abort_on_uncaught_exception = true; | ||
| 21885 | + isolate->SetAbortOnUncaughtExceptionCallback(NoAbortOnUncaughtException); | ||
| 21886 | + | ||
| 21887 | + CompileRun("function boom() { throw new Error(\"boom\") }"); | ||
| 21888 | + | ||
| 21889 | + v8::Local<v8::Object> global_object = env->Global(); | ||
| 21890 | + v8::Local<v8::Function> foo = | ||
| 21891 | + v8::Local<v8::Function>::Cast(global_object->Get(v8_str("boom"))); | ||
| 21892 | + | ||
| 21893 | + foo->Call(global_object, 0, NULL); | ||
| 21894 | + | ||
| 21895 | + CHECK_EQ(1, nb_uncaught_exception_callback_calls); | ||
| 21896 | + } | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments