Changeset 244673 in webkit


Ignore:
Timestamp:
Apr 25, 2019 6:28:39 PM (5 years ago)
Author:
Chris Dumez
Message:

ASSERT(scriptExecutionContext()) in Performance::resourceTimingBufferFullTimerFired()
https://bugs.webkit.org/show_bug.cgi?id=197300
<rdar://problem/49965990>

Reviewed by Youenn Fablet.

We crash because the scriptExecutionContext has been destroyed by the time the m_resourceTimingBufferFullTimer
timer fires. However, r241598 already makes sure that we stop the timer when the script execution context
is destroyed. This makes me think that somebody restarts the timer *after* the script execution context has
been destroyed. The thing is that we only start the timer in Performance::addResourceTiming() and there are
only 2 call sites for this method. Both call sites get the Performance object from the Window object, which
they get from the Document object. As a result, I would believe that the Window's document is alive, even
though the Performance object's scriptExecutionContext is not. This could indicate that the Performance
object's scriptExecutionContext gets out of sync with its Window's document. I have found one place where
it could happen in theory (DOMWindow::didSecureTransitionTo()). I have not been able to write a test
confirming my theory though so this is a speculative fix. I have also added a few assertions to help us
track down the issue if my speculative fix turns out to be ineffective.

No new tests, we do not know how to reproduce.

  • page/DOMWindow.cpp:

(WebCore::DOMWindow::didSecureTransitionTo):
This is a speculative fix for the crash. When a DOMWindow transitions from one document to
another, reset its data members which store the DOMWindow's document to make sure that they
do not get out of sync.

(WebCore::DOMWindow::crypto const):
(WebCore::DOMWindow::navigator):
(WebCore::DOMWindow::performance const):
Add assertions to make sure that the member's scriptExecutionContext is in sync with
the window's.

  • page/Performance.cpp:

(WebCore::Performance::addResourceTiming):
Add assertion to make sure that the scriptExecutionContext() is non-null when calling this
as this may start the m_resourceTimingBufferFullTimer timer. If my speculative fix above
does not work, we should hit this and this should tell us which call site is causing this.

Location:
trunk/Source/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r244665 r244673  
     12019-04-25  Chris Dumez  <cdumez@apple.com>
     2
     3        ASSERT(scriptExecutionContext()) in Performance::resourceTimingBufferFullTimerFired()
     4        https://bugs.webkit.org/show_bug.cgi?id=197300
     5        <rdar://problem/49965990>
     6
     7        Reviewed by Youenn Fablet.
     8
     9        We crash because the scriptExecutionContext has been destroyed by the time the m_resourceTimingBufferFullTimer
     10        timer fires. However, r241598 already makes sure that we stop the timer when the script execution context
     11        is destroyed. This makes me think that somebody restarts the timer *after* the script execution context has
     12        been destroyed. The thing is that we only start the timer in Performance::addResourceTiming() and there are
     13        only 2 call sites for this method. Both call sites get the Performance object from the Window object, which
     14        they get from the Document object. As a result, I would believe that the Window's document is alive, even
     15        though the Performance object's scriptExecutionContext is not. This could indicate that the Performance
     16        object's scriptExecutionContext gets out of sync with its Window's document. I have found one place where
     17        it could happen in theory (DOMWindow::didSecureTransitionTo()). I have not been able to write a test
     18        confirming my theory though so this is a speculative fix. I have also added a few assertions to help us
     19        track down the issue if my speculative fix turns out to be ineffective.
     20
     21        No new tests, we do not know how to reproduce.
     22
     23        * page/DOMWindow.cpp:
     24        (WebCore::DOMWindow::didSecureTransitionTo):
     25        This is a speculative fix for the crash. When a DOMWindow transitions from one document to
     26        another, reset its data members which store the DOMWindow's document to make sure that they
     27        do not get out of sync.
     28
     29        (WebCore::DOMWindow::crypto const):
     30        (WebCore::DOMWindow::navigator):
     31        (WebCore::DOMWindow::performance const):
     32        Add assertions to make sure that the member's scriptExecutionContext is in sync with
     33        the window's.
     34
     35        * page/Performance.cpp:
     36        (WebCore::Performance::addResourceTiming):
     37        Add assertion to make sure that the scriptExecutionContext() is non-null when calling this
     38        as this may start the m_resourceTimingBufferFullTimer timer. If my speculative fix above
     39        does not work, we should hit this and this should tell us which call site is causing this.
     40
    1412019-04-25  Timothy Hatcher  <timothy@apple.com>
    242
  • trunk/Source/WebCore/page/DOMWindow.cpp

    r244382 r244673  
    416416{
    417417    observeContext(&document);
     418
     419    // The Window is being transferred from one document to another so we need to reset data
     420    // members that store the window's document (rather than the window itself).
     421    m_crypto = nullptr;
     422    m_navigator = nullptr;
     423    m_performance = nullptr;
    418424}
    419425
     
    649655    if (!m_crypto)
    650656        m_crypto = Crypto::create(document());
     657    ASSERT(m_crypto->scriptExecutionContext() == document());
    651658    return *m_crypto;
    652659}
     
    714721    if (!m_navigator)
    715722        m_navigator = Navigator::create(scriptExecutionContext(), *this);
     723    ASSERT(m_navigator->scriptExecutionContext() == document());
    716724
    717725    return *m_navigator;
     
    724732        m_performance = Performance::create(document(), timeOrigin);
    725733    }
     734    ASSERT(m_performance->scriptExecutionContext() == document());
    726735    return *m_performance;
    727736}
  • trunk/Source/WebCore/page/Performance.cpp

    r243887 r244673  
    182182void Performance::addResourceTiming(ResourceTiming&& resourceTiming)
    183183{
     184    ASSERT(scriptExecutionContext());
     185
    184186    auto entry = PerformanceResourceTiming::create(m_timeOrigin, WTFMove(resourceTiming));
    185187
Note: See TracChangeset for help on using the changeset viewer.