Changeset 269806 in webkit


Ignore:
Timestamp:
Nov 13, 2020 4:20:47 PM (3 years ago)
Author:
BJ Burg
Message:

REGRESSION(r269701): inspector/console/webcore-logging.html is crashing
https://bugs.webkit.org/show_bug.cgi?id=218840
<rdar://problem/71310952>

Reviewed by Devin Rousso.

This test is triggering a bizarre backtrace that fails the assertion ASSERT(m_frontendLoaded)
in the frontend dispatcher. The sequence of events present in the stack trace is as follows:

  1. Test.html finishes loading.
  2. DOMContentLoaded event listener eventually calls InspectorFrontendHost::loaded().
  3. InspectorFrontendClient::frontendLoaded() calls -[NSWindow showWindow:] on the inspector window, which makes the inspected webpage window unfocus and resign first responder.
  4. Unfocusing causes an activity state change and style recalc. Script is unsafe to execute under this.
  5. Synchronously under the style recalc, inspector instrumentation is triggered when layers change.
  6. The backend sends a protocol event, which is synchronously dispatched to the frontend.
  7. Due to script evaluation being unsafe in (4), the frontend dispatcher tries to suspend. This hits the assertion because the frontend dispatcher hasn't been notified that the frontend finished loading as part of (3).

This only affects WebKitLegacy clients, where events 1-7 happen synchronously from top to bottom
due to the single process architecture. In the multiprocess case, frontendLoaded is an async
IPC message and frontend evaluations are not affected by the state of the inspected page.

  • inspector/InspectorFrontendAPIDispatcher.cpp:

(WebCore::InspectorFrontendAPIDispatcher::frontendLoaded): Dispatch messages iff not suspended.

(WebCore::InspectorFrontendAPIDispatcher::suspend): Remove the assertion that is incorrect.
Allow clients of this class to call suspend() before frontendLoaded().

(WebCore::InspectorFrontendAPIDispatcher::unsuspend): Using a similar argument as above, it
is possible that WebKitLegacy may unsuspend the dispatcher before the frontend has fully loaded.

Location:
trunk/Source/WebCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r269805 r269806  
     12020-11-13  Brian Burg  <bburg@apple.com>
     2
     3        REGRESSION(r269701): inspector/console/webcore-logging.html is crashing
     4        https://bugs.webkit.org/show_bug.cgi?id=218840
     5        <rdar://problem/71310952>
     6
     7        Reviewed by Devin Rousso.
     8
     9        This test is triggering a bizarre backtrace that fails the assertion ASSERT(m_frontendLoaded)
     10        in the frontend dispatcher. The sequence of events present in the stack trace is as follows:
     11
     12        1. Test.html finishes loading.
     13        2. DOMContentLoaded event listener eventually calls InspectorFrontendHost::loaded().
     14        3. InspectorFrontendClient::frontendLoaded() calls -[NSWindow showWindow:] on the inspector window,
     15           which makes the inspected webpage window unfocus and resign first responder.
     16        4. Unfocusing causes an activity state change and style recalc. Script is unsafe to execute under this.
     17        5. Synchronously under the style recalc, inspector instrumentation is triggered when layers change.
     18        6. The backend sends a protocol event, which is synchronously dispatched to the frontend.
     19        7. Due to script evaluation being unsafe in (4), the frontend dispatcher tries to suspend.
     20           This hits the assertion because the frontend dispatcher hasn't been notified that the frontend
     21           finished loading as part of (3).
     22
     23        This only affects WebKitLegacy clients, where events 1-7 happen synchronously from top to bottom
     24        due to the single process architecture. In the multiprocess case, frontendLoaded is an async
     25        IPC message and frontend evaluations are not affected by the state of the inspected page.
     26
     27        * inspector/InspectorFrontendAPIDispatcher.cpp:
     28        (WebCore::InspectorFrontendAPIDispatcher::frontendLoaded): Dispatch messages iff not suspended.
     29
     30        (WebCore::InspectorFrontendAPIDispatcher::suspend): Remove the assertion that is incorrect.
     31        Allow clients of this class to call suspend() before frontendLoaded().
     32
     33        (WebCore::InspectorFrontendAPIDispatcher::unsuspend): Using a similar argument as above, it
     34        is possible that WebKitLegacy may unsuspend the dispatcher before the frontend has fully loaded.
     35
    1362020-11-13  Sam Weinig  <weinig@apple.com>
    237
  • trunk/Source/WebCore/inspector/InspectorFrontendAPIDispatcher.cpp

    r269294 r269806  
    6666    m_frontendLoaded = true;
    6767
    68     evaluateQueuedExpressions();
     68    // In some convoluted WebKitLegacy-only scenarios, the backend may try to dispatch events to the frontend
     69    // underneath InspectorFrontendHost::loaded() when it is unsafe to execute script, causing suspend() to
     70    // be called before the frontend has fully loaded. See <https://bugs.webkit.org/show_bug.cgi?id=218840>.
     71    if (!m_suspended)
     72        evaluateQueuedExpressions();
    6973}
    7074
    7175void InspectorFrontendAPIDispatcher::suspend(UnsuspendSoon unsuspendSoon)
    7276{
    73     ASSERT(m_frontendLoaded);
    74 
    7577    if (m_suspended)
    7678        return;
     
    9698    m_suspended = false;
    9799
    98     evaluateQueuedExpressions();
     100    if (m_frontendLoaded)
     101        evaluateQueuedExpressions();
    99102}
    100103
Note: See TracChangeset for help on using the changeset viewer.