https://bugs.winehq.org/show_bug.cgi?id=29384
--- Comment #39 from Michael Müller michael@fds-team.de --- Hi,
thanks for pointing out this issue. I was able to track down the problem and fix it.
The problem was caused by the way how the unloading of builtin dlls is handled. In order to emulate the WRITECOPY protection correctly, we need remove the WRITE permission from the page and change the protection flags when we get an exception for an invalid write operation on such a page. In order to accomplish this, we have to get the current protection flags from Wines virtual memory management. This is usually no problem, since the required information is set when a page is allocated and will only be removed if a page is freed.
However, there is one exception: builtin dlls. Wine does not allocate the memory using its own memory functions, but uses dlopen / dlcose to take care of this. In order to provide the usual memory functions for these memory areas, Wine still keeps track of stuff like memory protection flags, but the deallocation of the memory is detached from the usual memory functions. For some reason Wine deleted the required memory management information _before_ unloading the builtin dll using dlclose. The destructor of the dll now tried to write to a WRITECOPY page (which was/is part of the dll), but the exception handler was unable to determine the protection flags of the page and thinks it is just a usual page fault and crashes.
In order to solve this problem, I simply swapped the order of deleting the memory management information and unloading the dll using dlclose. Now Steam runs without problems. Moreover I fixed a possible multithreading issue. The updated patch is available at:
https://github.com/compholio/wine-compholio/tree/master/patches/ntdll-WRITEC...