https://bugs.winehq.org/show_bug.cgi?id=46180
Bug ID: 46180 Summary: wineserver does not unregister windows classes on process termination Product: Wine Version: 3.20 Hardware: x86 OS: Linux Status: UNCONFIRMED Severity: major Priority: P2 Component: wineserver Assignee: wine-bugs@winehq.org Reporter: ralf.habacker@freenet.de Distribution: ---
According to (https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-regi...), Windows unregisters window classes registered by a process at process termination, which is not implemented in wine and leads to resource leaks.
This can lead to an overflow of the global atom table in long running processes, where wineserver is not restarted.
At this point (https://github.com/wine-mirror/wine/blob/master/server/class.c#L159 and https://github.com/wine-mirror/wine/blob/master/server/class.c#L166) an atom is created or the Usage counter incremented, but when destroyed ( https://github.com/wine-mirror/wine/blob/master/server/class.c#L77), the counter is not decremented, which would have to happen with a call to release_global_atom().
https://bugs.winehq.org/show_bug.cgi?id=46180
--- Comment #1 from Alexandre Julliard julliard@winehq.org --- (In reply to Ralf Habacker from comment #0)
According to (https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser- registerclassa), Windows unregisters window classes registered by a process at process termination, which is not implemented in wine and leads to resource leaks.
It's implemented in destroy_process_classes().
https://bugs.winehq.org/show_bug.cgi?id=46180
--- Comment #2 from Ralf Habacker ralf.habacker@freenet.de --- According to https://github.com/wine-mirror/wine/blob/master/server/class.c#L84 destroy_process_classes() is implemented as
void destroy_process_classes( struct process *process ) { struct list *ptr;
while ((ptr = list_head( &process->classes ))) { struct window_class *class = LIST_ENTRY( ptr, struct window_class, entry ); destroy_class( class ); } }
and uses also destroy_class(), but destroy_class() does not release the atom(s).
BTW: destroy_class() is also called from UnregisterClass() (https://github.com/wine-mirror/wine/blob/master/server/class.c#L234), which means relasing the atom need to be in destroy_class() to cover both cases.
https://bugs.winehq.org/show_bug.cgi?id=46180
Ralf Habacker ralf.habacker@freenet.de changed:
What |Removed |Added ---------------------------------------------------------------------------- Summary|wineserver does not |wineserver does not release |unregister windows classes |atom on unregistering |on process termination |window classes
https://bugs.winehq.org/show_bug.cgi?id=46180
--- Comment #3 from Ralf Habacker ralf.habacker@freenet.de --- Created attachment 62862 --> https://bugs.winehq.org/attachment.cgi?id=62862 test case (source code)
https://bugs.winehq.org/show_bug.cgi?id=46180
--- Comment #4 from Ralf Habacker ralf.habacker@freenet.de --- Created attachment 62863 --> https://bugs.winehq.org/attachment.cgi?id=62863 test case (binary)
https://bugs.winehq.org/show_bug.cgi?id=46180
--- Comment #5 from Ralf Habacker ralf.habacker@freenet.de --- Created attachment 62864 --> https://bugs.winehq.org/attachment.cgi?id=62864 windows log
https://bugs.winehq.org/show_bug.cgi?id=46180
--- Comment #6 from Ralf Habacker ralf.habacker@freenet.de --- Created attachment 62865 --> https://bugs.winehq.org/attachment.cgi?id=62865 wine log
https://bugs.winehq.org/show_bug.cgi?id=46180
--- Comment #7 from Ralf Habacker ralf.habacker@freenet.de --- Explanation of the log files:
Windows:
-------- first run-----------------
check internal atoms -> no related atoms available (expected) register classes check internal atoms got name 'test:16002' for atom 'c274' got name 'test:16001' for atom 'c275' got name 'test:16000' for atom 'c276' got name 'test:16005' for atom 'c277' got name 'test:16004' for atom 'c278' got name 'test:16003' for atom 'c279' got name 'test:16009' for atom 'c27c' got name 'test:16008' for atom 'c27f' got name 'test:16007' for atom 'c280' got name 'test:16006' for atom 'c281' -> related atoms available (expected) unregister classes check internal atoms -> no related atoms available (expected)
-------- second run-----------------
check internal atoms -> no related atoms available (expected) ...
Wine:
--------- first run ---------------
check internal atoms -> no related atom available (expected) register classes check internal atoms got name 'test:16000' for atom 'c025' got name 'test:16001' for atom 'c026' got name 'test:16002' for atom 'c027' got name 'test:16003' for atom 'c028' got name 'test:16004' for atom 'c029' got name 'test:16005' for atom 'c02a' got name 'test:16006' for atom 'c02b' got name 'test:16007' for atom 'c02c' got name 'test:16008' for atom 'c02d' got name 'test:16009' for atom 'c02e' -> related atoms available (expected) unregister classes check internal atoms got name 'test:16000' for atom 'c025' got name 'test:16001' for atom 'c026' got name 'test:16002' for atom 'c027' got name 'test:16003' for atom 'c028' got name 'test:16004' for atom 'c029' got name 'test:16005' for atom 'c02a' got name 'test:16006' for atom 'c02b' got name 'test:16007' for atom 'c02c' got name 'test:16008' for atom 'c02d' got name 'test:16009' for atom 'c02e' -> related atoms available (unexpected)
--------- second run ---------------
check internal atoms got name 'test:16000' for atom 'c025' got name 'test:16001' for atom 'c026' got name 'test:16002' for atom 'c027' got name 'test:16003' for atom 'c028' got name 'test:16004' for atom 'c029' got name 'test:16005' for atom 'c02a' got name 'test:16006' for atom 'c02b' got name 'test:16007' for atom 'c02c' got name 'test:16008' for atom 'c02d' got name 'test:16009' for atom 'c02e' -> related atoms available (unexpected)
https://bugs.winehq.org/show_bug.cgi?id=46180
--- Comment #8 from Ralf Habacker ralf.habacker@freenet.de --- I filed two patches:
1. a related test https://source.winehq.org/patches/data/154951 and 2. the main patch https://source.winehq.org/patches/data/154952
Please note that without patch 2, patch 1 will not run successful, but submitting guide mentions to provide test patch first.
https://bugs.winehq.org/show_bug.cgi?id=46180
--- Comment #9 from Ralf Habacker ralf.habacker@freenet.de --- (In reply to Ralf Habacker from comment #8)
- the main patch https://source.winehq.org/patches/data/154952
Just recognized that this patch only applies to git master branch, for stable branch a different patch is required without this line
+ release_global_atom( NULL, class->base_atom );
Unfortunally at https://wiki.winehq.org/Submitting_Patches I did not find a way how to proceed in this case.
https://bugs.winehq.org/show_bug.cgi?id=46180
--- Comment #10 from Ralf Habacker ralf.habacker@freenet.de --- (In reply to Ralf Habacker from comment #8)
I filed two patches:
- a related test https://source.winehq.org/patches/data/154951 and
- the main patch https://source.winehq.org/patches/data/154952
Please note that without patch 2, patch 1 will not run successful, but submitting guide mentions to provide test patch first.
Merged both patches into one and submitted at https://source.winehq.org/patches/data/154959
https://bugs.winehq.org/show_bug.cgi?id=46180
--- Comment #11 from Ralf Habacker ralf.habacker@freenet.de --- Updated patch with https://source.winehq.org/patches/data/154965
Running test case without patch:
$:~/src/wine-build/dlls/user32/tests> make class.ok ../../../../wine/tools/runtest -q -P wine -T ../../.. -M user32.dll -p user32_test.exe.so class && touch class.ok 000f:fixme:service:scmdatabase_autostart_services Auto-start service L"DirMngr" failed to start: 2 class.c:233: Test failed: UnregisterClass() failed - unable to unregister atom class.c:233: Test failed: UnregisterClass() failed - unable to unregister atom 003f:err:rebar:REBAR_NotifyFormat wrong response to WM_NOTIFYFORMAT (0), assuming ANSI Makefile:234: recipe for target 'class.ok' failed
Running test case with patch:
../../../../wine/tools/runtest -q -P wine -T ../../.. -M user32.dll -p user32_test.exe.so class && touch class.ok 000f:fixme:service:scmdatabase_autostart_services Auto-start service L"DirMngr" failed to start: 2 003f:err:rebar:REBAR_NotifyFormat wrong response to WM_NOTIFYFORMAT (0), assuming ANSI
https://bugs.winehq.org/show_bug.cgi?id=46180
--- Comment #12 from Ralf Habacker ralf.habacker@freenet.de --- commit fixing the issue is https://source.winehq.org/git/wine.git/commit/081a48ebabc5c258aa580ff05d31f2...
https://bugs.winehq.org/show_bug.cgi?id=46180
Józef Kucia joseph.kucia@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Resolution|--- |FIXED CC| |joseph.kucia@gmail.com Status|UNCONFIRMED |RESOLVED Fixed by SHA1| |081a48ebabc5c258aa580ff05d3 | |1f29c3fb3e08d
--- Comment #13 from Józef Kucia joseph.kucia@gmail.com --- (In reply to Ralf Habacker from comment #12)
commit fixing the issue is https://source.winehq.org/git/wine.git/commit/ 081a48ebabc5c258aa580ff05d31f29c3fb3e08d
https://bugs.winehq.org/show_bug.cgi?id=46180
Alexandre Julliard julliard@winehq.org changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |CLOSED
--- Comment #14 from Alexandre Julliard julliard@winehq.org --- Closing bugs fixed in 4.0-rc1.