I filed a bug for the slightly counter-intuitive behavior I mentioned: https://bugs.chromium.org/p/v8/issues/detail?id=8455
Cheers, Yang On Wed, Nov 14, 2018 at 9:01 AM Yang Guo <yang...@chromium.org> wrote: > When you terminate execution in V8, we abort execution until the > bottom-most call into V8. If you have re-entries into V8, V8 always returns > empty results until the bottom-most call into V8. On the Blink side on the > stack of the re-entries, you can try to call into V8 before returning, but > that will simply return empty results. v8::TryCatch scopes along the way > will return true for v8::TryCatch::HasCaught and > v8::TryCatch::HasTerminated. Isolate::IsExecutionTerminating returns true. > > As soon as we reach the bottom-most call, we return with an empty value as > well. The v8::TryCatch scope around that will return true for > v8::TryCatch::HasCaught and v8::TryCatch::HasTerminated, but > Isolate::IsExecutionTerminating will return false (even if you are still > inside this outer-most v8::TryCatch scope), because you can safely call > into V8 again, from here on. I actually find this a bit counter-intuitive, > and it might be better to have Isolate::IsExecutionTerminating return true, > until we leave the outer-most v8::TryCatch. Though implementing that seems > a bit annoying. > > So what you are observing is that you have a non-reentry call to execute > the worker. That terminates, and you then have another non-reentry call. > That is working as intended though. Once you have left V8 through > termination across all re-entries, the isolate is good to be re-used again. > I think the correct way to fix your issue is to, at non-reentry calls, *always > check for v8::TryCatch::HasTerminated, and use that to guide the following > control flow*. > > To answer your questions: > >> 1. What happens if the isolate is forcibly terminated (from another >> thread) while running a script? Will an exception be thrown? Is a >> v8::TryCatch catches the exception? > > Internally we throw a special exception that cannot be caught by > javascript. This exception causes execution to abort until we arrive at the > first (non-reentry) call into V8. > > 2. What happens if we try to run a script when the isolate has already >> been terminated? > > If you completely exited V8 back to the first non-reentry call, you can > safely use the isolate again. > > 3. What happens if v8 calls blink code, the isolate is forcibly terminated and >> then the control is back to v8? > > The termination exception is propagated back to V8, causes the current > execution to abort, so that we return an empty value to blink as soon as > possible. If this blink frame is called from V8, then calling into V8 will > only result in empty values. > > Cheers, > > Yang > > > > On Sat, Nov 10, 2018 at 12:15 AM Adam Klein <ad...@chromium.org> wrote: > >> On Thu, Nov 8, 2018 at 8:21 PM Yutaka Hirano <yhir...@chromium.org> >> wrote: >> >>> > As to the problem itself, I have a clarifying questions: doesn't Blink >>> already have some choke point to determine whether it's "ok to call script >>> now"? If so that'd be a more natural place to add this handling than >>> TryCatch. >>> >>> No, there isn't such a point. To make matters worse, some call-sites >>> don't check errors because they don't care. >>> >>> Sorry for the ignorance but I would like to know V8's policy on >>> termination. >>> >>> 1. What happens if the isolate is forcibly terminated (from another >>> thread) while running a script? Will an exception be thrown? Is a >>> v8::TryCatch catches the exception? >>> 2. What happens if we try to run a script when the isolate has already >>> been terminated? >>> 3. What happens if v8 calls blink code, the isolate is forcibly >>> terminated and then the control is back to v8? >>> >>> >> I'm not intimately familiar with the details here. Yang or Toon, perhaps >> you have more insight? >> >> >>> >>> >>> On Fri, Nov 9, 2018 at 5:30 AM Adam Klein <ad...@chromium.org> wrote: >>> >>>> Adding a couple more V8 folks who may have thoughts. >>>> >>>> On Thu, Nov 8, 2018 at 1:59 AM Kentaro Hara <hara...@chromium.org> >>>> wrote: >>>> >>>>> On Thu, Nov 8, 2018 at 1:10 AM Yuki Shiino <yukishi...@chromium.org> >>>>> wrote: >>>>> >>>>>> +adamk, cbruni to get more attention from V8 team. This needs V8 >>>>>> team's support. >>>>>> >>>>>> Actually, I intended haraken's (a3) at my proposal (a), but I'm >>>>>> afraid that changing an existing API HasCaught() would break backward >>>>>> compatibility. So, I'm also proposing to add a new V8 API like >>>>>> v8::TryCatch::HasPendingException or v8::TryCatch::HasCaughtOrTerminated >>>>>> or >>>>>> whatever we call it. >>>>>> >>>>>> By the way, the example code is just an example. Usually we don't >>>>>> have two TryCatch blocks next to each other, and Blink is rethrowing the >>>>>> exception in most cases. I just forgot to write rethrow in the example. >>>>>> That's not a point. Let me revise the example. >>>>>> >>>>>> Main thread: >>>>>> v8::Isolate* worker_isolate = ...; >>>>>> worker_isolate->TerminateExecution(); // Terminates the worker >>>>>> isolate. >>>>>> >>>>>> Worker thread (worker isolate): >>>>>> Foo(); // The v8::Isolate terminates during execution of Foo. >>>>>> Bar(); >>>>>> >>>>>> where Foo and Bar are the followings. >>>>>> >>>>>> void Foo() { >>>>>> v8::TryCatch try_catch1(isolate); >>>>>> // Call V8 APIs. The v8::Isolate gets terminated at this point. >>>>>> if (try_catch1.HasCaught()) { // => true due to the >>>>>> termination exception. >>>>>> // Rethrow or report the error to global error handlers. >>>>>> return; >>>>>> } >>>>>> } >>>>>> >>>>>> void Bar() { >>>>>> v8::TryCatch try_catch2(isolate); >>>>>> // Call V8 APIs. V8 APIs fail because the isolate is >>>>>> terminating. >>>>>> if (try_catch2.HasCaught()) { // => false because no new >>>>>> exception is thrown inside |try_catch2| scope. >>>>>> // Rethrow or report the error to global error handlers. >>>>>> return; >>>>>> } >>>>>> // Blink reaches here. :( >>>>>> } >>>>>> >>>>> >>>>> Hmm, I'm a bit confused. >>>>> >>>>> If Foo() rethrows the exception, why does the worker thread continue >>>>> execution and call Bar()? That will cause a problem even when the worker >>>>> is >>>>> not terminated (because the worker continues execution ignoring the thrown >>>>> exception)...? >>>>> >>>>> Also I might want to understand how widely the problem is happening. >>>>> First of all, it is not realistic to handle worker's sudden termination in >>>>> 100% cases (unless we add checks to all V8 API calls in the Blink code >>>>> base). So the best thing we can do is to insert the termination check to >>>>> places that may call scripts (e.g., V8ScriptRunner, EventListener, Promise >>>>> resolve / reject etc) and reduce the crash rate. We could introduce >>>>> HasCaughtOrTerminated() if it helps to reduce the crash rate, but I want >>>>> to >>>>> make sure that assumption is correct. My intuition is that it will be more >>>>> useful to identify places that may call scripts often and insert the >>>>> termination checks if missing. >>>>> >>>> >>>> I'd similarly like to understand how much this happens in practice. >>>> >>>> >>>>> A proposed solution looks like the following. >>>>>> >>>>>> v8::TryCatch try_catch(isolate); >>>>>> // ... >>>>>> if (try_catch.*HasCaughtOrTerminated*()) { >>>>>> v8::Local<v8::Exception> exception = try_catch. >>>>>> *CaughtExceptionOrTerminationException*(); >>>>>> // Do a job with |exception|. >>>>>> return; >>>>>> } >>>>>> >>>>>> where HasCaughtOrTerminated returns true when the isolate is >>>>>> terminating even if no exception is thrown inside the TryCatch scope, and >>>>>> CaughtExceptionOrTerminationException returns a thrown exception if an >>>>>> exception is thrown inside the TryCatch scope or the termination >>>>>> exception >>>>>> if the isolate is terminating. >>>>>> >>>>> >>>> As to the problem itself, I have a clarifying questions: doesn't Blink >>>> already have some choke point to determine whether it's "ok to call script >>>> now"? If so that'd be a more natural place to add this handling than >>>> TryCatch. >>>> >>>> - Adam >>>> >>>> >>>>> Cheers, >>>>>> Yuki Shiino >>>>>> >>>>>> >>>>>> 2018年11月8日(木) 17:38 Kentaro Hara <hara...@chromium.org>: >>>>>> >>>>>>> Thanks, I got it :) >>>>>>> >>>>>>> My proposal would be: >>>>>>> >>>>>>> (a3) Make HasCaught() return true when the isolate is terminated. >>>>>>> >>>>>>> I'm not sure if (a) or (a2) is a good idea because the fact that we >>>>>>> didn't call ReThrow() means that we (intentionally) suppressed the >>>>>>> exception. Thoughts? >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> On Wed, Nov 7, 2018 at 9:51 PM Yuki Shiino <yukishi...@chromium.org> >>>>>>> wrote: >>>>>>> >>>>>>>> Are you assuming that the worker is terminated while it's calling >>>>>>>>> DoSomethingElseWithV8()? If yes, why does HasCaught() not return >>>>>>>>> true? If >>>>>>>>> no, what's a problem of continuing execution? >>>>>>>> >>>>>>>> >>>>>>>> No, the worker is terminated while DoSomethingWithV8 (without >>>>>>>> "Else"), and Blink continues running more V8 code at >>>>>>>> DoSomethingElseWithV8. Two pieces of code run consecutively. >>>>>>>> >>>>>>>> Worker thread (worker isolate): >>>>>>>> { >>>>>>>> v8::TryCatch try_catch(isolate); >>>>>>>> DoSomethingWithV8(); // The Isolate terminates here. >>>>>>>> if (try_catch.HasCaught()) { // => true due to termination >>>>>>>> // Handle error or termination. >>>>>>>> return; >>>>>>>> } >>>>>>>> } >>>>>>>> { >>>>>>>> v8::TryCatch try_catch(isolate); >>>>>>>> DoSomethingElseWithV8(); // V8 APIs fail because the Isolate >>>>>>>> is terminating. >>>>>>>> if (try_catch.HasCaught()) { // => false because no new >>>>>>>> exception is thrown inside the v8::TryCatch. >>>>>>>> return; // Blink doesn't reach here. >>>>>>>> } >>>>>>>> // Blink reach here instead. :( >>>>>>>> } >>>>>>>> >>>>>>>> IIUC, the second try_catch.HasCaught() doesn't return true because >>>>>>>> there is no new exception thrown inside the v8::TryCatch scope, >>>>>>>> although V8 >>>>>>>> APIs fail inside DoSomethingElseWithV8 due to a pending termination >>>>>>>> exception. >>>>>>>> >>>>>>>> Cheers, >>>>>>>> Yuki Shiino >>>>>>>> >>>>>>>> >>>>>>>> 2018年11月8日(木) 3:18 Kentaro Hara <hara...@chromium.org>: >>>>>>>> >>>>>>>>> Sorry, I'm not sure if I understand your example... >>>>>>>>> >>>>>>>>> >>>>>>>>> On Wed, Nov 7, 2018 at 2:21 AM Yutaka Hirano <yhir...@chromium.org> >>>>>>>>> wrote: >>>>>>>>> >>>>>>>>>> +ricea@ >>>>>>>>>> >>>>>>>>>> On Wed, Nov 7, 2018 at 6:44 PM Yuki Shiino < >>>>>>>>>> yukishi...@chromium.org> wrote: >>>>>>>>>> >>>>>>>>>>> Hi V8-team and platform-architecture-dev, >>>>>>>>>>> >>>>>>>>>>> TL;DR: We'd like to extend v8::TryCatch APIs a little. >>>>>>>>>>> >>>>>>>>>>> We're having an issue how to handle worker termination, i.e. >>>>>>>>>>> v8::Isolate termination. Roughly speaking, the situation is like >>>>>>>>>>> below. >>>>>>>>>>> >>>>>>>>>>> Main thread: >>>>>>>>>>> v8::Isolate* worker_isolate = ...; >>>>>>>>>>> worker_isolate->TerminateExecution(); // Terminates the >>>>>>>>>>> worker isolate. >>>>>>>>>>> >>>>>>>>>>> Worker thread (worker isolate): >>>>>>>>>>> v8::TryCatch try_catch(isolate); >>>>>>>>>>> DoSomethingWithV8(); // The Isolate terminates here. >>>>>>>>>>> if (try_catch.HasCaught()) { // => true due to termination >>>>>>>>>>> // Handle error or termination. >>>>>>>>>>> return; >>>>>>>>>>> } >>>>>>>>>>> >>>>>>>>>>> No problem so far. Worker thread MUST NOT run any V8 code no >>>>>>>>>>> longer because the Isolate is terminating. However, Blink is not >>>>>>>>>>> perfect, >>>>>>>>>>> and it's pretty tough for Blink to stop everything with 100% >>>>>>>>>>> correctness. >>>>>>>>>>> Occasionally (or rarely) Blink continues running more V8 code like >>>>>>>>>>> below. >>>>>>>>>>> >>>>>>>>>>> Worker thread (worker isolate): >>>>>>>>>>> v8::TryCatch try_catch(isolate); >>>>>>>>>>> DoSomethingElseWithV8(); >>>>>>>>>>> if (try_catch.HasCaught()) { // => false because no new >>>>>>>>>>> exception is thrown inside the v8::TryCatch. >>>>>>>>>>> return; // Blink doesn't reach here. >>>>>>>>>>> } >>>>>>>>>>> // Blink reach here instead. :( >>>>>>>>>>> >>>>>>>>>>> If v8::TryCatch::HasCaught() returned true, Blink would be able >>>>>>>>>>> to handle it as error and Blink would work much better than now >>>>>>>>>>> (Blink is >>>>>>>>>>> now crashing). >>>>>>>>>>> >>>>>>>>>> >>>>>>>>> Are you assuming that the worker is terminated while it's calling >>>>>>>>> DoSomethingElseWithV8()? If yes, why does HasCaught() not return >>>>>>>>> true? If >>>>>>>>> no, what's a problem of continuing execution? >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>>>> So, proposals here are something like below (not yet so >>>>>>>>>>> concrete). >>>>>>>>>>> >>>>>>>>>>> a) Make v8::TryCatch::HasCaught() return true if there already >>>>>>>>>>> exists a pending exception. (Maybe this is no good.) >>>>>>>>>>> b) Make a new API like v8::TryCatch::HasPendingException() and >>>>>>>>>>> make it return true. Blink rewrites all HasCaught() to the new one. >>>>>>>>>>> >>>>>>>>>>> Similarly, >>>>>>>>>>> >>>>>>>>>>> a2) Make v8::TryCatch::Exception() return a pending exception if >>>>>>>>>>> there already exists. >>>>>>>>>>> b2) Make a new API like v8::TryCatch::PendingException() and >>>>>>>>>>> make it return a thrown exception or pending exception in the >>>>>>>>>>> isolate if >>>>>>>>>>> any. Blink rewrites all Exception() to the new one. >>>>>>>>>>> >>>>>>>>>>> What do you think of the issue and proposals? >>>>>>>>>>> >>>>>>>>>>> Cheers, >>>>>>>>>>> Yuki Shiino >>>>>>>>>>> >>>>>>>>>>> -- >>>>>>>>>> You received this message because you are subscribed to the >>>>>>>>>> Google Groups "platform-architecture-dev" group. >>>>>>>>>> To unsubscribe from this group and stop receiving emails from it, >>>>>>>>>> send an email to >>>>>>>>>> platform-architecture-dev+unsubscr...@chromium.org. >>>>>>>>>> To post to this group, send email to >>>>>>>>>> platform-architecture-...@chromium.org. >>>>>>>>>> To view this discussion on the web visit >>>>>>>>>> https://groups.google.com/a/chromium.org/d/msgid/platform-architecture-dev/CABihn6ER8q9QABC3ROCSkm6V4w%2BDb0xEqRvjgzwBpMG9DmiG1Q%40mail.gmail.com >>>>>>>>>> <https://groups.google.com/a/chromium.org/d/msgid/platform-architecture-dev/CABihn6ER8q9QABC3ROCSkm6V4w%2BDb0xEqRvjgzwBpMG9DmiG1Q%40mail.gmail.com?utm_medium=email&utm_source=footer> >>>>>>>>>> . >>>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> -- >>>>>>>>> Kentaro Hara, Tokyo, Japan >>>>>>>>> >>>>>>>> >>>>>>> >>>>>>> -- >>>>>>> Kentaro Hara, Tokyo, Japan >>>>>>> >>>>>> >>>>> >>>>> -- >>>>> Kentaro Hara, Tokyo, Japan >>>>> >>>>> -- >>>>> You received this message because you are subscribed to the Google >>>>> Groups "platform-architecture-dev" group. >>>>> To unsubscribe from this group and stop receiving emails from it, send >>>>> an email to platform-architecture-dev+unsubscr...@chromium.org. >>>>> To post to this group, send email to >>>>> platform-architecture-...@chromium.org. >>>>> To view this discussion on the web visit >>>>> https://groups.google.com/a/chromium.org/d/msgid/platform-architecture-dev/CABg10jx51JXHEt0H9z%3DzT%3D0GnhDf79QjhGtVxRc%3Dy-RXjHXUyw%40mail.gmail.com >>>>> <https://groups.google.com/a/chromium.org/d/msgid/platform-architecture-dev/CABg10jx51JXHEt0H9z%3DzT%3D0GnhDf79QjhGtVxRc%3Dy-RXjHXUyw%40mail.gmail.com?utm_medium=email&utm_source=footer> >>>>> . >>>>> >>>> -- >>> You received this message because you are subscribed to the Google >>> Groups "platform-architecture-dev" group. >>> To unsubscribe from this group and stop receiving emails from it, send >>> an email to platform-architecture-dev+unsubscr...@chromium.org. >>> To post to this group, send email to >>> platform-architecture-...@chromium.org. >>> To view this discussion on the web visit >>> https://groups.google.com/a/chromium.org/d/msgid/platform-architecture-dev/CABihn6GKuTUs5UfpbQ6RwXq%3DWw0dDUJkq2JLzadnesfjLG%3DStg%40mail.gmail.com >>> <https://groups.google.com/a/chromium.org/d/msgid/platform-architecture-dev/CABihn6GKuTUs5UfpbQ6RwXq%3DWw0dDUJkq2JLzadnesfjLG%3DStg%40mail.gmail.com?utm_medium=email&utm_source=footer> >>> . >>> >> -- >> You received this message because you are subscribed to the Google Groups >> "platform-architecture-dev" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to platform-architecture-dev+unsubscr...@chromium.org. >> To post to this group, send email to >> platform-architecture-...@chromium.org. >> To view this discussion on the web visit >> https://groups.google.com/a/chromium.org/d/msgid/platform-architecture-dev/CAEvLGcKKKdZ4-Svz7NmXdzSaL9ryQz4cPEqhTfmWEURzwTdMqQ%40mail.gmail.com >> <https://groups.google.com/a/chromium.org/d/msgid/platform-architecture-dev/CAEvLGcKKKdZ4-Svz7NmXdzSaL9ryQz4cPEqhTfmWEURzwTdMqQ%40mail.gmail.com?utm_medium=email&utm_source=footer> >> . >> > -- -- v8-users mailing list v8-users@googlegroups.com http://groups.google.com/group/v8-users --- You received this message because you are subscribed to the Google Groups "v8-users" group. To unsubscribe from this group and stop receiving emails from it, send an email to v8-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.