Bug 237621 - In isolated tree mode, do not call NSAccessibilityUnregisterUniqueIdForUIElement until the isolated object is detached.
Summary: In isolated tree mode, do not call NSAccessibilityUnregisterUniqueIdForUIElem...
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Accessibility (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Andres Gonzalez
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2022-03-08 15:12 PST by Andres Gonzalez
Modified: 2022-03-09 18:45 PST (History)
10 users (show)

See Also:


Attachments
Patch (3.33 KB, patch)
2022-03-08 15:27 PST, Andres Gonzalez
no flags Details | Formatted Diff | Diff
Patch (5.61 KB, patch)
2022-03-09 09:12 PST, Andres Gonzalez
no flags Details | Formatted Diff | Diff
Patch (5.51 KB, patch)
2022-03-09 09:22 PST, Andres Gonzalez
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Andres Gonzalez 2022-03-08 15:12:59 PST
In isolated tree mode, do not call NSAccessibilityUnregisterUniqueIdForUIElement until the isolated object is detached.
Comment 1 Radar WebKit Bug Importer 2022-03-08 15:13:08 PST
<rdar://problem/89992486>
Comment 2 Andres Gonzalez 2022-03-08 15:27:52 PST
Created attachment 454159 [details]
Patch
Comment 3 chris fleizach 2022-03-08 16:22:06 PST
Comment on attachment 454159 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=454159&action=review

> Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm:535
> +    if (!AXObjectCache::isIsolatedTreeEnabled())

I think we may want to verify that this wrapper DOES have an isolated object with it, otherwise its possible this object will only exist on the main thread and never get an isolated element
Comment 4 Andres Gonzalez 2022-03-08 16:35:48 PST
(In reply to chris fleizach from comment #3)
> Comment on attachment 454159 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=454159&action=review
> 
> > Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm:535
> > +    if (!AXObjectCache::isIsolatedTreeEnabled())
> 
> I think we may want to verify that this wrapper DOES have an isolated object
> with it, otherwise its possible this object will only exist on the main
> thread and never get an isolated element

The problem with accessing the wrapper's m_isolatedObject here is that this is on the main thread, and m_isolatedObject should only be accessed on the AX thread after creation.
Comment 5 chris fleizach 2022-03-08 16:38:58 PST
Comment on attachment 454159 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=454159&action=review

>>> Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm:535
>>> +    if (!AXObjectCache::isIsolatedTreeEnabled())
>> 
>> I think we may want to verify that this wrapper DOES have an isolated object with it, otherwise its possible this object will only exist on the main thread and never get an isolated element
> 
> The problem with accessing the wrapper's m_isolatedObject here is that this is on the main thread, and m_isolatedObject should only be accessed on the AX thread after creation.

can we check for its presence safely? just doing a read on the pointer value?
Comment 6 Andres Gonzalez 2022-03-08 16:53:38 PST
(In reply to chris fleizach from comment #5)
> Comment on attachment 454159 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=454159&action=review
> 
> >>> Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm:535
> >>> +    if (!AXObjectCache::isIsolatedTreeEnabled())
> >> 
> >> I think we may want to verify that this wrapper DOES have an isolated object with it, otherwise its possible this object will only exist on the main thread and never get an isolated element
> > 
> > The problem with accessing the wrapper's m_isolatedObject here is that this is on the main thread, and m_isolatedObject should only be accessed on the AX thread after creation.
> 
> can we check for its presence safely? just doing a read on the pointer value?

There is no guaranty that we can read that pointer on the main thread. The AX thread could be writing to it at that point, and thus you would read garbage. For instance, in the AXObjectCache we have:

#if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
    if (m_pageID) {
        if (auto tree = AXIsolatedTree::treeForPageID(*m_pageID))
            tree->removeNode(*object);
    }
#endif

    object->detach(AccessibilityDetachmentType::ElementDestroyed);

tree->removeNode will schedule the isolated object to be detached, so when the live object detach is called, the applyPendingChanges may be detaching the isolated object.

I think we would need to add a variable to be accessed on the main thread to signal whether the isolated object was attached or not.
Comment 7 Andres Gonzalez 2022-03-08 17:04:10 PST
(In reply to Andres Gonzalez from comment #6)
> (In reply to chris fleizach from comment #5)
> > Comment on attachment 454159 [details]
> > Patch
> > 
> > View in context:
> > https://bugs.webkit.org/attachment.cgi?id=454159&action=review
> > 
> > >>> Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm:535
> > >>> +    if (!AXObjectCache::isIsolatedTreeEnabled())
> > >> 
> > >> I think we may want to verify that this wrapper DOES have an isolated object with it, otherwise its possible this object will only exist on the main thread and never get an isolated element
> > > 
> > > The problem with accessing the wrapper's m_isolatedObject here is that this is on the main thread, and m_isolatedObject should only be accessed on the AX thread after creation.
> > 
> > can we check for its presence safely? just doing a read on the pointer value?
> 
> There is no guaranty that we can read that pointer on the main thread. The
> AX thread could be writing to it at that point, and thus you would read
> garbage. For instance, in the AXObjectCache we have:
> 
> #if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
>     if (m_pageID) {
>         if (auto tree = AXIsolatedTree::treeForPageID(*m_pageID))
>             tree->removeNode(*object);
>     }
> #endif
> 
>     object->detach(AccessibilityDetachmentType::ElementDestroyed);
> 
> tree->removeNode will schedule the isolated object to be detached, so when
> the live object detach is called, the applyPendingChanges may be detaching
> the isolated object.
> 
> I think we would need to add a variable to be accessed on the main thread to
> signal whether the isolated object was attached or not.

Maybe if I revert the order in the AXObjectCache snippet above, then it will be fine to read that pointer on the main thread.
Comment 8 chris fleizach 2022-03-08 18:07:16 PST
Comment on attachment 454159 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=454159&action=review

>>>>>> Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm:535
>>>>>> +    if (!AXObjectCache::isIsolatedTreeEnabled())
>>>>> 
>>>>> I think we may want to verify that this wrapper DOES have an isolated object with it, otherwise its possible this object will only exist on the main thread and never get an isolated element
>>>> 
>>>> The problem with accessing the wrapper's m_isolatedObject here is that this is on the main thread, and m_isolatedObject should only be accessed on the AX thread after creation.
>>> 
>>> can we check for its presence safely? just doing a read on the pointer value?
>> 
>> There is no guaranty that we can read that pointer on the main thread. The AX thread could be writing to it at that point, and thus you would read garbage. For instance, in the AXObjectCache we have:
>> 
>> #if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
>>     if (m_pageID) {
>>         if (auto tree = AXIsolatedTree::treeForPageID(*m_pageID))
>>             tree->removeNode(*object);
>>     }
>> #endif
>> 
>>     object->detach(AccessibilityDetachmentType::ElementDestroyed);
>> 
>> tree->removeNode will schedule the isolated object to be detached, so when the live object detach is called, the applyPendingChanges may be detaching the isolated object.
>> 
>> I think we would need to add a variable to be accessed on the main thread to signal whether the isolated object was attached or not.
> 
> Maybe if I revert the order in the AXObjectCache snippet above, then it will be fine to read that pointer on the main thread.

Or adding a tracking bit seems ok too
Comment 9 Andres Gonzalez 2022-03-08 18:11:27 PST
(In reply to chris fleizach from comment #8)
> Comment on attachment 454159 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=454159&action=review
> 
> >>>>>> Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm:535
> >>>>>> +    if (!AXObjectCache::isIsolatedTreeEnabled())
> >>>>> 
> >>>>> I think we may want to verify that this wrapper DOES have an isolated object with it, otherwise its possible this object will only exist on the main thread and never get an isolated element
> >>>> 
> >>>> The problem with accessing the wrapper's m_isolatedObject here is that this is on the main thread, and m_isolatedObject should only be accessed on the AX thread after creation.
> >>> 
> >>> can we check for its presence safely? just doing a read on the pointer value?
> >> 
> >> There is no guaranty that we can read that pointer on the main thread. The AX thread could be writing to it at that point, and thus you would read garbage. For instance, in the AXObjectCache we have:
> >> 
> >> #if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
> >>     if (m_pageID) {
> >>         if (auto tree = AXIsolatedTree::treeForPageID(*m_pageID))
> >>             tree->removeNode(*object);
> >>     }
> >> #endif
> >> 
> >>     object->detach(AccessibilityDetachmentType::ElementDestroyed);
> >> 
> >> tree->removeNode will schedule the isolated object to be detached, so when the live object detach is called, the applyPendingChanges may be detaching the isolated object.
> >> 
> >> I think we would need to add a variable to be accessed on the main thread to signal whether the isolated object was attached or not.
> > 
> > Maybe if I revert the order in the AXObjectCache snippet above, then it will be fine to read that pointer on the main thread.
> 
> Or adding a tracking bit seems ok too

Yes, that is actually the only choice because the m_isolatedObject can be written to not only in detach but in AXIsolatedObject::attachPlatformWrapper which is called during updates in applyPendingChanges on the AX thread, so it can be called at any time.
Comment 10 Andres Gonzalez 2022-03-09 09:12:29 PST
Created attachment 454245 [details]
Patch
Comment 11 chris fleizach 2022-03-09 09:15:50 PST
Comment on attachment 454245 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=454245&action=review

> Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperBase.mm:290
> +    m_isolatedObjectInitialized = false;

do we need this? won't it be false by default
Comment 12 Andres Gonzalez 2022-03-09 09:22:33 PST
Created attachment 454249 [details]
Patch
Comment 13 Andres Gonzalez 2022-03-09 09:25:19 PST
(In reply to chris fleizach from comment #11)
> Comment on attachment 454245 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=454245&action=review
> 
> > Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperBase.mm:290
> > +    m_isolatedObjectInitialized = false;
> 
> do we need this? won't it be false by default

Right, ObjC does that! Fixed in latest rev.
Comment 14 EWS 2022-03-09 18:45:01 PST
Committed r291084 (248246@main): <https://commits.webkit.org/248246@main>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 454249 [details].