【问题标题】:Why does calling XChangeProperty from Rust and Glium generate a segfault?为什么从 Rust 和 Glium 调用 XChangeProperty 会产生段错误?
【发布时间】:2017-10-29 15:24:17
【问题描述】:

我正在尝试从 Rust 进行 xlib 调用,但我不知道为什么这段代码给了我一个段错误。

main.rs:

extern crate glium;
extern crate x11;

fn main() {
    let mut events_loop = glium::glutin::EventsLoop::new();
    let context = glium::glutin::ContextBuilder::new();
    let window = glium::glutin::WindowBuilder::new()
        .with_dimensions(800, 600)
        .with_title("Backr");
    let display = glium::Display::new(window, context, &events_loop).unwrap();

    unsafe {
        use x11::xlib;

        let x_display = display.gl_window().platform_display() as *mut xlib::Display;
        let x_window = display.gl_window().platform_window() as u64;
        let x_type = CStr::from_bytes_with_nul(b"_NET_WM_WINDOW_TYPE\0").unwrap();
        let x_value = CStr::from_bytes_with_nul(b"_NET_WM_WINDOW_TYPE_DESKTOP\0").unwrap();
        xlib::XChangeProperty(
            x_display,
            x_window,
            xlib::XInternAtom(x_display, x_type.as_ptr(), xlib::False),
            xlib::XA_ATOM,
            32,
            xlib::PropModeReplace,
            xlib::XInternAtom(x_display, x_type.as_ptr(), xlib::False) as *const u8,
            1,
        );
    }
}

Cargo.toml:

[package]
name = "rust-xlib"
version = "0.1.0"
authors = ["Me <me@me.me>"]

[dependencies]
glium = "*" 
x11 = { version = "*", features = ["xlib"] }

Valgrind 报告的分段错误是:

Invalid read of size 8
   at 0x4E7DC40: _XData32 (in /usr/lib/libX11.so.6.3.0)
   by 0x4E58682: XChangeProperty (in /usr/lib/libX11.so.6.3.0)
   by 0x126898: rust-xlib::main (main.rs:17)
   by 0x362397: __rust_maybe_catch_panic (in /home/me/dev/rust-xlib/target/debug/rust-xlib)      
   by 0x34F847: std::panicking::try (in /home/me/dev/rust-xlib/target/debug/rust-xlib)
   by 0x34C325: std::rt::lang_start (in /home/me/dev/rust-xlib/target/debug/rust-xlib)
   by 0x1269F2: main (in /home/me/dev/rust-xlib/target/debug/rust-xlib)
 Address 0x188 is not stack'd, malloc'd or (recently) free'd


Process terminating with default action of signal 11 (SIGSEGV): dumping core
 Access not within mapped region at address 0x18A
   at 0x4E7DC40: _XData32 (in /usr/lib/libX11.so.6.3.0)
   by 0x4E58682: XChangeProperty (in /usr/lib/libX11.so.6.3.0)
   by 0x126898: rust-xlib::main (main.rs:17) 
   by 0x362397: __rust_maybe_catch_panic (in /home/me/dev/rust-xlib/target/debug/rust-xlib)      
   by 0x34F847: std::panicking::try (in /home/me/dev/rust-xlib/target/debug/rust-xlib)
   by 0x34C325: std::rt::lang_start (in /home/me/dev/rust-xlib/target/debug/rust-xlib)
   by 0x1269F2: main (in /home/me/dev/rust-xlib/target/debug/rust-xlib)

从错误消息来看,dataXChangeProperty 的参数似乎有问题,但我真的不知道它可能有什么问题。

【问题讨论】:

  • second-to-last argument of XChangePropertychar * — 你为什么要为它创建一个 Atom 然后再转换它?
  • @Shepmaster 可能是因为 XChangeProperty 手册页非常明确地表明您必须这样做(需要将不是 Atom 本身而是它的 地址 转换为 char*,我'不确定 Rust 的 as *const u8 到底是做什么的)。
  • 谢谢!我能够弄清楚。至于为什么倒数第二个参数的原子,我是通过我在这里找到的一个例子进行的:stackoverflow.com/a/31362328/8852117
  • 当我尝试像上面那样传递倒数第二个参数时,我仍然得到一个段错误。
  • 我认为你需要传递它的地址。一般来说,你会有一个数组。最后一个参数是数组的长度(如果传递单个元素,则为 1,但仍需要传递其地址)。

标签: rust x11 xlib glium


【解决方案1】:

这应该是正确的解决方案:

unsafe {
    use x11::xlib;

    let x_display = display.gl_window().platform_display() as *mut xlib::Display;
    let x_window = display.gl_window().platform_window() as u64;
    let x_type = CStr::from_bytes_with_nul(b"_NET_WM_WINDOW_TYPE\0").unwrap();
    let x_value = CStr::from_bytes_with_nul(b"_NET_WM_WINDOW_TYPE_DESKTOP\0").unwrap();
    let x_data = xlib::XInternAtom(x_display, x_value.as_ptr(), xlib::False);
    xlib::XChangeProperty(
        x_display,
        x_window,
        xlib::XInternAtom(x_display, x_type.as_ptr(), xlib::False),
        xlib::XA_ATOM,
        32,
        xlib::PropModeReplace,
        std::mem::transmute(&x_data),
        1,
    );
}

【讨论】:

  • 不要使用transmute;几乎没有理由这样做。简单的演员表(甚至可能连续 2 次)总是更好。您的答案非常缺乏细节 - 请描述更改是什么(因此未来的读者不必区分问题和答案)以及为什么需要它们。
猜你喜欢
  • 1970-01-01
  • 2011-01-27
  • 2016-02-08
  • 1970-01-01
  • 2013-05-01
  • 2016-01-09
  • 1970-01-01
相关资源
最近更新 更多