Reputation:
I used to believe it does for certain but... I can't find it explicitly stated.
man 3 exit
and man 2 _exit
verbosely specify the effects of process termination, but don't mention memory leaks.
Posix comes closer: it mentions this:
Memory mappings that were created in the process shall be unmapped before the process is destroyed.
[TYM] [Option Start] Any blocks of typed memory that were mapped in the calling process shall be unmapped, as if
munmap()
was implicitly called to unmap them. [Option End]
Intermixing this with man 3 malloc
:
Normally,
malloc()
allocates memory from the heap, and adjusts the size of the heap as required, usingsbrk(2)
. When allocating blocks of memory larger thanMMAP_THRESHOLD
bytes, the glibcmalloc()
implementation allocates the memory as a private anonymous mapping usingmmap(2)
.
So we could conclude that if malloc
called mmap
then process termination might make a corresponding call to munmap
, BUT... (a) this "optional feature" tags in this POSIX specification are kind of worrying, (b) This is mmap
but what about sbrk
? (c) Linux isn't 100% POSIX conformant so I'm uncertain if intermixing Linux docu with Posix specs is mandated
The reason I'm asking is this... When a library call fails, am I allowed to just exit?
if(somecall() == -1) {
error(EXIT_FAILURE, errno, "Big fat nasty error.\n");
}
Or do I have to go up the stack making sure everything all the way up to main()
is free()
'd and only call exit
or error
in main()
?
The former is so much simpler. But to feel easy going with the former, I'd like to find it in the docs explicitly mentioned that this is not an error and that doing this is safe. As I said, the fact that the docs care to explicitly mention a number of guarantees of what will surely be cleaned up BUT fail to mention this specific guarantee unsettles me. (Isn't it the most common and most obvious case? Wouldn't this be mentioned in the first place?)
Upvotes: 14
Views: 1086
Reputation: 140748
I am certain that the POSIX committee intended that all memory allocated by malloc
should be deallocated as one of the "consequences of process termination" listed in the specification of _exit
that you linked to. I can also tell you that in practice every implementation of Unix I've ever used has done this.
However, I think you have found a genuine lacuna in the specifications. POSIX doesn't say anything about memory allocated by sbrk
, because it doesn't specify sbrk
at all. Its specification for malloc
is taken more-or-less verbatim from the C standard, and the C standard intentionally doesn't say that all memory allocated by malloc
should be deallocated upon "normal termination" because there exist embedded environments that don't do that. And, as you point out, "memory mappings that were created in the process" could be read to apply only to allocations made directly by mmap
, shmat
, and similar. It might be worth filing an interpretation request with the Austin Group.
Upvotes: 7
Reputation: 121407
This "freeing" is done at kernel level. So you are unlikely to find anything direct in POSIX API or C specifications as virtual memory is well "below" them. So you would hardly find anything relevant - let alone guarantees.
On Linux, the kernel reclaims the memory on process exit (both sbrk and mmap), which is guaranteed. See source code of mm.
When a library call fails, am I allowed to just exit?
Yes. This is fine to do.
However, note that there may be other considerations you need to think of, such uncleaned temporary files, open database/network connections and so on. E.g., if your program leaves a database connection open and exits, the server side may not know when to close the connection.
You can read more about Virtual Memory Manager (it's based on older kernel but the idea is still applicable).
Upvotes: 7