I have been investigating the ole32:clipboard, user32:clipboard and user32:edit failures because they seemed to have a common outside cause, namely the Radeon Windows driver.
But user32:clipboard also sometimes has similar failures in Wine on my box. So I will start with these.
Here is one exemple happening in test_synthesized():
clipboard.c:817: 0024: CloseClipboard() = 1 # the test closed the clipboard
00a4:trace:clipboard:acquire_selection win e000010 00a4:trace:clipboard:X11DRV_SelectionRequest got request on e000010 for selection "CLIPBOARD" target "TARGETS" win bc00001 prop "SELECTION_DATA" # 00a4 is the winex11.drv thread for the clipboard manager # here it got an X11 message
... 00a4:trace:clipboard:OpenClipboard 00010040 == clipboard_hwnd 00a4:trace:clipboard:GetClipboardData CF_TEXT sending WM_RENDERFORMAT to 0005004A
0024:trace:clipboard:CountClipboardFormats returning 4 0024:trace:clipboard:IsClipboardFormatAvailable CF_TEXT -> 1 0024:trace:clipboard:IsClipboardFormatAvailable CF_LOCALE -> 1 0024:trace:clipboard:IsClipboardFormatAvailable CF_OEMTEXT -> 1 0024:trace:clipboard:IsClipboardFormatAvailable CF_UNICODETEXT -> 1 # back to the main test thread
0024:trace:clipboard:OpenClipboard 00000000 clipboard.c:832: 0024: OpenClipboard(00000000) = 0 (open=00010040 own=0005004A) clipboard.c:833: Test failed: 0: gle 5 # the test's OpenClipboard() call fails because winex11.drv has not # released the clipboard yet.
... 00a4:trace:clipboard:GetClipboardData CF_TEXT error c0000034 00a4:trace:clipboard:GetClipboardData CF_UNICODETEXT error c0000034 00a4:trace:clipboard:CloseClipboard
Why did winex11.drv get a query for the clipboard content? Based on other X11 requests I blame KDE's clipboard manager:
00a4:trace:clipboard:X11DRV_SelectionRequest got request on e000010 for selection "CLIPBOARD" target "TARGETS" win 2000013 prop "_QT_SELECTION"
So this explains why it happens on my box and not in the TestBot's VM since they run fvwm and have no clipboard manager.
What should we do about that?
Can this situation happen on Windows? From what I've seen, Windows code has no way of handling these random OpenClipboard failures. If it really works that way, it seems like a design flaw in the Windows API that we can't fix. It wouldn't be the first of those.
On Windows, we could fix this by running the tests on a separate desktop (assuming the software that's intefering doesn't follow us there), but that wouldn't help in Wine.
I found some references to this problem on Windows:
https://stackoverflow.com/questions/68666/clipbrd-e-cant-open-error-when-set...
https://techcommunity.microsoft.com/t5/security-compliance-and-identity/why-...
This says that a mechanism was added to allow Terminal Services to enumerate formats without opening the clipboard. I think this is the AddClipboardFormatListener function. Unfortunately, that doesn't help much with winex11 since it doesn't let us read the data.
I think the only correct way to fix this is to have our test code retry (for some attempt/time limit) when OpenClipboard or functions using it fail.
We could have wine library code that calls OpenClipboard do this, but I'm not sure if there are compatibility implications if Windows does not.
For winex11.drv to not interfere, we'd need some kind of wine-specific interface to user32. I'm not sure to what extent that's possible (we probably have to open the clipboard if the data we want isn't rendered), and it's probably not worth it for an error that doesn't come up in normal usage.
On Tue, 1 Jun 2021, Esme Povirk (they/them) wrote:
I think the only correct way to fix this is to have our test code retry (for some attempt/time limit) when OpenClipboard or functions using it fail.
Something like this works pretty well:
BOOL open_clipboard(HWND hwnd) { BOOL ret = OpenClipboard(hwnd); if (!ret && GetLastError() == ERROR_ACCESS_DENIED) { Sleep(10); ret = OpenClipboard(hwnd); } return ret; }
Then s/OpenClipboard/open_clipboard/. We may want to loop a few times for increased robustness.
But we'd also need to wrap other calls like GetOpenClipboardWindow(). I'm not entirely sure how long the list would be. We'd also need to do something similar for the Ole32 APIs in ole32:clipboard.
That feels invasive. I also worry it may end up masking bugs in Wine.
So I tested a few other approaches.
* A simple check like this at the start of the test would work on Windows:
if (FindWindowA("CLIPBRDWNDLASS", NULL)) { skip("skipping to avoid Ole32 clipboard interference\n"); return; }
- Of course it would not work if some other application monitors the clipboard without going through Ole32. - It also does not solve the Wine + KDE issue. - This feels a bit heavy handed, essentially banning all Radeon, Nvidia and Windows 7 machines.
* I also tried to lure the third party clipboard applications by putting some juicy delay-rendered data in the clipboard to detect them when they get it rendered (WM_RENDERFORMAT).
- That works to detect the Wine + KDE issue. - But it does not work for the Ole32 clipboard one. I guess Ole32 only queries the formats and I don't know how to detect that. - It would still end up skipping the whole test, probably also on Radeon, Nvidia, Wine + KDE, etc.
So maybe the wrapping approach is the only sane option.
This is the Windows side of the issue.
user32:clipboard sometimes fails like this:
clipboard.c:54: 0cc8: Starting open_and_empty_clipboard_thread hWnd=00010010 clipboard.c:55: 0cc8: OpenClipboard(00010010) = 1 (open=00010010 own=00000000) # the thread terminates which implicitly calls CloseClipboard() # so the clipboard should be unopened
clipboard.c:429: Test failed: wrong open window 00670304 # but it is actually opened
It turns out 670304 is actually a CLIPBRDWNDCLASS window created by RadeonSettings.exe.
CLIPBRDWNDCLASS is (usually) a class registered by ole32.
Why does a graphics driver (or associated tools) need to access the clipboard? It may actually be some background thing done by the QT5 framework in which case (based on the issue below) upgrading to a driver using QT5 > 5.12 may help.
https://github.com/Sigil-Ebook/Sigil/issues/401 https://code.qt.io/cgit/qt/qtbase.git/tree/src/plugins/platforms/windows/qwi...
But it turns out Radeon is not the only one using Ole's clipboard and if I try enough times I can also get failures on Nvidia. The w7u VM also has the telltale class but I have not seen failures there.
cw-rx460-win81 (Radeon 19.11.3) clipboard.c:2248: 00670304 CLIPBRDWNDCLASS 0190 '' [C:\Program Files\AMD\CNext\CNext\RadeonSettings.exe] hwnd class pid text executable path
cw-rx460-win2009 (Radeon 21.3.2) clipboard.c:2246: 00040054 CLIPBRDWNDCLASS 0c1c '' [C:\Windows\explorer.exe] clipboard.c:2246: 0004002C CLIPBRDWNDCLASS 1850 '' [C:\Windows\System32\svchost.exe] clipboard.c:2246: 00030056 CLIPBRDWNDCLASS 1850 '' [C:\Windows\System32\svchost.exe]
cw-gtx460-win2009 (Game Ready Driver 391.35) clipboard.c:2247: 000201B2 CLIPBRDWNDCLASS 1c68 '' [C:\Windows\System32\svchost.exe] clipboard.c:2247: 00010230 CLIPBRDWNDCLASS 1c68 '' [C:\Windows\System32\svchost.exe]
w7u clipboard.c:2246: 000100EA CLIPBRDWNDCLASS 05f0 '' [C:\Windows\Explorer.EXE] clipboard.c:2246: 00010052 CLIPBRDWNDCLASS 05f0 '' [C:\Windows\Explorer.EXE]
In any case, guided by the failure patterns I first tried to upgrade the Radeon driver. That helped on cw-rx460-1909 (21.3.2) but the latest drivers either won't install on older Windows versions (the infamous error 184), or crash regularly (even when left alone, and frequently enough during the tests to trigger a Windows reboot). So at least Windows 10 1507 and Windows 8.1 are stuck with 19.11.3 and its RadeonSettings.exe (I did not try the intermediate Windows versions).
Furthermore, while it would likely greatly reduce the failure rate we'd probably still get failures once in a while, likely at a rate so low it would cause TestBot false positives. Just like on Nvidia actually (see the cw-gtx560-1809-32 and cw-gtx560-1909-32 lines).
On 6/1/21 6:58 PM, Francois Gouget wrote:
This is the Windows side of the issue.
user32:clipboard sometimes fails like this:
clipboard.c:54: 0cc8: Starting open_and_empty_clipboard_thread hWnd=00010010 clipboard.c:55: 0cc8: OpenClipboard(00010010) = 1 (open=00010010 own=00000000) # the thread terminates which implicitly calls CloseClipboard() # so the clipboard should be unopened
clipboard.c:429: Test failed: wrong open window 00670304 # but it is actually opened
It turns out 670304 is actually a CLIPBRDWNDCLASS window created by RadeonSettings.exe.
CLIPBRDWNDCLASS is (usually) a class registered by ole32.
Why does a graphics driver (or associated tools) need to access the clipboard? It may actually be some background thing done by the QT5 framework in which case (based on the issue below) upgrading to a driver using QT5 > 5.12 may help.
https://github.com/Sigil-Ebook/Sigil/issues/401 https://code.qt.io/cgit/qt/qtbase.git/tree/src/plugins/platforms/windows/qwi...
But it turns out Radeon is not the only one using Ole's clipboard and if I try enough times I can also get failures on Nvidia. The w7u VM also has the telltale class but I have not seen failures there.
cw-rx460-win81 (Radeon 19.11.3) clipboard.c:2248: 00670304 CLIPBRDWNDCLASS 0190 '' [C:\Program Files\AMD\CNext\CNext\RadeonSettings.exe] hwnd class pid text executable path
cw-rx460-win2009 (Radeon 21.3.2) clipboard.c:2246: 00040054 CLIPBRDWNDCLASS 0c1c '' [C:\Windows\explorer.exe] clipboard.c:2246: 0004002C CLIPBRDWNDCLASS 1850 '' [C:\Windows\System32\svchost.exe] clipboard.c:2246: 00030056 CLIPBRDWNDCLASS 1850 '' [C:\Windows\System32\svchost.exe]
cw-gtx460-win2009 (Game Ready Driver 391.35) clipboard.c:2247: 000201B2 CLIPBRDWNDCLASS 1c68 '' [C:\Windows\System32\svchost.exe] clipboard.c:2247: 00010230 CLIPBRDWNDCLASS 1c68 '' [C:\Windows\System32\svchost.exe]
w7u clipboard.c:2246: 000100EA CLIPBRDWNDCLASS 05f0 '' [C:\Windows\Explorer.EXE] clipboard.c:2246: 00010052 CLIPBRDWNDCLASS 05f0 '' [C:\Windows\Explorer.EXE]
In any case, guided by the failure patterns I first tried to upgrade the Radeon driver. That helped on cw-rx460-1909 (21.3.2) but the latest drivers either won't install on older Windows versions (the infamous error 184), or crash regularly (even when left alone, and frequently enough during the tests to trigger a Windows reboot). So at least Windows 10 1507 and Windows 8.1 are stuck with 19.11.3 and its RadeonSettings.exe (I did not try the intermediate Windows versions).
Furthermore, while it would likely greatly reduce the failure rate we'd probably still get failures once in a while, likely at a rate so low it would cause TestBot false positives. Just like on Nvidia actually (see the cw-gtx560-1809-32 and cw-gtx560-1909-32 lines).
Or it's those "helpful" overlay/settings windows that always appear on startup. Maybe it's possible to just disable the service?
On Tue, 1 Jun 2021, Zebediah Figura wrote: [...]
Furthermore, while it would likely greatly reduce the failure rate we'd probably still get failures once in a while, likely at a rate so low it would cause TestBot false positives. Just like on Nvidia actually (see the cw-gtx560-1809-32 and cw-gtx560-1909-32 lines).
Or it's those "helpful" overlay/settings windows that always appear on startup. Maybe it's possible to just disable the service?
I tried that in the Radeon driver to no avail (I disabled In-Game Overlay, Advertisements, Toast Notifications, but also Upgrade Advisor, Hotkeys (when possible), Check for Updates, System Tray Menu).
Another related bit is that user32:clipboard systematically succeeds right after boot. This is a pain when testing whether upgrading the driver helps: upgrade, reboot, all works, yay, problem solved! But then WineTest runs the tests in alphabetical order so by the time it gets to user32:* everything is broken again and confusion ensues :-(.
Now that I've identified the troublesome window as CLIPBRDWNDCLASS I see that it does not get created right away.
One thing that worked is killing the "Radeon Settings: Host Application" process. * But that does not feel like a proper fix. * I did not find a proper registry entry or service that I could disable to prevent it from starting on boot. * It does not work in newer Radeon driver versions, though maybe disabling some service would work since CLIPBRDWNDCLASS is owned by svchost.exe there.
I did not try tweaking the Nvidia driver settings.