⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 271876 in webkit


Ignore:
Timestamp:
Jan 25, 2021, 9:09:16 PM (6 years ago)
Author:
Simon Fraser
Message:

Crash when remote inspecting in debug builds
​https://bugs.webkit.org/show_bug.cgi?id=220956
<rdar://73379637>

Reviewed by Devin Rousso.

Convert RemoteConnectionToTarget from using BlockPtr<> to Function<> because BlockPtr<>
was triggering crashes which seem to be related to mixing ARC and non-ARC code.

  • inspector/remote/RemoteConnectionToTarget.h:
  • inspector/remote/cocoa/RemoteConnectionToTargetCocoa.mm:

(Inspector::RemoteTargetHandleRunSourceGlobal):
(Inspector::RemoteTargetQueueTaskOnGlobalQueue):
(Inspector::RemoteTargetHandleRunSourceWithInfo):
(Inspector::RemoteConnectionToTarget::dispatchAsyncOnTarget):
(Inspector::RemoteConnectionToTarget::setup):
(Inspector::RemoteConnectionToTarget::close):
(Inspector::RemoteConnectionToTarget::sendMessageToTarget):
(Inspector::RemoteConnectionToTarget::queueTaskOnPrivateRunLoop):
(Inspector::RemoteConnectionToTarget::takeQueue):

