Bug 155794 - with NVDA running, loading a document via remote UNO connection may hang in SetWindowTextW
Summary: with NVDA running, loading a document via remote UNO connection may hang in S...
Status: RESOLVED FIXED
Alias: None
Product: LibreOffice
Classification: Unclassified
Component: LibreOffice (show other bugs)
Version:
(earliest affected)
unspecified
Hardware: All Windows (All)
: medium normal
Assignee: Michael Stahl (allotropia)
URL:
Whiteboard: target:24.2.0 target:7.6.0.0.beta2
Keywords: accessibility
Depends on:
Blocks:
 
Reported: 2023-06-12 17:39 UTC by Michael Stahl (allotropia)
Modified: 2023-06-14 08:48 UTC (History)
3 users (show)

See Also:
Crash report or crash signature:


Attachments
stack of main thread (29.83 KB, text/plain)
2023-06-12 17:39 UTC, Michael Stahl (allotropia)
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Michael Stahl (allotropia) 2023-06-12 17:39:01 UTC
Created attachment 187873 [details]
stack of main thread

(hi James - i see this as a bug in LO but was thinking maybe it's a fun story)

The problem is that LibreOffice hangs indefinitely in a SendMessage call, only when NVDA is active.

This appears to be largely caused by LO's threading architecture, or lack thereof.

The problem depends on timing, and can be reproduced with the odk/examples/java/DocumentHandling/DocumentLoader.java program.

So there is an external process that starts LibreOffice and then communicates with it remotely via UNO.

The main difference to normal usage of LibreOffice is that this remote connection does its API calls on a thread which is not the main thread.

To make this work, there are several things where the non-main thread does a SendMessage to the main thread, as some things involving Win32 Windows have to be done on the main thread.  For example, there are custom messages sent to the main thread to create the HWNDs, DCs, etc.

Now at one point during loading a document, the Win32 function SetWindowTextW is called, which appears to be equivalent to a SendMessage(WM_SETTEXT) to the main thread. The code is here: https://git.libreoffice.org/core/+/refs/heads/master/vcl/win/window/salframe.cxx#1084

The problem is that this SetWindowTextW blocks forever; if replaced with the following it also blocks forever:
    SendMessageW(mhWnd, WM_SETTEXT, 0, reinterpret_cast<LPARAM>(o3tl::toW(rTitle.getStr())));

Meanwhile, the main thread blocks on a Win32 Event object (that is coupled with a global mutex), via MsgWaitForMultipleObjects and QS_SENDMESSAGE, calling PeekMessageW to dispatch anything sent via SendMessage.

The interesting difference with NVDA running is that while the WM_SETTEXT is being processed in DefWindowProcW, nvdaHelperRemote.dll functions are invoked, and calls oleacc.dll!AccessibleObjectFromEvent, and a WM_GETOBJECT message is dispatched to LO/VCL's handler.

Now handling the WM_GETOBJECT requires the same global mutex/Win32 Event thing that  the main thread is already blocking on, and this now blocks the handling of the WM_SETTEXT message further up the stack, so the non-main-thread that holds the global mutex is blocked on SendMessage forever.

My conclusion is that the main thread must process WM_GETOBJECT without ever acquiring the global mutex.
Comment 1 Commit Notification 2023-06-13 14:07:12 UTC
Michael Stahl committed a patch related to this issue.
It has been pushed to "master":

https://git.libreoffice.org/core/commit/ac1099443e70eefbd8fdd7dd3705fff08a9c75b8

tdf#155794 winaccessibility: no SolarMutex in getAccObjectPtr()

It will be available in 24.2.0.

The patch should be included in the daily builds available at
https://dev-builds.libreoffice.org/daily/ in the next 24-48 hours. More
information about daily builds can be found at:
https://wiki.documentfoundation.org/Testing_Daily_Builds

Affected users are encouraged to test the fix and report feedback.
Comment 2 Commit Notification 2023-06-13 14:08:15 UTC
Michael Stahl committed a patch related to this issue.
It has been pushed to "master":

https://git.libreoffice.org/core/commit/889c12e98e04edb4bc25b86bf16b8cf1d9b68420

tdf#155794 vcl: handle WM_GETOBJECT without SolarMutex

It will be available in 24.2.0.

The patch should be included in the daily builds available at
https://dev-builds.libreoffice.org/daily/ in the next 24-48 hours. More
information about daily builds can be found at:
https://wiki.documentfoundation.org/Testing_Daily_Builds

Affected users are encouraged to test the fix and report feedback.
Comment 3 Michael Stahl (allotropia) 2023-06-13 14:09:37 UTC
hopefully fixed on master
Comment 4 Commit Notification 2023-06-14 08:47:14 UTC
Michael Stahl committed a patch related to this issue.
It has been pushed to "libreoffice-7-6":

https://git.libreoffice.org/core/commit/b54b07d7282e500018226a2976104d5f5b524537

tdf#155794 winaccessibility: no SolarMutex in getAccObjectPtr()

It will be available in 7.6.0.0.beta2.

The patch should be included in the daily builds available at
https://dev-builds.libreoffice.org/daily/ in the next 24-48 hours. More
information about daily builds can be found at:
https://wiki.documentfoundation.org/Testing_Daily_Builds

Affected users are encouraged to test the fix and report feedback.
Comment 5 Commit Notification 2023-06-14 08:48:17 UTC
Michael Stahl committed a patch related to this issue.
It has been pushed to "libreoffice-7-6":

https://git.libreoffice.org/core/commit/6c6ff04a82d50691aaa5d084660b606b5c137be1

tdf#155794 vcl: handle WM_GETOBJECT without SolarMutex

It will be available in 7.6.0.0.beta2.

The patch should be included in the daily builds available at
https://dev-builds.libreoffice.org/daily/ in the next 24-48 hours. More
information about daily builds can be found at:
https://wiki.documentfoundation.org/Testing_Daily_Builds

Affected users are encouraged to test the fix and report feedback.