-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Can we stop generating illegal instructions? #1454
Comments
There’s a bunch of reasons to generate the
If you’re hitting (executing) a If you can prove there’s no code invoking UB in your code and the libraries you use, its a bug in rustc. |
@nagisa we use unreachable in other contexts, like an OOM, that valid code can hit. EDIT: we actually specifically use the abort intrinsic instead, which is lowered to a ud2 as well. |
@nagisa You're confusing abort and unreachable and OP is complaining not because of the existence of abort but because unwinding is not implemented on windows and thus panicking causes an abort. |
@sfackler |
There is no need for a fix because nothing is broken. |
32bit MSVC only, IIRC. The OP has explicitly mentioned x86-64. Both of x86-64-msvc and x86-64-gnu have implementations of unwinding. |
Then there is another bug somewhere but this has nothing to do with ud2. |
@sfackler Then OOM should do something else. Changing abort into a breakpoint is nonsensical. |
AFAIK, |
@huonw sure. The code I'd been fiddling around with was more or less this: And when compiled to object code and disassembled using the following commands
my code produced the following disassembly: My result of running
|
Oh, were you calling A good way to resolve this is to use some other way to handle errors, e.g. return a worked/failed boolean from the function: pub unsafe extern fn cell_get_fixnum(cell: *mut Cell, num: *mut i32) -> i32 {
match *cell {
Cell::Fixnum(i) => { *num = i; 1 }
Cell::Double(f) => { *num = f as f64; 1 }
_ => { 0 }
}
} (Incidentally, if you're calling things from other languages you'll need the |
Well the intention was to "print error message and stop application" upon a bad state, which is why I was using panic!, although it would seem that if its behavior is intended to be undefined when run from another program, I may just have to write my own crash() function to handle this all gracefully (even if it's not necessarily idiomatic Rust). Still, I am confused as to why Rust emits illegal instructions in the first place. Although I am not the most knowledgeable about compilers in general, I did find myself asking a professor today his opinions on when it would be appropriate for a compiler to emit such an instruction. His response was a simple "never," leaving me to question the logic behind these choices. But anyways, thanks for the advice with regards to an alternative way to handle those errors. Although I was under the impression that extern is for importing functions written in C, and not necessarily needed for exporting functions, as I have been able to get functions to be visible and callable from C without the keyword, so long as I use |
What you see in your disassembly, namely the Consider what would happen, if For now I filled rust-lang/rust#30791 resolving which would make |
Yeah, if you want certain exit behaviour writing it yourself will be better than relying on
It's a little more subtle than never: it's a very effective way to stop execution when there's a problem, e.g. Clang/LLVM sometimes emits a
Also, it might be worth noting that rustc isn't directly choosing to emit
There's two uses of the
The latter is what I'm talking about. Both ends of a function call Thanks for filing, but I don't think there's any action to be taken here, especially now that rust-lang/rust#30791 has been opened: usually, it's a bug in the program (or some library it is using) if a |
In my experiments in programming Rust, I've noticed that the panic! macro seems to generate an instruction called ud2 on x86-64 -- an instruction that is intentionally invalid. Doing this, I presume, is to intentionally raise a SIGILL and crash the program, a practice I have not seen in any other systems programming language. This should likely be for the same reason that no one terminates a process by intentionally dereferencing a null pointer -- the OS has more graceful ways of stopping it, and nobody wants to add "segmentation fault" or "illegal instruction" (or similar output messages depending on the OS) to their program's output. On Windows, this becomes particularly annoying, as running into either of these errors will cause a window to appear for a few seconds informing the user that the program has stopped working.
Would it be unreasonable to simply print the appropriate error message and call std::process::exit()?
The text was updated successfully, but these errors were encountered: