UIAutomationCore doesn't release IAccessible2 objects which get focus
Categories
(Core :: Disability Access APIs, defect)
Tracking
()
People
(Reporter: Jamie, Assigned: Jamie)
References
(Depends on 1 open bug)
Details
Attachments
(1 file)
6.00 KB,
text/plain
|
Details |
Spun off bug 1572915 comment 18.
As part of my investigation regarding the RPC hang (bug 1572915), I added some debugging code to track when we create and destroy handlers.
Simply fetching an accessible with AccessibleObjectFromEvent/accChild on the root, we get the handler and then destroy it. This is what I expected, since the parent process gives the object to the out-of-process client and then forgets about it.
However, whenever an object gets focus, even after refreshing the document, the handler for the object that had focus never gets destroyed! Leaky leaky leaky!
Disabling virtual buffers doesn't fix this. Disabling NVDAHelper (NVDA's in-process componentry) doesn't fix this. Disabling NVDA's UIA support does fix this!
So, the next question is: why is UIA not releasing objects (or what is it doing that's causing us to leak a reference)? My guess is that it caches objects, but then I'm not sure how to invalidate that cache. Firing EVENT_OBJECT_DESTROY does not fix this leak, nor does firing EVENT_OBJECT_HIDE. (I'm pretty sure we were already firing hide, but I fired it again in ProxyDestroyed just in case. No joy.)
NVDA's experimental selective UIA event registration does not help here. That's not surprising, since unfortunately, focus event listening is global; you can't restrict it to specific processes.
Narrator and JAWS seem to leak objects in this way too.
I sent an email to a contact at Microsoft asking for details on how UIA manages the lifecycle of IAccessible2 proxies. I am awaiting a response.
Assignee | ||
Comment 1•4 years ago
|
||
I created a test case which just exposes a single MSAA object and logs the ref count to the console when Release is called.
Compile with:
cl msaaTest_noIMarshal.cpp user32.lib ole32.lib oleaut32.lib oleacc.lib
Whenever UIA touches this (e.g. focusing the window with Narrator or NVDA), when switching away from the app, the ref count never goes down to 1; it stays at 9 or higher. If you repeatedly alt+tab to the app and away again, the ref count keeps getting higher. Exiting NVDA/Narrator doesn't make the ref count go down. Even after waiting 10 minutes, the ref count doesn't go down.
Firing EVENT_OBJECT_HIDE and EVENT_OBJECT_DESTROY has no effect. (You can trigger this by sending WM_USER to the test window.)
In contrast, if you use NVDA with UIA disabled, the ref count goes down to 1 when you switch away from the app as expected.
I've sent this (and details) to Microsoft.
Assignee | ||
Comment 2•4 years ago
|
||
If I block uiautomationcore.dll using the Windows dll blocklist, Narrator still works, including caret tracking in editable text. This suggests UIA runs out-of-process in that case. I knew this was possible with the MSAA proxy, but I wasn't sure about the IA2 proxy.
What's really curious is that the leak still occurs even when UIA is running out-of-process. At the very least, I would have expected references to get cleaned up when the UIA client exits, since it presumably held the COM references and normal COM rules should apply. However, this isn't the case: again, the object never gets destroyed.
Assignee | ||
Comment 3•9 months ago
|
||
I neglected to update this to note that I received a reply from Microsoft on 28 July 2020 which notes:
Haven’t figured out the leak yet. I’ve opened a bug to track this.
The test case seems to indicate that this is a UIA bug. I don’t think I’m seeing a leak on the client side, but I need to check UIA on the provider side.
I never got any follow-up after that. Unfortunately, I wasn't given a bug id on the Microsoft side.
Assignee | ||
Comment 4•17 days ago
|
||
This should cease to be a practical concern once we have native UIA, since the IA2 proxy won't be used any more.
Description
•