14

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?)

Community
  • 1
  • 1
  • The call to exit will eventually free up all private anonymous memory of the abandoned process in the kernel. How come you think that Linux doesn't do this ? – Karim Manaouil Nov 22 '18 at 17:08
  • 2
    @KarimManaouil How came I think? Look I dunno how Linux works under the hood. I'm just a n00b who's made it a rule to never do anything he wasn't explicitly told he was allowed to do. This approach, I believe, makes sense when I'm dealing with C++, C, system calls, etc, so basically when the environment is plauged with undefined behavior of all sorts in the least intuitive places. The approach "oh duh this must be working I can't imagine how can this not be working" **has already bitten me** so I prefer to be safe from this time on. –  Nov 22 '18 at 17:21
  • 2
    I, totally, agree with you in this regard. – Karim Manaouil Nov 22 '18 at 17:29
  • When you're asking questions like this, about whether or not things that everyone expects to work a particular way are actually guaranteed to work that way by relevant standards, it helps to tag the question "language-lawyer". – zwol Nov 22 '18 at 17:38
  • @zwol And I did! But this was the fifth tag. Then I thought it'd make sense to tag it "malloc" as well. But I had to remove one of the existing tags to do this. "language-lawyer" was my choice. I still want "laguange-lawyer" to be included, but I'm not sure which of the existing tags to forgo. –  Nov 22 '18 at 17:39
  • @gaazkam I think this question will come to the attention of more of the right people if you drop both "c" and "linux" and add "posix" and "language-lawyer" instead. It's not really a C question nor is it really specific to Linux. – zwol Nov 22 '18 at 17:41
  • @gaazkam Based on the title, "Linux isn't 100% POSIX conformant..", and plus your comment, it looks like you're primarily interested in Linux and looking at man pages & POSIX spec to reinforce guarantees for the same. If this is not about Linux but solely about POSIX then edit the question as such (and the answer is simple "it's unspecified and no guarantees"). – P.P Nov 22 '18 at 17:54
  • "language-lawyer" except it isn't linked to any programming language, just to an OS specification... – curiousguy Nov 23 '18 at 08:11
  • Possible duplicate of [When you exit a C application, is the malloc-ed memory automatically freed?](https://stackoverflow.com/questions/2213627/when-you-exit-a-c-application-is-the-malloc-ed-memory-automatically-freed) – Jean-Baptiste Yunès Nov 24 '18 at 10:43
  • While suggested the duplicate does not mention Linux explicitly, it is well known that major modern OS free heap memory on termination (including Linux as a major OS). – Jean-Baptiste Yunès Nov 24 '18 at 10:45
  • @Jean-BaptisteYunès I don't think it's a dupe. My question explicitly asks for documentation / specification guarantees to confirm common knowledge (see the language lawyer tag?) The proposed dupe simply reiterates the common knowledge. –  Nov 24 '18 at 10:56
  • @zwol I appreciate your feedback, but could you please take a look at this? [How should my question about guarantees of freeing memory on program termination be tagged?](https://meta.stackoverflow.com/questions/377001/how-should-my-question-about-guarantees-of-freeing-memory-on-program-termination) –  Nov 24 '18 at 11:17
  • @usr Please see above. –  Nov 24 '18 at 11:17
  • @curiousguy Please see above. –  Nov 24 '18 at 11:17
  • it is just the inevitable outcome of how all modern demand-paged virtual memory operating systems work today. They create the illusion that a process has access to the entire available address space and can allocate memory where-ever it wants, considerably more than a machine actually has available. This virtualization ends when the process terminates. No more memory allocation, nothing could ever be leaked. It doesn't matter how the program ends either, works just as well when it suffers a fatal heart-attack and can't clean up by itself anymore. – Hans Passant Nov 24 '18 at 12:40

2 Answers2

7

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).

P.P
  • 117,907
  • 20
  • 175
  • 238
7

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.

zwol
  • 135,547
  • 38
  • 252
  • 361
  • The point about C is important: Standards are sometimes intentionally permissive, so this could really go either way. – alexis Nov 26 '18 at 08:18
  • @alexis Yes. C is intentionally permissive here. I don't think POSIX means to be, though. – zwol Nov 26 '18 at 12:07