[pulseaudio-tickets] [PulseAudio] #158: possibly dangerous use of exit() in a shared library?
PulseAudio
trac-noreply at tango.0pointer.de
Fri Nov 16 08:13:31 PST 2007
#158: possibly dangerous use of exit() in a shared library?
-----------------------+----------------------------------------------------
Reporter: pmasiar | Owner: lennart
Type: defect | Status: closed
Priority: low | Milestone:
Component: libpulse | Severity: minor
Resolution: invalid | Keywords:
-----------------------+----------------------------------------------------
Changes (by lennart):
* status: new => closed
* resolution: => invalid
Comment:
Uh. The guy who posted that obviously has not much clue about writing
software or about memory management.
There are three kinds of software. That which handles OOM gracefully and
is carefully debugged to make sure it continues to run -- but with
graceful degradation if no memory is available anymore. Then, there is
software that aborts on OOM. That's almost any free desktop software,
especially the one written using libraries like GLib/Gnome which uses
aborting malloc() almost exclusively (and Qt does it much the same way).
And finally there's the software which uses plain malloc() but ignores
errors and segfaults on OOM. Unfortunately the latter style of programming
is one of the most popular. Now, clueful programmers know about these
issues and carefully choose in which of the first two styles to program.
For system programs like init, dbus and suchlike clueful programmers
usually choose the first style, for desktop programs, and other not
crucial components they choose aborting malloc(). Why? First, because it
is much easier to program with. And second, because it doesn't hide or
abritrarily escalate errors.
Also note that due to overcommiting on Linux OOM errors are generally not
handled by malloc() returning NULL, but by killing processes via the OOM
killer. So spending much time thinking about handling malloc() returning
NULL is generally a waste of it. It just doesn't happen, unless you
disable overcommit, or you enforce resource limits. Disabling overcommit
is only useful on some very specific (usually embedded) applications. It's
mostly paranoia. So in effect, aborting if malloc() returns NULL just
makes all situations of OOM behave identically.
Programs should be optimized to not lose any data if they crash. Every
non-trivial program has bugs, and thus the priority should be to make them
not lose any data in the worst of the cases. And thus, in many cases a
clean abort on OOM is the better choice then continuing with half
completed operations -- just for the sake of the consistency of the data
stored on disk.
So, to be frank: I think that most of the software I wrote makes the right
choices with handling OOM. In Avahi, the daemon uses aborting malloc(),
because network service discovery is clearly not a crucial part of the
system. So if we get into OOM we should be killed -- as one of the first
processes -- to free up memory for more imporant processes. However, the
Avahi client libraries are carefully programmed to deal with malloc()
returning NULL. Why? Because they are used in quite a bit of system-level
software where an aborting malloc would not be a good thing. For the PA
case, I chose to always use aborting malloc. Why? Because audio *never*
is a crucial component of the system. If audio crashes due to what reason
whatsoever all you lose is that your music stops to play -- but no data is
lost. And thus, audio software should be the first one to be killed, too.
A lot of unix software defines a wrapper to malloc() which is called
xmalloc(), which implements the aborting malloc. It's one of the moston
common idioms in C programs on Unix.
Oh, and the the guy is asking why so many systems define their own
malloc() wrapper? Precisely to implement an aborting malloc(). And also
for portability reasons, i.e. some systems abort on malloc(0), others
return NULL, others return a single constant but valid pointer and even
others actually allocate a zero-length memory block.
Also note, that PA doesn't call exit(). It calls _exit() which is a small
difference.
Quoting from his post:
"crummy, amateurish programming". I like that. I wonder what kind of
really important, really safe software that "j_g" guy ever wrote. I
certainly haven't heard of it.
I hope he doesn't really use Ubuntu, because most of the software running
on Ubuntu desktops uses an aborting malloc(), by using GLib. And thus must
be "crummy, amateurish".
"And anyone who makes such a shared library a part of his operating
system should be shot dead, and then stabbed through the heart with a
stake just to make sure he's really dead."
Yes, that's constructive. Tell j_g I love him too. Even though he's a
clueless FUD-spreading fool.
"God help us if this pulse audio thing is ever chosen to replace ALSA in
the kernel. This will make Linux stability and reliability go to hell if
you have operating system calls terminating apps at will."
Hehe. it's getting better. PA does not live in kernel space and doesn't
replace ALSA in any way. It sits on top of ALSA. I am not sure what kind
of illusions that guy has about the Linux kernel and the general code
quality of Linux.
Oh, you wanna know something? Even ALSA doesn't properly check the return
values of all malloc()s. Oh! My! God! Hell is freezing over! Heaven's
sake!
I am sorry, I am no going to sign up to some random ubuntu forum, just to
reply to some clueless fool. However, feel free to link or copy my reply
into that forum.
--
Ticket URL: <http://pulseaudio.org/ticket/158#comment:1>
PulseAudio <http://pulseaudio.org/>
The PulseAudio Sound Server
More information about the pulseaudio-bugs
mailing list