Andrew Eikum : winecoreaudio.drv: Ensure divide-by-zero SSE exceptions are masked before calling AudioConverterNew.

Alexandre Julliard julliard at wine.codeweavers.com
Fri Mar 25 10:00:39 CDT 2016


Module: wine
Branch: master
Commit: 8efa49375a92913be3db11c7028c8f7eabccfce7
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=8efa49375a92913be3db11c7028c8f7eabccfce7

Author: Andrew Eikum <aeikum at codeweavers.com>
Date:   Fri Mar 25 08:26:11 2016 -0500

winecoreaudio.drv: Ensure divide-by-zero SSE exceptions are masked before calling AudioConverterNew.

AudioConverterNew can trigger a divide-by-zero exception. Normally this
is masked by the default SSE mask flags. However, iRacing disables this
mask, leading to a crash when it tries to initialize a recording device.

Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/winecoreaudio.drv/mmdevdrv.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/dlls/winecoreaudio.drv/mmdevdrv.c b/dlls/winecoreaudio.drv/mmdevdrv.c
index 9f9fd0d..8316d65 100644
--- a/dlls/winecoreaudio.drv/mmdevdrv.c
+++ b/dlls/winecoreaudio.drv/mmdevdrv.c
@@ -36,6 +36,7 @@
 #include <sys/stat.h>
 #include <sys/ioctl.h>
 #include <fcntl.h>
+#include <fenv.h>
 #include <unistd.h>
 
 #include <libkern/OSAtomic.h>
@@ -1233,6 +1234,8 @@ static HRESULT ca_setup_audiounit(EDataFlow dataflow, AudioComponentInstance uni
         AudioStreamBasicDescription desc;
         UInt32 size;
         Float64 rate;
+        fenv_t fenv;
+        BOOL fenv_stored = TRUE;
 
         hr = ca_get_audiodesc(&desc, fmt);
         if(FAILED(hr))
@@ -1262,7 +1265,17 @@ static HRESULT ca_setup_audiounit(EDataFlow dataflow, AudioComponentInstance uni
             return osstatus_to_hresult(sc);
         }
 
+        /* AudioConverterNew requires divide-by-zero SSE exceptions to be masked */
+        if(feholdexcept(&fenv)){
+            WARN("Failed to store fenv state\n");
+            fenv_stored = FALSE;
+        }
+
         sc = AudioConverterNew(dev_desc, &desc, converter);
+
+        if(fenv_stored && fesetenv(&fenv))
+            WARN("Failed to restore fenv state\n");
+
         if(sc != noErr){
             WARN("Couldn't create audio converter: %x\n", (int)sc);
             return osstatus_to_hresult(sc);




More information about the wine-cvs mailing list