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

Add `segfault` keyword #2446

Closed
SoniEx2 opened this Issue May 24, 2018 · 30 comments

Comments

Projects
None yet
@SoniEx2
Copy link

SoniEx2 commented May 24, 2018

There should be a keyword for easy segfaultation. The main use-case is to make your program segfault at runtime.

It's not one of the most common use-cases, but every other systems programming language has an easy to use segfault operation. It seems fairly reasonable to add it to Rust so that Rust stays relevant in the systems programming language category.

I propose segfault be reserved in Rust 2018.

@steveklabnik

This comment has been minimized.

Copy link
Member

steveklabnik commented May 24, 2018

@CryZe

This comment has been minimized.

Copy link

CryZe commented May 24, 2018

It reserves a keyword for it integrating it further into the language.

@steveklabnik

This comment has been minimized.

Copy link
Member

steveklabnik commented May 24, 2018

What's the benefit of that?

@SoniEx2

This comment has been minimized.

Copy link
Author

SoniEx2 commented May 24, 2018

abort is usually an illegal instruction (and has a rather unfortunate name). segfault is guaranteed to be a segfault. (a null dereference is the canonical example of a segfault)

@CryZe

This comment has been minimized.

Copy link

CryZe commented May 24, 2018

What about platforms that don't have segfaults? Like wasm. Would that just abort then?

Also in case this isn't just bait: Is there an actual benefit to segfaulting manually?

@SoniEx2

This comment has been minimized.

Copy link
Author

SoniEx2 commented May 24, 2018

Surely wasm has a null dereference?

@CryZe

This comment has been minimized.

Copy link

CryZe commented May 24, 2018

It just reads from the 0 address just fine without trapping / panicking or anything.

@SoniEx2

This comment has been minimized.

Copy link
Author

SoniEx2 commented May 24, 2018

can you set the 0 address as an abort trap? I doubt rust would be able to use the 0 address anyway, because of how references work...

@Centril

This comment has been minimized.

Copy link
Contributor

Centril commented May 24, 2018

So... I don't exactly understand what the point of intentionally causing a segfault is... why would you want to do that?

@SoniEx2

This comment has been minimized.

Copy link
Author

SoniEx2 commented May 24, 2018

Sometimes, a program is written expecting another program to segfault.

@petrochenkov

This comment has been minimized.

Copy link
Contributor

petrochenkov commented May 24, 2018

@Centril

So... I don't exactly understand what the point of intentionally causing a segfault is... why would you want to do that?

Oh man, this happens all the time if you are working on validation of legacy x86 features, just... not with Rust and not with keywords 😄

@Centril

This comment has been minimized.

Copy link
Contributor

Centril commented May 24, 2018

@SoniEx2 @petrochenkov Interesting; Got any resources I can study re. this?

(I think a keyword for something surely so niche is not warranted)

@SoniEx2

This comment has been minimized.

Copy link
Author

SoniEx2 commented May 24, 2018

I have a program at work that "expects" the target program to segfault, and restarts it when it does so.

A non-segfaulting exit is treated as success.

@ordovicia

This comment has been minimized.

Copy link
Contributor

ordovicia commented May 24, 2018

You can intentionally cause segfault by calling unsafe { *std::ptr::null_mut() = 0; }.
It's not too long.

EDIT: On my platform (x86_64 Linux) and on Playground, this program segment causes segfault with debug mode.
OTOH, with release mode, it causes illegal hardware instruction.

@warlord500

This comment has been minimized.

Copy link

warlord500 commented May 24, 2018

@ordovicia that only works on some platforms and some times, its techinically UB which isnt what @SoniEx2 is asking for. @SoniEx2, why not change the program so that panics or aborts work as errors in your program at work?, I am not sure what would the most effective way to cause a segfault intentionally on all platforms, but I think the most reliable to way to force an error exit would be via panic or abort.

segfault as a keyword simply wouldnt pull its weight,a function maybe but you would have to more percise as in why abort wouldnt work

@ordovicia

This comment has been minimized.

Copy link
Contributor

ordovicia commented May 24, 2018

@warlord500 Oh, you are quite right. And that's why optimization changes the behavior of my program above. Thanks!

