Rust-SDL2 / rust-sdl2

SDL2 bindings for Rust
MIT License
2.71k stars 466 forks source link

audio-whitenoise.rs cause seg fault on Linux #640

Open CorruptComputer opened 7 years ago

CorruptComputer commented 7 years ago

Running audio-whitenoise.rs causes a seg fault:

CorruptComputer@Ubuntu-GNOME:~/Desktop/SDL2test$ cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
 Running `target/debug/sdl2test`
AudioSpec { freq: 44100, format: F32LSB, channels: 1, silence: 0, samples: 1024, size: 4096 }
Segmentation fault (core dumped)

Running Ubuntu GNOME 17.04, 64-bit.

Cobrand commented 7 years ago

Can you run that with RUST_BACKTRACE=1please ? I'm on linux 64bit as well and I don't have any segfault.

It might be related to Alsa or Pulseaudio, so if you have info about the number of audio devices you have or anything particular that might help me debug that, that'd be great.

CorruptComputer commented 7 years ago

RUST_BACKTRACE doesn't seem to change anything:

CorruptComputer@Ubuntu-GNOME:~/Desktop/SDL2test$ RUST_BACKTRACE=1 cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
 Running `target/debug/sdl2test`
AudioSpec { freq: 44100, format: F32LSB, channels: 1, silence: 0, samples: 1024, size: 4096 } Segmentation fault (core dumped)

I know I have Realtek HD Audio, but I have no clue what drivers I am using. Whatever came with Ubuntu has been working fine so I never bothered to look at it. Here's my sound devices if it helps:

CorruptComputer@Ubuntu-GNOME:~/Desktop/SDL2test$ lsmod | grep snd
snd_usb_audio         184320  3
snd_usbmidi_lib        32768  1 snd_usb_audio
snd_hda_codec_hdmi     49152  1
snd_hda_codec_realtek    90112  1
snd_hda_codec_generic    73728  1 snd_hda_codec_realtek
snd_hda_intel          36864  10
snd_hda_codec         126976  4 snd_hda_intel,snd_hda_codec_hdmi,snd_hda_codec_generic,snd_hda_codec_realtek
snd_hda_core           81920  5 snd_hda_intel,snd_hda_codec,snd_hda_codec_hdmi,snd_hda_codec_generic,snd_hda_codec_realtek
snd_hwdep              16384  2 snd_hda_codec,snd_usb_audio
snd_pcm               102400  7 snd_hda_intel,snd_hda_codec,snd_usb_audio,snd_hda_core,snd_hda_codec_hdmi
snd_seq_midi           16384  0
snd_seq_midi_event     16384  1 snd_seq_midi
snd_rawmidi            32768  2 snd_seq_midi,snd_usbmidi_lib
snd_seq                65536  2 snd_seq_midi_event,snd_seq_midi
snd_seq_device         16384  3 snd_seq,snd_rawmidi,snd_seq_midi
snd_timer              32768  2 snd_seq,snd_pcm
snd                    77824  37 snd_hda_intel,snd_hwdep,snd_seq,snd_hda_codec,snd_usb_audio,snd_timer,snd_rawmidi,snd_hda_codec_hdmi,snd_hda_codec_generic,snd_usbmidi_lib,snd_seq_device,snd_hda_codec_realtek,snd_pcm
soundcore              16384  1 snd
Cobrand commented 7 years ago

Silly me, of course Rust doesn't print a backtrace in a segfault ... Unfortunately my debugging power is quite limited here, the best way to debug this would be to execute this program with gdb and try to get a stack trace, or do some println in the code to pinpoint the exact location of the segfault ... Unfortunately since I can't reproduce this, this is impossible for me to debug right now.

Xaeroxe commented 7 years ago

@Cobrand are you using Ubuntu? I've got that set up on my machines so I'm happy to see if I can reproduce if that's the missing variable.

Xaeroxe commented 7 years ago

I am unable to reproduce, I'm using the latest master branch on Ubuntu 16.04. My sound information:

$ lsmod | grep snd
snd_usb_audio         184320  3
snd_usbmidi_lib        32768  1 snd_usb_audio
snd_hda_codec_hdmi     49152  1
snd_hda_codec_realtek    90112  1
snd_hda_codec_generic    73728  1 snd_hda_codec_realtek
snd_hda_intel          36864  10
snd_hda_codec         126976  4 snd_hda_intel,snd_hda_codec_hdmi,snd_hda_codec_generic,snd_hda_codec_realtek
snd_hda_core           81920  5 snd_hda_intel,snd_hda_codec,snd_hda_codec_hdmi,snd_hda_codec_generic,snd_hda_codec_realtek
snd_hwdep              16384  2 snd_hda_codec,snd_usb_audio
snd_pcm               102400  7 snd_hda_intel,snd_hda_codec,snd_usb_audio,snd_hda_core,snd_hda_codec_hdmi
snd_seq_midi           16384  0
snd_seq_midi_event     16384  1 snd_seq_midi
snd_rawmidi            32768  2 snd_seq_midi,snd_usbmidi_lib
snd_seq                65536  2 snd_seq_midi_event,snd_seq_midi
snd_seq_device         16384  3 snd_seq,snd_rawmidi,snd_seq_midi
snd_timer              32768  2 snd_seq,snd_pcm
snd                    77824  37 snd_hda_intel,snd_hwdep,snd_seq,snd_hda_codec,snd_usb_audio,snd_timer,snd_rawmidi,snd_hda_codec_hdmi,snd_hda_codec_generic,snd_usbmidi_lib,snd_seq_device,snd_hda_codec_realtek,snd_pcm
soundcore              16384  1 snd
$ rustc --version
rustc 1.16.0 (30cf806ef 2017-03-10)

