enigo-rs / enigo

Cross platform input simulation in Rust
MIT License
920 stars 98 forks source link

Core dumped when invoking `mouse_location()` on Linux. #181

Closed efJerryYang closed 10 months ago

efJerryYang commented 1 year ago

Describe the bug I encountered a bug while using Tauri to build a desktop application on Linux. This issue only occurs in release mode; the debug build runs without any problem.

When invoking the mouse_location() from a tauri command function, a Segmentation fault (core dumped) error appears. Switching to production debug mode using the VS Code debugging tool (following this guide Tauri - Debugging in VS Code) reveals that the error occurs at the address 0x555500000000, which seems to be a memory access error. No such error arises when using development debug mode.

Error message in console:

./src-tauri/target/release/reproduce-bug

# ignore some Gtk Warnings as I am using KDE

Input: He
Segmentation fault (core dumped)

Error message you can see from vscode debugger: SIGNAL SIGSEGV: INVALID ADDRESS (FAULT ADDRESS: 0X555500000000)

The corresponding source code is as follows:

    let mut enigo = Enigo::new();
    println!("Input: {}", name);

    let current_pos = enigo.mouse_location();
    println!("Current mouse location: {:?}", current_pos);

To Reproduce The process of constructing the application using create-tauri-app is shown below:

cargo install create-tauri-app
cargo create-tauri-app

Following the prompts, my settings were as follows:

✔ Project name · reproduce-bug
✔ Choose which language to use for your frontend · TypeScript / JavaScript - (pnpm, yarn, npm)
✔ Choose your package manager · yarn
✔ Choose your UI template · Vue - (https://vuejs.org)
✔ Choose your UI flavor · TypeScript

Then I could successfully launch a desktop application by following the provided instructions. To reproduce this bug, I modified the greet function in src-tauri/src/main.rs as follows:

#[tauri::command]
fn greet(name: &str) -> String {
    use enigo::{Enigo, MouseControllable};
    let mut enigo = Enigo::new();
    println!("Input: {}", name);

    let current_pos = enigo.mouse_location();
    println!("Current mouse location: {:?}", current_pos);

    "Action triggered successfully".to_string()
}

Also, I added the corresponding enigo dependency in the Cargo.toml:

enigo = { version = "0.1.2", features = ["with_serde"] }

To compile successfully, I also modified the "identifier" in the src-tauri/tauri.conf.json file, changing it to "org.test.dev",.

At this point, the minimalist application build was complete. The binary generated in debug mode using cargo tauri dev ran normally, and calling mouse_location did not cause any problems. However, when I switched to release mode:

cargo tauri build -b none # -b none is to avoid generating a large appimage file and improve testing efficiency

Running the binary located in src-tauri/target/release/ caused the segmentation fault.

Expected behavior The release build should behave consistently with the development build, correctly obtaining the mouse's coordinate position. However, the release build results in a core dump.

Environment (please complete the following information):

The environment displayed by cargo tauri info is shown below:

cargo tauri info

[✔] Environment
    - OS: Ubuntu 23.04 X64
    ✔ webkit2gtk-4.0: 2.40.1
    ✔ rsvg2: 2.54.5
    ✔ rustc: 1.72.0-nightly (a97c36dd2 2023-06-07)
    ✔ Cargo: 1.72.0-nightly (b0fa79679 2023-06-03)
    ✔ rustup: 1.26.0 (5af9b9484 2023-04-05)
    ✔ Rust toolchain: nightly-x86_64-unknown-linux-gnu (environment override by RUSTUP_TOOLCHAIN)
    - node: 17.9.1
    - pnpm: 7.27.1
    - yarn: 1.22.19
    - npm: 8.11.0

[-] Packages
    - tauri [RUST]: 1.3.0
    - tauri-build [RUST]: 1.3.0
    - wry [RUST]: 0.24.3
    - tao [RUST]: 0.16.2
    - @tauri-apps/api [NPM]: 1.3.0
    - @tauri-apps/cli [NPM]: 1.3.1

[-] App
    - build-type: bundle
    - CSP: unset
    - distDir: ../dist
    - devPath: http://localhost:1420/
    - framework: Vue.js
    - bundler: Vite

Additional context It's worth noting that when I added a print line to the mouse_location method in the enigo source code (linux.rs), I was able to compile an application that worked. However, this seems absurd, and this kind of workaround should not be the solution.

// enigo-0.1.2/src/linux.rs
    fn mouse_location(&self) -> (i32, i32) {
        println!("here in mouse_location"); // when I added this line, the release version did not crash
        let mut x = 0;
        let mut y = 0;
        let mut unused_screen_index = 0;
        let mut unused_window_index = CURRENT_WINDOW;
        unsafe {
            xdo_get_mouse_location2(
                self.xdo,
                &mut x,
                &mut y,
                &mut unused_screen_index,
                &mut unused_window_index,
            )
        };
        (x, y)
    }
dladeira commented 10 months ago

I'm having the exact same issue.

luc4hu commented 10 months ago

Hey, I'm having the same issues (even without tauri).

I think I found the culprit. Could you please try out the fix in #194 and let me know if that works for you? (@dladeira @efJerryYang)

Thanks!

efJerryYang commented 10 months ago

Yes, it works. Thanks for your investigation!