@petrochenkov

This comment has been minimized.

Copy link
Contributor

petrochenkov commented May 24, 2018

@Centril
That was intended to be a joke (despite being true), this is one of the most crazy useless suggestions I've ever seen.

@Diggsey

This comment has been minimized.

Copy link
Contributor

Diggsey commented May 24, 2018

There's no way this justifies a new keyword. I don't think it even justifies a place in the standard library. This could easily be implemented in a crate using OS-specific system calls to trigger the desired behaviour.

Segfaults are not a portable concept to begin with, and AFAIK you can't generate a segfault with portable LLVM IR without invoking undefined behaviour, so it needs to be solved at the OS level anyway.

@SoniEx2

This comment has been minimized.

Copy link
Author

SoniEx2 commented May 24, 2018

Oh please there are very good backwards-compatibility (as in, "reimplementing things in rust in a way that's backwards compatible with the original C code, including equivalent failure modes") reasons to have this. LLVM can be patched, or you can use inline asm.

@CryZe

This comment has been minimized.

Copy link

CryZe commented May 24, 2018

How does explicitly segfaulting work in C?

@SoniEx2

This comment has been minimized.

Copy link
Author

SoniEx2 commented May 24, 2018

It just... happens.

@CryZe

This comment has been minimized.

Copy link

CryZe commented May 24, 2018

So just like in Rust? Why does Rust need a keyword / library function if C doesn't have that either?

@SoniEx2

This comment has been minimized.

Copy link
Author

SoniEx2 commented May 24, 2018

Rust doesn't segfault, unless something else does. Rust can segfault if a C library you're using segfaults, or if your unsafe code is broken, etc.

But when reimplementing something in safe Rust, it really doesn't segfault. It may panic, but that's still different from a segfault.

@wesleywiser

This comment has been minimized.

Copy link
Member

wesleywiser commented May 24, 2018

Safe Rust doesn't segfault but unsafe certainly can.

unsafe { *std::ptr::null() } produces Segmentation fault on the playground.

@SoniEx2

This comment has been minimized.

Copy link
Author

SoniEx2 commented May 24, 2018

No it doesn't.

@Diggsey

This comment has been minimized.

Copy link
Contributor

Diggsey commented May 24, 2018

@SoniEx2 it doesn't in this case because it invokes undefined behaviour which the compiler optimises away.

Note that if you compiled the exact equivalent C/C++ code with clang and the same optimisation level, it would likely do the exact same thing, and would not be guaranteed to segfault.

@Diggsey

This comment has been minimized.

Copy link
Contributor

Diggsey commented May 24, 2018

You should use the nix crate:

use nix::sys::signal;

fn main() {
    signal::raise(signal::Signal::SIGSEGV);
}

https://docs.rs/nix/0.10.0/nix/sys/signal/fn.raise.html

@barzamin

This comment has been minimized.

Copy link

barzamin commented May 24, 2018

Note that there is not a standardized way to segfault across every arch/OS combination. In certain settings, 'segfaulting' isn't even a thing you can do that makes sense. What's a 'segfault' on ring0 x86_64? no-std Cortex M0? wasm?

To make 'segfault' a keyword would definitely fall under the heading of language bloat, in addition to it being an extremely context-dependent operation.

Additionally, note that segfaulting on Linux, SIGSEGV notwithstanding, must necessarily invoke UB of some kind - eg, dereffing an invalid pointer.

@clarfon

This comment has been minimized.

Copy link
Contributor

clarfon commented May 31, 2018

On x86_64 dereferencing usize::max_value() will always segfault as memory addresses can only actually be 48 bits long, whereas zero is a valid address despite never being mapped on most operating systems. For i686 you're out of luck and probably any address is valid if you've got four GiB of memory.

But also, I'm not sure how much I should interpret this as trolling and how much I should interpret it as "I intentionally want segfaults, but I'm exaggerating the desire for a keyword."

@scottmcm

This comment has been minimized.

Copy link
Member

scottmcm commented Jun 8, 2018

@Diggsey's suggestion seems to be the solution here, so I'm going to close.

@scottmcm scottmcm closed this Jun 8, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment