Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 22 Sep 2004 05:07:13 +0900
From:      JINMEI Tatuya / =?ISO-2022-JP?B?GyRCP0BMQEMjOkgbKEI=?= <jinmei@isl.rdc.toshiba.co.jp>
To:        netch@lucky.net
Cc:        Thomas Quinot <thomas@freebsd.org>
Subject:   Re: freeaddrinfo(NULL)
Message-ID:  <y7vfz5bgzda.wl@ocean.jinmei.org>
In-Reply-To: <20040921190717.GG84228@lucky.net>
References:  <20040921123016.GA41677@melusine.cuivre.fr.eu.org> <y7visa7h2ki.wl@ocean.jinmei.org> <20040921190717.GG84228@lucky.net>

next in thread | previous in thread | raw e-mail | index | archive | help
>>>>> On Tue, 21 Sep 2004 22:07:17 +0300, 
>>>>> Valentin Nechayev <netch@lucky.net> said:

>> As Umemoto-san said, if we made freeaddrinfo(NULL) "safe", the
>> application programmers might tend to rely on the "safety net" and
>> the uncareful coding style.  This can be worse than the segfault here,

> Let you try to apply the same arguments to free() and you'll see nonsense.
> If free(NULL) is freely allowed, what's the problem with freeaddrinfo()?

One major problem is that the result when we pass NULL to freeaddrinfo
is not documented, while C90 (if I understand it correctly) explicitly
says the result is no-op.  In my preference (note that I admit this is
a controversial issue), I'd say the decision of C90 about free(NULL)
is also bad, but I can live with it since the standard is clear on
this.

>> because the reason for the NULL argument might be a bug in the
>> program, and, as a result of hiding the bug by making

> NULL was specially designed by C authors as special value, "no valid pointer
> here". One may wrap anything with "if(p) freeaddrinfo(p);", but this
> has no deep sense and leads only to style flames.

>> freeaddrinfo(NULL) "safe", it might cause much more serious effects
>> later in the program.

> What effects? Why they doesn't appear with another pointer?

I was not talking about things like whether NULL had been specially
designed or not.  I was basically talking about any invalid argument
to freeaddrinfo.  More specifically, I was talking about the following
type of coding:

foo(addrinfo)
	struct *addrinfo; /* this should be non NULL */
{
	....

	freeaddrinfo(addrinfo);

	...
}

Here the programmer imposes an assumption that addrinfo is non NULL
(or is valid for freeaddrinfo).  It's the caller's responsibility to
ensure that this is a valid pointer.  But consider the case where the
caller-side code has a bug and passes a NULL pointer to foo().  If
freeaddrinfo(NULL) segfaults, we found the bug at this point.  If
freeaddrinfo(NULL) does no-op, the latter part of the function is
executed whereas the assumption isn't met.  This may or may not
cause a bad effect.  But the real point of the bug that led to the
NULL argument is hidden, which may cause another serious problem in
some other part of the code.

Of course, a careful programmer would always check the assumption
somewhere in the function foo() (probably at the head of the
function), regardless of the behavior of freeaddrinfo(NULL).  This is
desirable.  However, I can easily imagine that a lazy programmer will
tend to omit the check if freeaddrinfo(NULL) does no-op, since the
function itself seems to work without a problem whereas it actually
just hides a bug.

I admit the scenario is not so specific and some others may think it's
not so convincing.  I basically talk about a general practice (which I
personally believe) that it's always better to catch an error than to
ignore it and the sooner is the better.

>> In my understanding, this kind of discussion has always been
>> controversial; whether we want to make more explicit errors (even if
>> those are segfaults), or whether we want to "spoil" bad programmers by
>> making the library interface "safe".

> Segfaulting on NULL makes nothing more safe.

This statement is too short to tell if it's valid, but I believe
Segfaulting on freeaddrinfo(NULL) can make something safer for the
reason I described above.  That is, catching a bug earlier *can*
make a safer result.

Again, note that I admit this is a controversial issue.  Regarding
whether we should change FreeBSD's implementation of freeaddrinfo() so
that it does no-op against NULL, I won't strongly oppose to that if
the vast majority supports the idea.  However, since the API
specification is silent on this, I'd then request that the man page
make an explicit note that the application programmer should be check
if the argument to freeaddrinfo() is valid because passing a NULL
pointer may cause an unexpected result, including segfaulting, on
other systems.

					JINMEI, Tatuya
					Communication Platform Lab.
					Corporate R&D Center, Toshiba Corp.
					jinmei@isl.rdc.toshiba.co.jp



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