This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: ctermid: return string literal, document MT-Safety pitfall
- From: Torvald Riegel <triegel at redhat dot com>
- To: Florian Weimer <fweimer at redhat dot com>
- Cc: Alexandre Oliva <aoliva at redhat dot com>, libc-alpha at sourceware dot org
- Date: Fri, 14 Nov 2014 14:28:01 +0100
- Subject: Re: ctermid: return string literal, document MT-Safety pitfall
- Authentication-results: sourceware.org; auth=none
- References: <ortx2b8l2k dot fsf at free dot home> <54620F80 dot 3030001 at redhat dot com> <ortx22ak52 dot fsf at free dot home> <5465EF19 dot 5040802 at redhat dot com>
On Fri, 2014-11-14 at 13:01 +0100, Florian Weimer wrote:
> On 11/13/2014 10:03 PM, Alexandre Oliva wrote:
> > On Nov 11, 2014, Florian Weimer <fweimer@redhat.com> wrote:
> >
> >> On 11/07/2014 09:35 AM, Alexandre Oliva wrote:
> >>> This was based on an interpretation that strcpy (and memcpy, and
> >>> compiler-inlined versions thereof) could not write garbage in the
> >>> destination before writing the intended values, because this would be a
> >>> deviation from the specification, and it could be observed by an
> >>> asynchronous signal handler.
> >
> >> Which specification do you mean? glibc or the C standard?
> >
> > I meant standard C.
>
> I've been staring at the standard for a while. The standard explicitly
> refuses to deal with the interaction of signal handlers and threads
> (7.14.1.1/7, âUse of this function in a multi-threaded program results
> in undefined behavior.â).
At least in ISO C++, what a signal handler can do is still being
discussed. There's sig_atomic_t and the lock-free atomic ops that are
safe, and at least C++ wants some ordering guarantee wrt. to the
installation of the signal handler and an executing signal handler.
AFAIU from the ISO C++ discussions, the same discussion is happening
among ISO C committee members.
> However, the standard still required that lock-free atomic objects have
> values which are not unspecified. But as far as I can tell, the
> standard does not explicitly sequence operations on atomic objects,
What do you mean by "to sequence"? The sequenced-before relation can
include atomic operations, and atomic operations will be part of
happens-before.
> so
> the normal sequencing rules apply, and they fail to specify a value, so
> the value is still effectively unspecified, and library functions such
> as memcpy and memset can write ghost values, or can be implemented with
> one-char-at-a-time loops, and there is no way to observe that.
>
> This (the ânot unspecified but not specified eitherâ state) seems to be
> a defect in the standard. I very much doubt the intent was invalidate
> existing implementations which write ghost values, such as the
> Solaris/SPARC memset implementation:
>
> <https://bugs.openjdk.java.net/browse/JDK-6948537>
>
I agree that what happens during the execution of non-concurrent
functions is unspecified, and that the as-if rule applies. For a
sequential specification of a function, one has a precondition and a
postcondition -- but how to reach a state satisfying the postcondition
is left to the implementation. memset is allowed to change one bit at a
time, in any order. Wanting anything else would require specifying the
actual implementation, which the standard doesn't do; it might be easy
to assume that many implementations of a very simple function like
memset would behave in a certain way -- but this already breaks down
with more complex functions such as qsort (which intermediate states are
actually allowed? can it use the to-be-sorted array as scratch space?).
Also, making assumptions about intermediate states kills the as-if rule,
hampering compiler optimizations.
If we want to reason about states during the execution of a function,
there must be some way to observe that, and the observation will be
concurrent with the execution of the function. Thus, we need a
concurrent specification not just a sequential one, which describes the
possible outcomes when combining the function and something concurrently
running.