user4385532
user4385532

Reputation:

Does Linux guarantee freeing malloc'd unfreed memory on program exit?

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, using sbrk(2). When allocating blocks of memory larger than MMAP_THRESHOLD bytes, the glibc malloc() implementation allocates the memory as a private anonymous mapping using mmap(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

Answers (2)

zwol
zwol

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

P.P
P.P

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

Related Questions