3 ms·
The first sample code; "This program segfaults because the entire stack is set to 0 at program start." I'd be surprised; as a strong general rule, the stack do
by EliRivers 11y ago
The first sample code; "This program segfaults because the entire stack is set to 0 at program start."
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.
- dkopi 11y agoedit: exDM69 actually makes more sense.
- EliRivers 11y agoWell, I can see the build command on the webpage there, and assuming this is the same gcc we all know and love without any cleverness going on, it's not a debug build of any kind as far as I can see: 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.
- exDM69 11y agoIt's the OS linker/loader that zeros the pages used by a new process to avoid leaking memory contents of previous processes (security risk). It's zero only because this occurs at the very beginning of the program. In general it would be undefined.
- EliRivers 11y agoNice. Learn something every day. I edited my original post to add this; save anyone else tracing through the whole thread.
- Buge 11y agoThe OS will initialize the memory of the stack to 0 before the program starts. But before main is called, the compiler is free to insert other code that runs before main. gcc inserts a function named __libc_start_main that runs before main. This code will modify the content of the stack. So when main is run, the stack where the uninitialized local variable is has a decent chance of not being 0 anymore. This is easily testable. #include <stdio.h> int main(void) { char* pointers[20]; int i; for (i = 0; i < 20; ++i) { printf("%p\n", pointers[i]); } return 0; } And yes when I run it, most of the pointers are not null.
- exDM69 11y agoSure, the C runtime initialization runs before main. Unless you're looking at the stack at _start, it's probably unintialized. And it depends on your libc implementation, etc. It just happened to be zero in the author's case.
- kalmar 11y agoOh this is cool! I should have checked more pointers. On my machine, the single pointer was always null, and I read up on stack being initialized to zero. I didn't realize the things-before-main could mess up the stack so much.
- kalmar 11y agoI should have made that clearer, thanks! If there were intervening function calls there would be garbage. Then it would only "most likely" segfault instead of always segfault.
- Annatar 11y ago> It's the OS zeroing everything - learn something very day 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).