Fixed bug 2690 - Floating point exception in Mix_Volume()
authorSam Lantinga <slouken@libsdl.org>
Sat, 23 Aug 2014 10:57:26 -0700
changeset 6969599bb0ff844
parent 695 6a5e6d8d6a35
child 697 b28b41b93ba7
Fixed bug 2690 - Floating point exception in Mix_Volume()

Francisco de la Peña

This happens rarely under uncertain circunstances, as it doesn't crash always and does it randomly. Fortunately, I've got a backtrace when running a GDB session. Might be a divide by zero issue in SDL or SDL_mixer.

Program received signal SIGFPE, Arithmetic exception.
0x00000038e8c08a7d in mix_channels (udata=<optimized out>, stream=0x24e11b0 "", len=2048) at mixer.c:345
345 Mix_Volume(i, (mix_channel[i].fade_volume * ticks) / mix_channel[i].fade_length );
(gdb) bt f
#0 0x00000038e8c08a7d in mix_channels (udata=<optimized out>, stream=0x24e11b0 "", len=2048) at mixer.c:345
ticks = 0
mix_input = <optimized out>
i = 0
mixable = <optimized out>
volume = <optimized out>
sdl_ticks = 129373

Using SDL 2.0.3 and SDL_Mixer 2.0.0, PulseAudio, Fedora 20 x86_64 but looks like can be reproduced on other platforms.
mixer.c
     1.1 --- a/mixer.c	Sat Aug 16 22:46:16 2014 -0700
     1.2 +++ b/mixer.c	Sat Aug 23 10:57:26 2014 -0700
     1.3 @@ -320,7 +320,7 @@
     1.4      /* Mix any playing channels... */
     1.5      sdl_ticks = SDL_GetTicks();
     1.6      for ( i=0; i<num_channels; ++i ) {
     1.7 -        if( ! mix_channel[i].paused ) {
     1.8 +        if ( !mix_channel[i].paused ) {
     1.9              if ( mix_channel[i].expire > 0 && mix_channel[i].expire < sdl_ticks ) {
    1.10                  /* Expiration delay for that channel is reached */
    1.11                  mix_channel[i].playing = 0;
    1.12 @@ -330,7 +330,7 @@
    1.13                  _Mix_channel_done_playing(i);
    1.14              } else if ( mix_channel[i].fading != MIX_NO_FADING ) {
    1.15                  Uint32 ticks = sdl_ticks - mix_channel[i].ticks_fade;
    1.16 -                if( ticks > mix_channel[i].fade_length ) {
    1.17 +                if ( ticks >= mix_channel[i].fade_length ) {
    1.18                      Mix_Volume(i, mix_channel[i].fade_volume_reset); /* Restore the volume */
    1.19                      if( mix_channel[i].fading == MIX_FADING_OUT ) {
    1.20                          mix_channel[i].playing = 0;
    1.21 @@ -340,7 +340,7 @@
    1.22                      }
    1.23                      mix_channel[i].fading = MIX_NO_FADING;
    1.24                  } else {
    1.25 -                    if( mix_channel[i].fading == MIX_FADING_OUT ) {
    1.26 +                    if ( mix_channel[i].fading == MIX_FADING_OUT ) {
    1.27                          Mix_Volume(i, (mix_channel[i].fade_volume * (mix_channel[i].fade_length-ticks))
    1.28                                     / mix_channel[i].fade_length );
    1.29                      } else {
    1.30 @@ -1094,7 +1094,7 @@
    1.31                  (mix_channel[which].fading != MIX_FADING_OUT) ) {
    1.32                  mix_channel[which].fade_volume = mix_channel[which].volume;
    1.33                  mix_channel[which].fading = MIX_FADING_OUT;
    1.34 -                mix_channel[which].fade_length = ms;
    1.35 +                mix_channel[which].fade_length = (Uint32)ms;
    1.36                  mix_channel[which].ticks_fade = SDL_GetTicks();
    1.37  
    1.38                  /* only change fade_volume_reset if we're not fading. */