Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Date: Thu, 5 Mar 2015 16:38:55 -0500
From: Rich Felker <dalias@...c.org>
To: musl@...ts.openwall.com
Subject: Re: MUSL Feature Detection

On Thu, Mar 05, 2015 at 01:02:18PM -0800, William Ahern wrote:
> I understand and basically agree with the arguments against defining a
> version macro or symbol. I don't think anybody disagrees with the argument
> that feature detection is the preferable route. It's just not sufficient.
> 
> The kind of feature detection I had in mind isn't simply whether or not a
> specific API is provided. That can be accomplished pretty easily with
> autoconf. I probably wasn't sufficiently clear on that in the beginning.

My position is that detection is the right approach for presence of
interfaces but not for behaviors. For the latter it precludes
cross-compiling and also fails to deal with behavioral differences
that vary by run-time environment (e.g. kernel version, which affects
even static linking).

> But some implementation-defined behaviors are impractical or impossible to
> programmatically determine. Most obvious in this case is thread-safety.
> Theoretically you could implement a test to determine whether shared buffers
> are used, but knowing that doesn't 100% resolve the question, because there
> could be other thread-safety issues. Or maybe the implementation conditions
> shared buffer use on something else, like initializing locale support.

As an example where it doesn't work, you could always build a public
interface that _appears_ thread-safe on a non-thread-safe backend by
interning the results (thus never reusing buffers). This would be
fully thread-safe as long as ony the public interface is used
(assuming it has proper locking), but fails horribly if the backend is
externally callable without the lock being held.

As an aside, this exact issue is _why_ POSIX is so extreme in its
definition of non-thread-safe: non-thread-safe functions cannot be
called concurrently with ANY standard function, even unrelated
thread-safe ones, without invoking UB. This basically means their use
is completely forbidden in multi-threaded programs (since there is no
way to preclude concurrency short of spinning on an atomic).

As an example, as far as I can tell, POSIX allows implementing
getpwnam_r or localtime_r as a wrapper around getpwnam or localtime
that holds a lock while calling the underlying non-thread-safe
function and copying its result to a caller-provided buffer.

> Implementations usually document the choices they make when a standard
> interface provides them an option. But that is typically done in
> human-readable documentation.
> 
> I've been trying to curate a small database (unstructured) of thread-safety
> and other portability issues by analyzing libc source code and
> documentation, but in the case of musl I can't query my database because I
> can't know whether musl is being used, let alone the version. Except,
> perhaps, by process of elimination, or inspecting the toolchain directly.
> 
> I suppose my next step should be to try to turn by collected information on
> portability problems into a structured database of some sort. Then that
> would be a starting point for discussing the possiblity of defining a libc
> API that communicates features and semantics.

I think that sounds reasonable.

Rich

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.