Messages in this thread | | | Date | Thu, 13 Jul 2000 13:50:47 +0200 | From | Jamie Lokier <> | Subject | Re: SIGSEGV on fclose. |
| |
Bjarne Blichfeldt wrote: > #include <stdio.h> > FILE *new; > main () { > fclose (new); /* <---- SIGSEGV on linux only */ > }
Your example misses the point: you're doing "fclose(NULL)". That has
(a) nothing to do with the kernel -- the kernel isn't called at all.
(c) nothing to do with sys_close() or close() in libc -- fclose() won't get as far as calling close().
(b) nothing to do with "closing an unopened file" -- NULL isn't a file at all.
However if we fclose() a already closed file your point is illustrated:
#include <errno.h> #include <stdio.h> FILE * new; int main () { new = fopen ("/tmp/a_file", "w"); if (new) { fclose (new); fclose (new); /* SEGV here */ } return 0; }
Why does this happen? Because fclose(new) calls free(new). You're not allowed to free() the same memory twice, and Glibc's memory allocator knows this and optimises accordingly.
Why does it work on other unix systems? Because some malloc/free implementations let you do things like continue to access the most recently freed block, free it twice, and realloc it. Beware, that's far from reliable everywhere, and it's not supported by the relevant standards either. As the implementation says:
Because freed chunks may be overwritten with link fields, this malloc will often die when freed memory is overwritten by user programs. This can be very effective (albeit in an annoying way) in helping track down dangling pointers.
By the way, your manual page reference is to close(2) which _will_ return EBADF for an already closed file descriptor. That's quite different to fclose(3).
have a nice day, -- Jamie
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |