AltF02 / x11-rs

Rust bindings for X11 libraries
https://docs.rs/x11
MIT License
207 stars 66 forks source link

Illegal instruction in nightly-x86_64-unknown-linux-gnu unchanged - rustc 1.29.0-nightly (866a71325 2018-07-29) #90

Closed norru closed 6 years ago

norru commented 6 years ago

Cross-posting from rust-lang

https://github.com/rust-lang/rust/issues/52875#issuecomment-409360741

Cargo.toml:x11-dl = "2.18.1" Illegal instruction with Rust nightly


2018-07-30T20:46:20.443731114+01:00 INFO rust_oids::app - Resuming simulation from snapshot: "/home/nico/.config/rust-oids/saved_state/20180730_193912.json"
error: XDG_RUNTIME_DIR not set in the environment.
Illegal instruction
nico@lenovo-devuan:~/Projects/itadinanta/rust-oids$ gdb target/release/rust-oids 
GNU gdb (Debian 7.12-6+b2) 7.12.0.20161007-git
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from target/release/rust-oids...done.
(gdb) run
Starting program: /u01/home/nico/Projects/itadinanta/rust-oids/target/release/rust-oids 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
2018-07-30T20:46:43.747665697+01:00 INFO rust_oids::app - Resuming simulation from snapshot: "/home/nico/.config/rust-oids/saved_state/20180730_193912.json"
error: XDG_RUNTIME_DIR not set in the environment.

Program received signal SIGILL, Illegal instruction.
0x0000555555758d1b in x11_dl::xlib_xcb::Xlib_xcb::open::hcf5d0b06fb3c742a ()
(gdb) stack
Undefined command: "stack".  Try "help".
(gdb) help
List of classes of commands:

aliases -- Aliases of other commands
breakpoints -- Making program stop at certain points
data -- Examining data
files -- Specifying and examining files
internals -- Maintenance commands
obscure -- Obscure features
running -- Running the program
stack -- Examining the stack
status -- Status inquiries
support -- Support facilities
tracepoints -- Tracing of program execution without stopping the program
user-defined -- User-defined commands

Type "help" followed by a class name for a list of commands in that class.
Type "help all" for the list of all commands.
Type "help" followed by command name for full documentation.
Type "apropos word" to search for commands related to "word".
Command name abbreviations are allowed if unambiguous.
(gdb) bt
#0  0x0000555555758d1b in x11_dl::xlib_xcb::Xlib_xcb::open::hcf5d0b06fb3c742a ()
#1  0x00005555556f9b20 in winit::platform::platform::x11::xdisplay::XConnection::new::hd8037cc51043bb68 ()
#2  0x00005555556f14bc in std::sync::once::Once::call_once::_$u7b$$u7b$closure$u7d$$u7d$::h3db9c6506b2778f4 ()
#3  0x00005555557f70e1 in std::sync::once::Once::call_inner::h19d8fb8519a6ca98 () at libstd/sync/once.rs:349
#4  0x0000555555702945 in winit::platform::platform::EventsLoop::new::h96a6247628a19d25 ()
#5  0x00005555556fe0b8 in winit::EventsLoop::new::h494bdedfa0de9eda ()
#6  0x000055555565b8c0 in rust_oids::app::main::main_loop::h05b6ab6851b78251 ()
#7  0x00005555555f3645 in rust_oids::app::run::h9bd1da782e5bcfa7 ()
#8  0x00005555556390f6 in rust_oids::main::h93ddf1c0aa5bdd7c ()
#9  0x0000555555625c23 in std::rt::lang_start::_$u7b$$u7b$closure$u7d$$u7d$::h8a490e39f0d9316a ()
#10 0x00005555557e4ff3 in std::rt::lang_start_internal::_$u7b$$u7b$closure$u7d$$u7d$::he46bbe21d122334d () at libstd/rt.rs:59
#11 std::panicking::try::do_call::h8ed5eafe3e94e158 () at libstd/panicking.rs:310
#12 0x000055555580492a in __rust_maybe_catch_panic () at libpanic_unwind/lib.rs:105
#13 0x00005555557e7a16 in std::panicking::try::hb8f13a044e539797 () at libstd/panicking.rs:289
#14 std::panic::catch_unwind::h09594af9f6e0fec4 () at libstd/panic.rs:392
#15 std::rt::lang_start_internal::ha4a5edbf3a495792 () at libstd/rt.rs:58
#16 0x0000555555639c04 in main ()
norru commented 6 years ago

