https://bugs.winehq.org/show_bug.cgi?id=42546
Bug ID: 42546 Summary: DSOUND_PrimaryOpen() incorrect set buf size Product: Wine Version: 2.2 Hardware: x86 OS: FreeBSD Status: UNCONFIRMED Severity: major Priority: P2 Component: directx-dsound Assignee: wine-bugs@winehq.org Reporter: rozhuk.im@gmail.com
Wine (1.x, 2.x) crashes on FreeBSD 11 release with wineoss.drv With winealsa.drv on FreeBSD 11 - OK. With winoss.drv on FreeBSD 10 - OK.
I made some investigation and make patch to fix problem. I test it and it work. But looks like dsound needs review.
DSOUND_ReopenDevice() call DSOUND_PrimaryOpen() with forcewave = FALSE DSOUND_PrimaryOpen() calculate: new_buflen = device->buflen; new_buflen -= new_buflen % wfx->nBlockAlign; (wrong alig code, but newer mind) Then calculated DWORD alloc_len = frames * sizeof(float); and allocated buffer if (device->buffer) newbuf = HeapReAlloc(GetProcessHeap(), 0, device->buffer, alloc_len); else newbuf = HeapAlloc(GetProcessHeap(), 0, alloc_len); final: save new buffer pointer and size: device->buffer = newbuf; device->buflen = new_buflen; !!! We allocate 6144 (0x00001800) bytes but set buf size to 65536. DSOUND_MixToPrimary() and norm16() in DSOUND_mixthread use device->buflen and corrupt heap after first call.
First I make more proper alignment: new_buflen = (device->buflen + wfx->nBlockAlign); new_buflen -= (new_buflen % wfx->nBlockAlign); and change calculation to: DWORD alloc_len = ((new_buflen / wfx->nBlockAlign) * sizeof(float)); It works.
Next I replace alloc_len->new_buflen and return original calc code: new_buflen = (frames * sizeof(float)); This work but sound with a bit noise and game crash after some time.
Finnaly: new_buflen = ((frames + 1) * wfx->nBlockAlign * sizeof(float)); This work OK. This not looks like proper buf size.
Also in DSOUND_ReopenDevice() after DSOUND_PrimaryOpen(): device->fraglen = frag_frames * wfx->nBlockAlign; device->aclen = aclen_frames * wfx->nBlockAlign;
device->buflen should somehow be synced with this.
606723.622:0034:0035:trace:heap:RtlAllocateHeap (0x110000,70000062,00000030): returning 0x11d438 606723.622:0034:0035:trace:oss:AudioClient_Start (0x1ecb38) now playing... 606723.622:0034:0035:trace:oss:AudioClient_GetStreamLatency (0x1ecb38)->(0x335f590) 606723.622:0034:0035:trace:oss:AudioClient_GetBufferSize (0x1ecb38)->(0x335f58c) 606723.622:0034:0035:trace:oss:AudioClient_GetBufferSize buffer size: 3840 606723.622:0034:0035:trace:dsound:DSOUND_ReopenDevice period 11 ms fraglen 2048 buflen 6144 606723.622:0034:0035:trace:dsound:DSOUND_PrimaryOpen (0x11e4d8) 606723.622:0034:0035:trace:heap:RtlAllocateHeap (0x110000,70000062,00001800): returning 0x1fc1e8 606723.622:0034:0035:trace:dsound:DSOUND_PrimaryOpen buflen: 65536, fraglen: 0 606723.622:0034:0035:trace:oss:AudioClient_IsFormatSupported (0x1ecb38)->(0, 0x335f650, 0x335f64c) ... 606723.688:0034:003e:trace:dsound:DSOUND_mixthread (0x11e4d8) 606723.688:0034:003e:trace:dsound:DSOUND_PerformMix (0x11e4d8) 606723.688:0034:003e:trace:oss:AudioClient_GetCurrentPadding (0x1ecb38)->(0x1448f6b8) 606723.688:0034:003e:trace:oss:AudioClient_GetCurrentPadding pad: 0 606723.688:0034:003e:warn:dsound:DSOUND_PerformMix Probable buffer underrun 606723.688:0034:003e:trace:oss:AudioRenderClient_GetBuffer (0x1ecb38)->(1536, 0x1448f6b0) 606723.690:0034:003e:trace:heap:RtlAllocateHeap (0x110000,70000062,00001810): returning 0x141908b0 606723.690:0034:003e:trace:dsound:DSOUND_MixToPrimary (0,6144) 606723.690:0034:003e:trace:dsound:norm16 0x1fc1e8 - 0x141908b0 6144 606723.690:0034:003e:trace:oss:AudioRenderClient_ReleaseBuffer (0x1ecb38)->(1536, 0) 606723.690:0034:003e:trace:oss:AudioRenderClient_ReleaseBuffer writen: 6144 606723.690:0034:003d:err:heap:HEAP_ValidateInUseArena Heap 0x110000: block 0x1fc1e8 tail overwritten at 0x1fd9e8 (byte 0/8 == 0x00) Heap: 0x110000 ... Sub-heap 0x110014: base=0x110000 size=00110000 committed=00110000
Block Arena Stat Size Id ... 0x1f0118 00bedead pend 00000430 0x1f0550 00bedead pend 00002c18 0x1f3170 00bedead pend 00000430 0x1f35a8 00bedead pend 00008c30 0x1fc1e0 00455355 used 00001808 0x1fd9f0 00000000 pend 00000000 0x1fd9f8 00000000 pend 00000000 0x1fda00 00000000 pend 00000000 0x1fda08 00000000 pend 00000000