Location:
trunk/Source/JavaScriptCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r271873 r271876  
     12021-01-25  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Crash when remote inspecting in debug builds
     4        https://bugs.webkit.org/show_bug.cgi?id=220956
     5        <rdar://73379637>
     6
     7        Reviewed by Devin Rousso.
     8
     9        Convert RemoteConnectionToTarget from using BlockPtr<> to Function<> because BlockPtr<>
     10        was triggering crashes which seem to be related to mixing ARC and non-ARC code.
     11
     12        * inspector/remote/RemoteConnectionToTarget.h:
     13        * inspector/remote/cocoa/RemoteConnectionToTargetCocoa.mm:
     14        (Inspector::RemoteTargetHandleRunSourceGlobal):
     15        (Inspector::RemoteTargetQueueTaskOnGlobalQueue):
     16        (Inspector::RemoteTargetHandleRunSourceWithInfo):
     17        (Inspector::RemoteConnectionToTarget::dispatchAsyncOnTarget):
     18        (Inspector::RemoteConnectionToTarget::setup):
     19        (Inspector::RemoteConnectionToTarget::close):
     20        (Inspector::RemoteConnectionToTarget::sendMessageToTarget):
     21        (Inspector::RemoteConnectionToTarget::queueTaskOnPrivateRunLoop):
     22        (Inspector::RemoteConnectionToTarget::takeQueue):
     23
    1242021-01-25  Alexey Shvayka  <shvaikalesh@gmail.com>
    225
  • trunk/Source/JavaScriptCore/inspector/remote/RemoteConnectionToTarget.h

    r261569 r271876  
    4545
    4646#if PLATFORM(COCOA)
    47 typedef Vector<BlockPtr<void ()>> RemoteTargetQueue;
     47typedef Vector<Function<void ()>> RemoteTargetQueue;
    4848#endif
    4949
    … …  
    7474    Lock& queueMutex() { return m_queueMutex; }
    7575    const RemoteTargetQueue& queue() const { return m_queue; }
    76     void clearQueue() { m_queue.clear(); }
     76    RemoteTargetQueue takeQueue();
    7777#endif
    7878
    … …  
    8383private:
    8484#if PLATFORM(COCOA)
    85     void dispatchAsyncOnTarget(void (^block)());
     85    void dispatchAsyncOnTarget(Function<void ()>&&);
    8686
    8787    void setupRunLoop();
    8888    void teardownRunLoop();
    89     void queueTaskOnPrivateRunLoop(void (^block)());
     89    void queueTaskOnPrivateRunLoop(Function<void ()>&&);
    9090#endif
    9191
  • trunk/Source/JavaScriptCore/inspector/remote/cocoa/RemoteConnectionToTargetCocoa.mm

    r266077 r271876  
    5656    {
    5757        LockHolder lock(rwiQueueMutex);
    58         queueCopy = *rwiQueue;
    59         rwiQueue->clear();
    60     }
    61 
    62     for (const auto& block : queueCopy)
    63         block();
    64 }
    65 
    66 static void RemoteTargetQueueTaskOnGlobalQueue(void (^task)())
     58        std::swap(queueCopy, *rwiQueue);
     59    }
     60
     61    for (const auto& function : queueCopy)
     62        function();
     63}
     64
     65static void RemoteTargetQueueTaskOnGlobalQueue(Function<void ()>&& function)
    6766{
    6867    ASSERT(rwiRunLoopSource);
    … …  
    7170    {
    7271        LockHolder lock(rwiQueueMutex);
    73         rwiQueue->append(task);
     72        rwiQueue->append(WTFMove(function));
    7473    }
    7574
    … …  
    102101    {
    103102        LockHolder lock(connectionToTarget->queueMutex());
    104         queueCopy = connectionToTarget->queue();
    105         connectionToTarget->clearQueue();
    106     }
    107 
    108     for (const auto& block : queueCopy)
    109         block();
     103        queueCopy = connectionToTarget->takeQueue();
     104    }
     105
     106    for (const auto& function : queueCopy)
     107        function();
    110108}
    111109
    … …  
    139137}
    140138
    141 void RemoteConnectionToTarget::dispatchAsyncOnTarget(void (^block)())
     139void RemoteConnectionToTarget::dispatchAsyncOnTarget(Function<void ()>&& callback)
    142140{
    143141    if (m_runLoop) {
    144         queueTaskOnPrivateRunLoop(block);
     142        queueTaskOnPrivateRunLoop(WTFMove(callback));
    145143        return;
    146144    }
    … …  
    148146#if USE(WEB_THREAD)
    149147    if (WebCoreWebThreadIsEnabled && WebCoreWebThreadIsEnabled()) {
    150         WebCoreWebThreadRun(block);
     148        WebCoreWebThreadRun(^ { callback(); });
    151149        return;
    152150    }
    153151#endif
    154152
    155     RemoteTargetQueueTaskOnGlobalQueue(block);
     153    RemoteTargetQueueTaskOnGlobalQueue(WTFMove(callback));
    156154}
    157155
    … …  
    164162
    165163    auto targetIdentifier = this->targetIdentifier().valueOr(0);
     164
     165    dispatchAsyncOnTarget([&, strongThis = makeRef(*this)]() {
     166        LockHolder lock(m_targetMutex);
     167
     168        if (!m_target || !m_target->remoteControlAllowed()) {
     169            RemoteInspector::singleton().setupFailed(targetIdentifier);
     170            m_target = nullptr;
     171        } else if (is<RemoteInspectionTarget>(m_target)) {
     172            auto castedTarget = downcast<RemoteInspectionTarget>(m_target);
     173            castedTarget->connect(*this, isAutomaticInspection, automaticallyPause);
     174            m_connected = true;
     175
     176            RemoteInspector::singleton().updateTargetListing(targetIdentifier);
     177        } else if (is<RemoteAutomationTarget>(m_target)) {
     178            auto castedTarget = downcast<RemoteAutomationTarget>(m_target);
     179            castedTarget->connect(*this);
     180            m_connected = true;
     181
     182            RemoteInspector::singleton().updateTargetListing(targetIdentifier);
     183        }
     184    });
     185
     186    return true;
     187}
     188
     189void RemoteConnectionToTarget::targetClosed()
     190{
     191    LockHolder lock(m_targetMutex);
     192
     193    m_target = nullptr;
     194}
     195
     196void RemoteConnectionToTarget::close()
     197{
     198    auto targetIdentifier = m_target ? m_target->targetIdentifier() : 0;
    166199   
    167     ref();
    168     dispatchAsyncOnTarget(^{
     200    dispatchAsyncOnTarget([&, strongThis = makeRef(*this)]() {
     201        LockHolder lock(m_targetMutex);
     202        if (m_target) {
     203            if (m_connected)
     204                m_target->disconnect(*this);
     205
     206            m_target = nullptr;
     207            if (targetIdentifier)
     208                RemoteInspector::singleton().updateTargetListing(targetIdentifier);
     209        }
     210    });
     211}
     212
     213void RemoteConnectionToTarget::sendMessageToTarget(NSString *message)
     214{
     215    dispatchAsyncOnTarget([this, strongMessage = retainPtr(message), strongThis = makeRef(*this)]() {
     216        RemoteControllableTarget* target = nullptr;
    169217        {
    170218            LockHolder lock(m_targetMutex);
    171 
    172             if (!m_target || !m_target->remoteControlAllowed()) {
    173                 RemoteInspector::singleton().setupFailed(targetIdentifier);
    174                 m_target = nullptr;
    175             } else if (is<RemoteInspectionTarget>(m_target)) {
    176                 auto castedTarget = downcast<RemoteInspectionTarget>(m_target);
    177                 castedTarget->connect(*this, isAutomaticInspection, automaticallyPause);
    178                 m_connected = true;
    179 
    180                 RemoteInspector::singleton().updateTargetListing(targetIdentifier);
    181             } else if (is<RemoteAutomationTarget>(m_target)) {
    182                 auto castedTarget = downcast<RemoteAutomationTarget>(m_target);
    183                 castedTarget->connect(*this);
    184                 m_connected = true;
    185 
    186                 RemoteInspector::singleton().updateTargetListing(targetIdentifier);
    187             }
     219            if (!m_target)
     220                return;
     221            target = m_target;
    188222        }
    189         deref();
    190     });
    191 
    192     return true;
    193 }
    194 
    195 void RemoteConnectionToTarget::targetClosed()
    196 {
    197     LockHolder lock(m_targetMutex);
    198 
    199     m_target = nullptr;
    200 }
    201 
    202 void RemoteConnectionToTarget::close()
    203 {
    204     auto targetIdentifier = m_target ? m_target->targetIdentifier() : 0;
    205    
    206     ref();
    207     dispatchAsyncOnTarget(^{
    208         {
    209             LockHolder lock(m_targetMutex);
    210             if (m_target) {
    211                 if (m_connected)
    212                     m_target->disconnect(*this);
    213 
    214                 m_target = nullptr;
    215                
    216                 RemoteInspector::singleton().updateTargetListing(targetIdentifier);
    217             }
    218         }
    219         deref();
    220     });
    221 }
    222 
    223 void RemoteConnectionToTarget::sendMessageToTarget(NSString *message)
    224 {
    225     ref();
    226     dispatchAsyncOnTarget(^{
    227         {
    228             RemoteControllableTarget* target = nullptr;
    229             {
    230                 LockHolder lock(m_targetMutex);
    231                 if (!m_target)
    232                     return;
    233                 target = m_target;
    234             }
    235 
    236             target->dispatchMessageFromRemote(message);
    237         }
    238         deref();
     223
     224        target->dispatchMessageFromRemote(strongMessage.get());
    239225    });
    240226}
    … …  
    281267}
    282268
    283 void RemoteConnectionToTarget::queueTaskOnPrivateRunLoop(void (^block)())
     269void RemoteConnectionToTarget::queueTaskOnPrivateRunLoop(Function<void ()>&& function)
    284270{
    285271    ASSERT(m_runLoop);
    … …  
    287273    {
    288274        LockHolder lock(m_queueMutex);
    289         m_queue.append(block);
     275        m_queue.append(WTFMove(function));
    290276    }
    291277
    … …  
    294280}
    295281
     282RemoteTargetQueue RemoteConnectionToTarget::takeQueue()
     283{
     284    return std::exchange(m_queue, { });
     285}
     286
    296287} // namespace Inspector
    297288
Note: See TracChangeset for help on using the changeset viewer.