Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 29 Nov 2013 22:40:09 +0100
From:      Alex <alex@kaworu.ch>
To:        freebsd-pkg@freebsd.org
Subject:   [dev] about unchecked functions calls
Message-ID:  <529909B9.2050007@kaworu.ch>

next in thread | raw e-mail | index | archive | help
Hi list,

We do have currently several libc function calls that are completely
unchecked. Amongst them, the malloc(3) family calls are almost always
assumed to succeed and I am feeling uneasy about it.

To be honest, I've never experienced genuine ENOMEM as a programmer.
What makes me uneasy is that I personally think that when writting C,
one has to take a stand on some question like "what do I do if malloc(3)
ever fail?". UNIX as a strong tradition about robust C programming and
we should embrace it.

About solutions, the alternatives I have in mind are:

1. assume that ENOMEM is fatal. We just abort() as soon as we see it. In
that case we should have some kind of xmalloc(3) & Co. and use them
consistently accross all the project. On the pros side it's very easy to
do, on the cons it could leave the system in a unclean state (half done
install / uninstall, corrupted pkg database etc.).

2. assume that pkg should fail gracefully when ENOMEM occurs. In general
it is considered bad design for a library to abort() (in any case) and
so if part of pkg can be considered as a library (like libpkg suggest by
its name) then maybe this is the Right Thing™ to do. Basically, it means
that functions considered part of the library would return an error code
(EPKG_FATAL) while other "higher part" would gracefully cleanup and exit
(using for example err(3)). On the pros side we would have a more robust
application, a more reliable library and a cleaner codebase. On the cons
side it is hard to achieve and time consuming.

To me, (1) is better that what we do now (i.e. nothing) and (2) is
better than (1). Obviously, (1) can be achieved easily while (2) is a
long process.

I've been playing Coccinelle[1] on the pkg codebase recently (long story
short: Coccinelle is a matching and transformation engine for C). What
is relevant to know is that Coccinelle is a great tool to achieve (1),
and that I am willing to integrate it. In other words we have a way to
step quickly to (1). My proposition is to use Coccinelle in order to
step to a first goal (1) and achieve (2) as a second, long-term and
shared goal. If at anytime (2) seems unreasonable, we can still drop it
and fallback to (1).

It is much more a change of mindset than a change in the code. It's
about writting cleaner, hopefully more robust code. I think that the two
steps could (and should) also be applied for other other calls like
strlcpy(3). However, in order to succeed cooperation is required at
every levels (all the contributors should try to comply to it and
commiters should enforce it). Therefore comments and inputs are welcome,
in particular from current active pkg commiters.

Regards,
Alex.

[1]: http://coccinelle.lip6.fr/



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?529909B9.2050007>