[Bug 60114] New: Client fails to find shared session objects after the session mapping has grown, window class registration fails with error 1411
http://bugs.winehq.org/show_bug.cgi?id=60114 Bug ID: 60114 Summary: Client fails to find shared session objects after the session mapping has grown, window class registration fails with error 1411 Product: Wine Version: 11.13 Hardware: x86-64 OS: Linux Status: UNCONFIRMED Severity: normal Priority: P2 Component: win32u Assignee: wine-bugs@list.winehq.org Reporter: Seth2313@gmail.com Target Milestone: --- Distribution: --- IN PLAIN WORDS Wine keeps user interface objects (window classes, windows, message queues) in a shared memory area that starts small and is supposed to grow as needed. Once it actually has to grow, the application side can no longer find objects that the wineserver created successfully just before - window class registration then fails with error 1411 and the application aborts. Making the area large enough that it never has to grow avoids the problem entirely, which is what points at the growth path as the culprit. SUMMARY After the shared session mapping has had to grow beyond its initial size, the CLIENT can no longer resolve session objects the SERVER has successfully allocated: find_shared_session_object() returns NULL although the server request succeeded and returned a valid locator. Window class registration then fails with ERROR_CLASS_DOES_NOT_EXIST (1411). Raising only the INITIAL size of the session mapping in server/mapping.c:create_session_mapping() from 512 to 32768 object_shm_t slots avoids the growth path entirely and makes the failure disappear permanently. ENVIRONMENT Wine: wine-staging 11.13 (also 11.9, 11.10, 11.11, 11.12) Application: FL Studio 2025 / 2026 (64-bit), large projects with many plugin instances Kernel: 7.1.3 (CachyOS), ntsync in use STEPS TO REPRODUCE 1. Run FL Studio with a stock wineserver. 2. Load a project large enough to create several thousand user objects (window classes, windows, message queues) - in practice a project with many plugin windows. 3. Loading fails with error 1411. Actual result: error 1411; in our case followed by an abort inside the application (c0000409). Expected result: project loads; the session mapping grows transparently. EVIDENCE: THE FAILURE IS ON THE CLIENT SIDE WINEDEBUG output at the moment of failure: err:class:NtUserRegisterClassExWOW Failed to get shared session object for window class That ERR is emitted in dlls/win32u/class.c:656, and the code path matters: SERVER_START_REQ( create_class ) { ... ret = !wine_server_call_err( req ); locator = reply->locator; /* server succeeded, locator valid */ atom = reply->atom; } SERVER_END_REQ; if (!ret) goto failed; /* not taken - server call was fine */ if (!(shared = find_shared_session_object( locator.id, locator.offset ))) { ERR( "Failed to get shared session object for window class\n" ); So the server allocated the object and returned its locator; only the client-side lookup in find_shared_session_object() (dlls/win32u/winstation.c:175) failed. It fails either because find_shared_session_block() could not map a block covering locator.offset, or because the id check "id == shared_object_get_id( object )" did not match. WHY THIS POINTS AT THE GROWTH PATH * Server side, the mapping is explicitly designed to grow: alloc_shared_object() -> find_free_session_block() -> grow_session_mapping() in server/mapping.c, which enlarges the backing file and maps the additional region. * Client side, find_shared_session_block() (dlls/win32u/winstation.c:145) walks the list of already mapped blocks and otherwise calls map_shared_session_block(), which re-opens \KernelObjects\__wine_session and maps a view at the granularity-aligned offset. * A larger INITIAL size cannot change any of this logic - it only ensures the growth path is never taken. That it reliably fixes the failure is the strongest indication that the defect lives in growing the mapping or in the client picking the growth up. One detail I noticed while reading, possibly harmless but it looks wrong: LIST_FOR_EACH_ENTRY( block, &session_blocks, struct session_block, entry ) if (block->offset < offset && offset + size <= block->offset + block->size) The first comparison is strict, so an object located exactly at block->offset is not recognised as covered by that block and an additional view gets mapped. "<=" looks like the intended comparison. WORKAROUND CURRENTLY IN USE --- a/server/mapping.c +++ b/server/mapping.c @@ -1425,7 +1425,7 @@ unsigned int attr, const struct security_descriptor *sd ) { static const unsigned int access = FILE_READ_DATA | FILE_WRITE_DATA; - size_t size = max( sizeof(*shared_session) + sizeof(object_shm_t) * 512, 0x10000 ); + size_t size = max( sizeof(*shared_session) + sizeof(object_shm_t) * 32768, 0x10000 ); size = round_size( size, host_page_mask ); return create_mapping( root, name, attr, size, SEC_COMMIT, 0, access, sd ); In continuous daily use across five Wine releases (11.9 -> 11.13) without any observed side effect. It requires rebuilding wineserver from matching sources after every Wine update, which is why a proper fix would be very welcome. RULED OUT BY TESTING ntsync, esync/fsync settings, and Wine version updates - the failure follows the session pool size and nothing else. AVAILABLE ON REQUEST A full WINEDEBUG=warn+win32u,+class log from a reproduction with the stock wineserver. The interesting lines would be "Failed to map session block for offset ..." from find_shared_session_block(), which would distinguish "could not map the block" from "id mismatch". Say the word and I will produce it. -- Do not reply to this email, post in Bugzilla using the above URL to reply. You are receiving this mail because: You are watching all bug changes.
http://bugs.winehq.org/show_bug.cgi?id=60114 --- Comment #1 from Seth2313@gmail.com <Seth2313@gmail.com> --- Clarification on the scope of the evidence, so that nobody over-reads the original description. The failure was observed and analysed on a single occasion (2026-06-03), and that is where the quoted WINEDEBUG line comes from. Since then the patched wineserver with the larger initial mapping has been in place for practically all use of this setup, so the failure has had little opportunity to recur. "Makes the failure disappear permanently" in the original description should therefore be read as "has not been seen again while the larger initial mapping was in place". It is not the result of a controlled A/B comparison, and I want that stated plainly rather than implied. What this does not change is the log evidence itself: NtUserRegisterClassExWOW had already completed the create_class server call successfully and received a valid locator, and only the client-side find_shared_session_object() lookup failed. That is a direct observation from the log, not an inference from the workaround. If a reproduction with a stock wineserver plus WINEDEBUG=warn+win32u,+class would help triage, I am happy to produce one. It should show whether find_shared_session_block() fails to map the block covering the offset, or whether the id check in find_shared_session_object() mismatches. -- Do not reply to this email, post in Bugzilla using the above URL to reply. You are receiving this mail because: You are watching all bug changes.
participants (1)
-
WineHQ Bugzilla