fix: avoid UIA teardown hang on browser exit#277
Conversation
|
Thanks for the detailed writeup. I followed your exact steps but can't reproduce the residue on my machine. I understand this type of issues are often hard to reproduce, but I still want to pin down the root cause before merging. Could you grab a dump of a stuck chrome.exe and share the main thread's call stack? And just to make sure, do you disable "Continue running background apps when Google Chrome is closed" in chrome://settings/system? |
|
I reproduced this with a fresh portable Chrome 150.0.7871.129 installation and a fresh user-data directory, using the pre-fix UIA build from 8b22f8d (Chrome++ 1.15.2). After opening two tabs, double-clicking one tab to initialize the UIA path, and closing all browser windows, two chrome.exe processes remained. I captured a full dump of the browser process. The main thread (CrBrowserMain) is blocked during process shutdown in a cross-apartment COM release: win32u!NtUserMsgWaitForMultipleObjectsEx This confirms the process is hanging while the thread-local UIA session is torn down from the injected DLL's TLS destructor. The dump is approximately 649 MB; I can provide it separately. |
|
Can you try disabling "Continue running background apps when Google Chrome is closed" in chrome://settings/system? |
|
Yes. I confirmed that “Continue running background apps when Google Chrome is closed” is disabled in chrome://settings/system. I reproduced the same residual chrome.exe processes after closing the fresh portable Chrome profile. |
|
Thanks! |
Summary
Prevent Chrome from remaining in the background after all browser windows are closed.
Root cause
The thread-local
UiaSessiondestructor releases UI Automation proxies during the injected DLL's TLS teardown.When this cleanup runs on Chrome's UI thread, releasing these apartment-bound COM proxies can block indefinitely during process shutdown, leaving Chrome processes in the background.
Regression
The regression was introduced by commit 8b22f8d, which migrated tab and
bookmark handling from IA2 to UI Automation.
On Chrome 150.0.7871.129, the parent commit f7d23b3 exited normally after
the affected interaction, while 8b22f8d still had Chrome processes running
after 15 seconds.
The first affected prerelease was 1.16.0-alpha.1, and the first affected
stable release was 1.16.0.
Fix
Keep the
UiaSessionisolated per thread, but intentionally give it process lifetime by storing it behind a thread-local pointer.This prevents UIA and COM cleanup from running during the injected DLL's TLS teardown. The operating system reclaims the process resources when Chrome terminates.
Trade-off
This intentionally skips per-thread UIA and COM teardown.
The UIA session is currently instantiated only on Chrome's browser UI thread through thread-specific input hooks, so the retained state is bounded to one session per browser process.
This project loads
version.dllfor the lifetime of the browser process and does not support unloading it while Chrome is still running.Testing
xmake build -y.Related to #271.