I'm beginning to become suspicious this might be a bug somewhere upstream and not in rust-sdl2 itself.

Xaeroxe commented 7 years ago

@CorruptComputer is probably running a newer version of SDL2 than I am though.

@CorruptComputer SDL: http://packages.ubuntu.com/zesty/libdevel/libsdl2-dev My SDL: http://packages.ubuntu.com/xenial/libsdl2-dev

So maybe it's not a system specific problem as much as one that only occurs in SDL 2.0.5.

Xaeroxe commented 7 years ago

I'm setting up a 17.04 VM now to see if I can reproduce.

Xaeroxe commented 7 years ago

I got a vm with 17.04, I still can't reproduce this. @CorruptComputer Post your rustc --version

Xaeroxe commented 7 years ago

So I may have made a mistake earlier with my VM while testing this. The VM didn't have audio, the program was ending instantly, and my terminal may not have been wide enough to see the segfault message. And I've already deleted my VM. Sadly I'm out of time to work on this at the moment but I will certainly try again tonight.

CorruptComputer commented 7 years ago

Ok, so running with some println!'s it seems to die sometime after device.resume();:

fn main() {
    let sdl_context = sdl2::init().unwrap();
    let audio_subsystem = sdl_context.audio().unwrap();

    let desired_spec = AudioSpecDesired {
        freq: Some(44100),
        channels: Some(1),  // mono
        samples: None,      // default sample size
    };

    // None: use default device
    let mut device = audio_subsystem.open_playback(None, &desired_spec, |spec| {
        // Show obtained AudioSpec
        println!("{:?}", spec);

        MyCallback { volume: 0.5 }
    }).unwrap();

    // Start playback
    device.resume();
    println!("device.resume()");
    // Play for 1 second
    std::thread::sleep(Duration::from_millis(1000));
    println!("thread::sleep()");
    {
        // Acquire a lock. This lets us read and modify callback data.
        let mut lock = device.lock();
        println!("device.lock()");
        (*lock).volume = 0.25;
        // Lock guard is dropped here
    }

    // Play for another second
    std::thread::sleep(Duration::from_millis(1000));

    // Device is automatically closed when dropped
}

It gets this far:

CorruptComputer@Ubuntu-GNOME:~/Desktop/SDL2test$ cargo run
   Compiling sdl2test v0.1.0 (file:///home/ngupton/Desktop/SDL2test)
    Finished dev [unoptimized + debuginfo] target(s) in 0.32 secs
     Running `target/debug/sdl2test`
AudioSpec { freq: 44100, format: F32LSB, channels: 1, silence: 0, samples: 1024, size: 4096 }
device.resume()
Segmentation fault (core dumped)

Commenting out both std::thread::sleep()'s seems to make it not seg fault, however nothing ends up playing:

CorruptComputer@Ubuntu-GNOME:~/Desktop/SDL2test$ cargo run
   Compiling sdl2test v0.1.0 (file:///home/ngupton/Desktop/SDL2test)
warning: unused import: `std::time::Duration`, #[warn(unused_imports)] on by default
 --> src/main.rs:5:5
  |
5 | use std::time::Duration;
  |     ^^^^^^^^^^^^^^^^^^^

    Finished dev [unoptimized + debuginfo] target(s) in 0.33 secs
     Running `target/debug/sdl2test`
AudioSpec { freq: 44100, format: F32LSB, channels: 1, silence: 0, samples: 1024, size: 4096 }
device.resume()
thread::sleep()
device.lock()

EDIT: rustc version:

CorruptComputer@Ubuntu-GNOME:~/Desktop/SDL2test$ rustc --version
rustc 1.16.0
Cobrand commented 7 years ago

Does audio-squarewave play correctly ? I suspect it's simply the input that we give in this example that is garbage, because there is absolutely no change between whitenoise and squarewave aside from the data we're giving to the playback.

Makes sense anyway, the audio sent is just rand() * 2.0 - 1.0 where rand is between 0 and 1 randomly. I don't know if you're familiar with how sound is represented but giving a random value for the sound 44100 times per second isn't something your computer is going to appreciate IMO. I might be wrong, but I don't see any other way.

CorruptComputer commented 7 years ago

I actually just changed to AntergOS, I will test it there when I get the chance.