I believe this won't be fixed in the compiler (as apparently the compiler is doing The Right Thing™:

https://github.com/rust-lang/rust/issues/52898

OvermindDL1 commented 6 years ago

Yeah I'm hitting this recently as well. The referenced rust ticket says it's because some unsafe block has some undefined behaviour regarding a zero-value reference, which is illegal.

ghost commented 6 years ago

This is because of my abomination that is the x11_link! macro. In an old version of the macro, it loaded the library in a single pass instead of a loop (IIRC), but for some reason it was causing stack overflows that appeared to be a rustc bug. Enormous structs on the stack are a pain to work with when stack size is so limited, but afaik we still don't have the box keyword.

I find it unpleasantly surprising that a language marketed toward kernel writers is making it increasingly harder to directly operate on memory.

Edit: ~I just read #91, and this seems like the only possible fix that doesn't break backwards compatibility.~

ghost commented 6 years ago

It looks like they've re-opened 52898. This was a breaking change in rustc and contradicts the docs, and I really hope they revert it.

norru commented 6 years ago

FYI, Bug still open in x11-dl 2.18.2

ghost commented 6 years ago

Looks like #91 fails to build on my system, probably because generating a behemoth function requires more RAM than the 4 GiB on my laptop. This seemed like the only thing that would work. I'm seriously out of ideas unless the rust devs decide to revert this unacceptable regression in the compiler.

norru commented 6 years ago

While I'm all for strong defined behaviour, I think this one was rushed.

Can you try, er, negotiate at least a "stopgap revert" until a graceful way out is found?

ghost commented 6 years ago

This is caused by a change in rustc, so I don't know what to do unless they revert that change (which it's looking more likely that they will). #91 reverts x11-dl to loading libraries like it did something like 2 years ago, and it's not even building on my system anymore. I can try using mem::uninitialized instead of mem::zeroed, as someone suggested that it doesn't have the same level of undefined behavior (which makes no sense to me, but whatever), but I'm not sure it will fix anything. I'll make the change now.

ghost commented 6 years ago

Coyboy fix published. Lmk if it works (the bug wasn't occurring on my system, so I can't test that).

kevinmehall commented 6 years ago

2.18.3 fixes it for me.

I can try using mem::uninitialized instead of mem::zeroed, as someone suggested that it doesn't have the same level of undefined behavior (which makes no sense to me, but whatever)

The undefined behavior is writing a zero to a function pointer, because a function pointer is not allowed to be zero. uninitialized does not write anything to it at all.

ghost commented 6 years ago

That makes sense, but it seems very odd to me that their solution was raise SIGILL, causing existing code to now break instead of hey, we're in an unsafe block, so expect and allow unsafe things to occur, especially when the uninitialized/zeroed value is replaced with something valid before ever being used.

kevinmehall commented 6 years ago

hey, we're in an unsafe block, so expect and allow unsafe things to occur.

That's not what an unsafe block means. You still have to follow the same rules, but rustc isn't checking whether you do or not. If LLVM is told a type is not going to be zero, and code explicitly writes a zero to it, it can assume that code is unreachable, and compile it into an abort to reduce code size.

ghost commented 6 years ago

If LLVM is told a type is not going to be zero, and code explicitly writes a zero to it, it can assume that code is unreachable, and compile it into an abort to reduce code size.

This is the first time I've read a good explanation. In the thread for the issue in the rust compiler, people just said "undefined behavior" and made no explanation of how it's different from uninitialized. Thanks!

norru commented 6 years ago

Bug fixed in 2.18.3. Good work!