> The Rust program got a segmentation fault because it attempted to write to inaccessible memory, but only through the stack pointer. None of the undefined behaviors disallow this, which I think is why it’s ok for this Rust program to segfault.
What I got out of that is that Rust does not work as advertised if there are still situations where a program could segfault. The entire premise of Rust, as I understood it at least, is that it does things in a safe manner and the programmer does not have to worry about it. Now I learned that there are undefined behaviors. In my view, for a language that bills itself as safe, there should not exist such things as undefined behaviors. As far as I am concerned, then, based on the advertising of Rust, this is false advertising.
(Basically, stack probes are only implemented on Windows, and we need them on the other platforms, but it hasn't been implemented yet, for various reasons.)
The key thing from the reference [0]:
> "Type checking provides the guarantee that these issues are never caused by safe code."
It's subtle, but I think the situation is that "some segfaults are caused by undefined behaviour, and some undefined behaviour causes segfaults". Neither fully contains the other. One thing I was trying to get across is that a segmentation fault has a very specific meaning, and that meaning is not "bad thing was done with pointers".
[0]: http://doc.rust-lang.org/reference.html#behavior-considered-...
I know that Rust in particular tries to be very open about the caveats to its claims, but this is the kind of commentary that causes any ambitious project to try to minimize and hide its weaknesses instead of openly and honestly discussing them. I opened this discussion knowing that there would be a comment just like yours, and it made my heart feel heavy.
Something as core as proper stack handling is to me basic functionality. If the aim is to be a safe language, and there are undefined behaviors, or in this case such bugs, then this is at odds with the Rust public relations effort.
And, any project which resents such technical / conceptual criticism leaves one with much to ponder.
What Rust does promise is that undefined behavior will never happen if you don't use code blocks marked as unsafe (which include the C FFI). In other words, if you are able to trigger undefined behavior without using unsafe code, that is a compiler or library bug.
EDIT: as noted by steveklabnik, this is not undefined behavior. Actually you should get a better error message instead of a segmentation fault (see the link to the issue on GitHub in steveklabnik's comment).
I'd be surprised; as a strong general rule, the stack does not get zeroed [Edit: see end of thread! It's the OS zeroing everything - learn something very day]. I'd expect it to segfault because the pointer value is whatever leftover non-zero value happens to be in that piece of memory, so it points into random memory the user program shouldn't be messing with (sticking in a printf to output the value of the pointer confirms this on at least one system). Wouldn't be surprised if some implementations took security really seriously and zero everything, or if a debug build was zero happy, but under normal circumstances, the stack doesn't get zeroed.
No, the operating system (kernel, actually) does not zero out anything. The runtime linker would be the one initializing static memory declared in the ELF BSS sections at execution time. The rest (including the stack and heap) is setup by the prologue (crti.o, depending on the OS crt1.o, and crts.o).
gcc segfault.c
Now that I think about it, I'm not aware that gcc C compiler even offers the option to deliberately zero initialise non-static local variables, so unless I've missed a switch somewhere there is no arrangement of options available for a "debug build" to do this. I recall the GCC Fortran compiler did offer it.This is because of gcc padding. Programs have to allocate whole page from OS. So if you want just 1 int, you have to get whole page for it (compilers can optimize it in some conditions). This is result of MMU that works for memory block and not for single bytes (performance issue I think) But as I know by default page size have 4KB.
Another reason may be that compiler tries to allocate 2^n bytes because of performance. and 8KB is close enough I think.
This is true only for first thread, other threads have fixed stack size specified on thread creation (on Linux it's 8MB by default), but usually even thread's stack pages are really allocated only on first access.
On UNIX if you really want to bump stack by arbitrary amounts the most portable way is to preallocate your own stack of sufficient size and then use that (either by abusing sigaltstack() or via makecontext()/setcontext() or possibly by creating new thread). But generally, having large local variables is not exactly good idea.
https://users.rust-lang.org/t/rust-guarantees-no-segfaults-w...
Too bad memory is not better segmented then. For instance, when linking against a library, that library's memory ends up in the same "segment" as the program itself. Therefore, right now, you can totally screw up a library's internal data structures without even causing a segfault directly.
...which are caught by the OS and used to either truly kill the process when the stack overflows, or to dynamically allocate more memory as the stack grows downwards. That's how it works on Windows, at least; I'm not as clear about Linux.