Date:        Sun, 15 Sep 2019 19:42:06 +0000
    From:        David Holland <dholland-t...@netbsd.org>
    Message-ID:  <20190915194206.gb6...@netbsd.org>

  | There have been OSes in the past where memory not freed yet at process
  | exit is _not_ freed by the system, and there might be again,

Please everyone, let's retain some perspective.   Systems like those
(Roy mentioned RTEMS as an example) require specially constructed code,
as in a system where process termination doesn't free all the process's
resources, then what

Kamil Rytarowski <n...@gmx.com> said:
  | err(3) / abort(3) etc, are abnormal exit. Abnormal one differs from normal/ 
  | clean. For the same reason nobody registers a SIGFPU signal handler to free
  | resources.

doesn't apply, and processes need to clean up after themselves
evern when they abort.

If the system (whatever it is) can handle aborted processes without
suffering, but cannot handle cleanly exiting ones (which would be
bizarre, but never mind) then the simple solution for any process is
simply to always abort:
        err(0, "normal exit");

Also remember, that it is not only exit (via normal means, via an error
exit, or even killed by a signal) that requires cleanup, but exec() as
well.

That means, for example, that if you truly believe that a program should
free all of its resources before exiting, then you must also believe that
it must do the same before exec() (as the process is gone after that
happens, and nothing else knows what memory it has or where it was put)
which makes implementations of routines like popen() and system() kind
of interesting to imagine.

This is why the unix environment defines it as a system responsibiliy to
do that cleanup, not the process' and that's the model in which we program.

Expecting any unix program (even the simplest) to simply compile and run
in a non-kernel environment is pointless, they simply won't work.

I used to program such things in the past (distant past) - one of the
requirements of the particular system I was using was that processes
were not allowed to run for "too long" before calling the system process
switch function (no kernel running clock interrupts to do time slicing).

Do we want to make all of our processes able to run in an environment
like that as well?

  | In cases where it _is_ expensive, or at least where it's expensive to
  | figure out, the same argument applies as against garbage collection:
  | if you aren't sure what the lifetime of that object is, and the
  | program isn't structured in a way that allows being reasomably sure it
  | is disposed of exactly once, how can you have confidence in any other
  | correctness properties?

That isn't the issue at all - in the programs in question, there's no
issue with the lifetimes of objects, it is from creation until something
explicitly makes them go away, or process exit, whichever comes first.

Unlike garbage collection systems, there's no difficulty in finding the
allocated objects, the issue is that there are *lots* of them, in lots
of different data structures, all of which in the "free before exit" model
have to be freed - lots of data structure walking, and not just once, as
these programs fork() a lot, and those child processes inherit all the
allocated memory - it would have to be freed in every one of the children.

And all for no useful purpose, as the system does the free for us when the
process image is deleted.   And we rely upon that everywhere.

The one reason for doing this kind of free() is so that LSan type analysers
can look at memory and report anything that wasn't freed.

kre

Reply via email to