[Bug 20380] Heroes of Might and Magic III hangs

wine-bugs at winehq.org wine-bugs at winehq.org
Mon Feb 8 05:57:19 CST 2010


http://bugs.winehq.org/show_bug.cgi?id=20380





--- Comment #68 from Roderick Colenbrander <thunderbird2k at gmail.com>  2010-02-08 05:57:19 ---
(In reply to comment #67)
> Created an attachment (id=26121)
 --> (http://bugs.winehq.org/attachment.cgi?id=26121) [details]
> patch
> 
> I've created a small patch for wine-1.1.38/dlls/winex11.drv/dib.c - see
> attachment.
> This patch fixes access flags for DIB image and greatly reduces number of
> exceptions - so it looks like my HOMM3 works fine.

(In reply to comment #66)
> Created an attachment (id=26120)
 --> (http://bugs.winehq.org/attachment.cgi?id=26120) [details]
> trace with WINEDEBUG=+all
> 
> Hello, seems i found where the bug is.
> Yes, it's access violation when writing to read-only DIB image.
> (look for the accesses to address 0x1dd0000 in attachment)
> 
> in short, the we have:
> 
> ---> create DIB image to render screen to
> 0009:trace:bitmap:CreateDIBSection format (800,-600), planes 1, bpp 16, size
> 960000, RGB
> ---> then render to our DIB image
> 0009:trace:bitblt:BitBlt hdcSrc=0x714 0,0 -> hdcDest=0x5cc 0,0 800x600
> rop=cc0020
>     0009:trace:bitblt:X11DRV_StretchBlt     vissrc=0,0-800,600
> visdst=0,0-800,600
>         0009:trace:bitmap:X11DRV_DIB_Lock Locking 0x710 from thread 0009
>         0009:trace:bitmap:X11DRV_DIB_Coerce GdiMod requested in status AppMod
>             0009:trace:bitmap:X11DRV_DIB_DoProtectDIBSection Changed protection
> from 4 to 2
>             ---> DIB image is read-only
>             X11DRV_DIB_DoUpdateDIBSection();
>             0009:trace:bitmap:X11DRV_DIB_DoCopyDIBSection Copying from DIB bits
> to Pixmap
>             0009:trace:bitmap:X11DRV_DIB_DoProtectDIBSection Changed protection
> from 2 to 1
>             ---> and here we have not-accessible DIB image
>         0009:trace:bitmap:X11DRV_DIB_Unlock Unlocking in status GdiMod
>         0009:trace:bitmap:X11DRV_DIB_DoProtectDIBSection Changed protection
> from 1 to 2
>         ---> but now DIB image only read-only!
> ---> and when we try to write
> 0009:trace:ddraw:IDirectDrawSurfaceImpl_Blt
> (0x1792d8)->(0x339ec4,0x1a71e8,0x339f98,1008000,(nil))
>     0009:trace:d3d_surface:IWineD3DBaseSurfaceImpl_LockRect (0x1793d8) :
> rect at 0x339c24 flags(00000000), output lockedRect at 0x339c0c, memory at 0x1dd0000
>     ---> we get SIGSEGV (address 01e54fe8 is within range 0x1dd0000-0x1ebb000)
>     0009:trace:seh:raise_exception code=c0000005 flags=0 addr=0x7ddacaf1
> ip=7ddacaf1 tid=0009
>     0009:trace:seh:raise_exception  info[0]=00000001
>     0009:trace:seh:raise_exception  info[1]=01e54fe8
>         ---> in exception handler we try to restore access flags for read/write
>         0009:trace:bitmap:X11DRV_DIB_Coerce AppMod requested in status InSync
>         0009:trace:bitmap:X11DRV_DIB_DoProtectDIBSection Changed protection
> from 2 to 4
>         ---> ok, now DIB has r/w-access
> 
> This sequence (rw->r->no->r->seh->rw) is repeated again and again generating a
> log of exceptions and at some moment the program hangs.
> Disabling audio something helps, maybe because there is no additional threads
> created for audio processing, but access-violations don't disappear :)

This is the way the DIBSection code is supposed to work. The problem is that
the content of a DIBSection needs to be around on the X11 side but programs
also have to be able to access the data from a pointer. In order to synchronize
both copies there is all this memory protection magic.

In case of a Blt an exception is triggered when the memory copy isn't the
latest revision of the image. This is not a problem.

Games which also give issues are ones which use Lock instead of Blt. In such
cases we present the DIBSection memory directly to the app. Some programs (at
least Populous) directly mess with the stack registers which prevents the
memory protection code from recovering from the exception. This is very bad and
we consider these apps broken (a DIB engine would fix this OR we shouldn't
export the DIBSection memory directly to the app OR prevent the exception from
occuring).

The code which I changed in Wine is related to the DIBSection code. Homm3 uses
16-bit and before we had to convert this 16-bit data to 24-bit on each upload
(this would likely trigger the memory protection code as well). Due to my
xrender work this conversion is not needed. Some code is different now (so
perhaps somewhere I forgot to call some dib memory protection related code) or
my code was fully correct but uncovered a new bug (I mean that when using the
depth conversion, some code 'by accident' disarms the memory protections before
they are presented to the app).



Based on what I described above, you might understand that the patch which you
proposed is not a correct solution since this is how the DIBSection code should
behave. The huge amount of exceptions which occurs is what makes the issue very
hard to debug in combination with the fact that for some apps the stack gets
corrupted which makes it very hard to find what code triggered the bug.

In case of Homm3 I would recommend to figure out first if the bug is not a
result of Homm3 calling Lock/Unlock directly.

Roderick

-- 
Configure bugmail: http://bugs.winehq.org/userprefs.cgi?tab=email
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.



More information about the wine-bugs mailing list