PolyMeilex / rfd

Rusty File Dialog
MIT License
564 stars 64 forks source link

Attempted to construct an Id from a null pointer if binary is deleted #111

Open dceddia opened 1 year ago

dceddia commented 1 year ago

I'm using Tauri and its auto-updater functionality. It prompts "do you want to download the update?" and then separately, "do you want to restart now?" (after it has unpacked the files and replaced the binary). If I say "No" and then try to open a file dialog, I get a panic with the message Attempted to construct an Id from a null pointer.

I was able to reproduce the crash using only this rfd library. I changed the simple.rs example to add a pause:

#[cfg(not(target_arch = "wasm32"))]
fn main() {
    let path = std::env::current_dir().unwrap();

    // Added this pause:
    println!("press enter to continue (after deleting the target/debug/examples/simple)");
    let mut input = String::new();
    let _ = std::io::stdin().read_line(&mut input);

    let res = rfd::FileDialog::new()
        .add_filter("text", &["txt", "rs"])
        .add_filter("rust", &["rs", "toml"])
        .set_directory(&path)
        .pick_files();

    println!("The user choose: {:#?}", res);
}

#[cfg(target_arch = "wasm32")]
fn main() {
    // On wasm only async dialogs are possible
}

If I run this, then delete the binary, then hit enter, it crashes reliably. I'm running macOS 12.5.1 (might matter? I haven't tried on other OSes yet).

If I set a breakpoint here in Panel::new and see that panel is null. It seems that [NSOpenPanel openPanel] is returning a null pointer.

    pub fn open_panel() -> Self {
        Self::new(unsafe { msg_send![class!(NSOpenPanel), openPanel] })
    }

I tried some other things too, like moving the binary while it was running, and that was fine. I also tried deleting it, and then replacing it with a similar but different one (swapping a release build for a debug one) and that also works fine.

Maybe the real solution here is to avoid deleting the file during the update – and it's possible this is my fault, because I'm working off a fork with some mods to the updater. But it's also very weird! So I'm curious and if you have any ideas why this fails that would be awesome.