coder543 / dataplotlib

Scientific plotting library for Rust
59 stars 6 forks source link

Examples crash on Mac OS X #6

Open SirVer opened 7 years ago

SirVer commented 7 years ago

I wanted to check out the examples, unfortunately they do not seem to work on OS X:

$ cargo run --example coloredxy
    Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
     Running `target/debug/examples/coloredxy`
thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: UiThreadExited', src/libcore/result.rs:906:4
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
stack backtrace:
   0: std::sys::imp::backtrace::tracing::imp::unwind_backtrace
   1: std::panicking::default_hook::{{closure}}
   2: std::panicking::default_hook
   3: std::panicking::rust_panic_with_hook
   4: std::panicking::begin_panic
   5: std::panicking::begin_panic_fmt
   6: rust_begin_unwind
   7: core::panicking::panic_fmt
   8: core::result::unwrap_failed
   9: <core::result::Result<T, E>>::unwrap
  10: <dataplotlib::draw_sdl::DrawSDL as dataplotlib::draw::Drawable>::get_events
  11: dataplotlib::plot::draw_plots
  12: dataplotlib::plot::Plot::new2d
  13: dataplotlib::plotter::Plotter::plot2d::{{closure}}
cargo run --example simplexy
   Compiling dataplotlib v0.1.3 (file:///private/tmp/dataplotlib)
    Finished dev [unoptimized + debuginfo] target(s) in 1.38 secs
     Running `target/debug/examples/simplexy`
thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: UiThreadExited', src/libcore/result.rs:906:4
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
stack backtrace:
   0: std::sys::imp::backtrace::tracing::imp::unwind_backtrace
   1: std::panicking::default_hook::{{closure}}
   2: std::panicking::default_hook
   3: std::panicking::rust_panic_with_hook
   4: std::panicking::begin_panic
   5: std::panicking::begin_panic_fmt
   6: rust_begin_unwind
   7: core::panicking::panic_fmt
   8: core::result::unwrap_failed
   9: <core::result::Result<T, E>>::unwrap
  10: <dataplotlib::draw_sdl::DrawSDL as dataplotlib::draw::Drawable>::get_events
  11: dataplotlib::plot::draw_plots
  12: dataplotlib::plot::Plot::new2d
  13: dataplotlib::plotter::Plotter::plot2d::{{closure}}
coder543 commented 7 years ago

Interesting. I don't have ready access to any macs at the moment, but under Windows and Linux it works fine, I believe. I did most of the development on Linux, and I just tested it on Windows 10 right now. I'll try to get with someone who has a MacBook and see if I can reproduce the issue.

coder543 commented 7 years ago

From testing this out on a friend's MacBook, the UI thread is inexplicably dying when it calls SDL2's event poll function. It's leaving no stack trace... it appears to be terminating in the C code of SDL2, from the few minutes that I had access to a Mac to look at this issue. Reading around, this seems similar to issues that are running rampant in the Ruby community since users upgraded to macOS High Sierra.

It could be unrelated to High Sierra, and it would be interesting to see if this issue is reproducible on earlier versions of macOS. Are you running High Sierra?

My code isn't forking though, so I don't know. The only other thing I can think of is that maybe macOS will not allow a thread other than the main thread to handle UI stuff. If that's the case, that would be a huge problem.

SirVer commented 7 years ago

I did not read the code, but are you using SDL2 according to its limitation? Basically, there are two rules that I know of:

  1. You should not expect to be able to create a window, render, or receive events on any thread other than the main one.
  2. Drawing calls must all be made in the same thread, the one that created the renderer. This usually only applies to GPU backends, but SDL2 will default to that.

Together they usually mean that all interactions with SDL2 besides audio must be made in the same thread or you run into issues on one platform or another.

coder543 commented 7 years ago

I've been operating under the tested assumption that you just have to interact with SDL2 from only one thread, which works great on Windows and Linux. Number 2 is explicitly being handled correctly, since SDL2 is not thread safe. The poor ergonomics of requiring the user to run their own stuff in a secondary thread make me concerned about what fixing this issue might involve. The other alternative could be to just have a way to run everything synchronously, which would be a different ergonomic compromise over the current design.

As I don't have a Mac, testing this issue as changes are made to see if it is fixed is difficult.

According to here,

you can only call this function in the thread that set the video mode.

Since all SDL2 initialization and operations are running from a single background thread, it is surely that same thread which set the video mode, unless macOS does some kind of implicit video mode initialization for every program that runs prior to handing control over to that program.

If you can help with this issue, that would be great, but otherwise macOS support may not come until someone else helps.

coder543 commented 7 years ago

Over here, it does say:

WARNING: This should only be run in the thread that initialized the video subsystem, and for extra safety, you should consider only doing those things on the main thread in any case.

which is not exciting.