Re: Differences between man-pages and libc manual safety markings

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, 2014-11-03 at 03:43 -0200, Alexandre Oliva wrote:
> On Nov  1, 2014, Torvald Riegel <triegel@xxxxxxxxxx> wrote:
> 
> >> The information is all there: there's a static shared buffer (as
> >> required by ctermid(NULL), and that's usually not thread-safe, but
> >> that's tacit knowledge of our time not explicitly duplicated there),
> 
> > Wow, really?  It supposed to be "tacit knowledge of our time" to not
> > have thread-safe initialization of a static buffer?
> 
> You seem to have misread what I wrote.  It's the fact that ctermid(NULL)
> is not required to be thread-safe that is tacit knowledge of our time.

I don't find that interpretation any less surprising.  So, again, why is
that "tacit knowledge of our time"?

> > "but the internal buffer is always set
> > to /dev/tty" makes it obvious that there's a data race?
> 
> The reasoning indicates there's something non-obvious going on there.
> When there isn't, there's no reason for any such note.

So, the note says that an internal buffer is used if NULL is returned,
but this buffer is always set to /dev/tty.  Why does that indicate that
there's a race, or that ctermid(NULL) is not MT-Safe, different from the
actual annotation you added?

> > Maybe we should make a poll on libc-alpha to see which percentage of
> > people actually understands this comment as implying that there is a
> > data race.
> 
> Will you please stop putting words I didn't say in my mouth?

That's the way I understood your comment but ...

> Where did I say the comment meant to imply that there was a data race in
> there?
> 
> All it was meant to do was justify why I regarded the function as
> MT-Safe and AS-Safe, in spite of the possibility of concurrent
> initializations of the buffer.

... we can as well make a poll about this reasoning of yours above.

> > Also note that "your wishes" isn't what this is about -- it is about
> > maintainable documentation.  This affects glibc in general.
> 
> That's still your wishes for additional documentation that nobody has
> stepped up to do.  Others (myself included) may share such a wish for
> better documentation on various fronts, but none of this would entitle
> you to demand me to do so, or to complain that I didn't, when I never
> agreed to do it.

Yeah, you never promised me to create maintainable documentation.  So I
can't demand it.  I just thought that this would be common sense, and as
here, it's actually not a lot of work.  You'd have had to just write
another sentence, or say
  @ data race on initialization of static buffer
or
  @ buffer initialized by running strcpy potentially concurrently

or really something like that.

Sorry if I've asked for something outrageous here...

> > 1) Do the loads use an acquire fence (ie, atomic_read_barrier)?
> 
> No.
> 
> > If not, is any new locale data they can read from initialized before
> > those reads (e.g., at program startup, so happening before any spawned
> > threads)?
> 
> No

Then this sounds like a bug that could trigger an error on archs with
weak HW memory models.

And to be clear, I'd never asked you to fix it, but I would have
appreciated if you gave me (or other glibc folks) a heads-up that
something might be fishy here, so *somebody* (not you, don't worry) can
revisit it later on.

I guess nobody specifically asked you to report potential bugs you've
found during the review for MT-Safety.  It would have just been better
if you did note them...

> > 2) If the compiler sees such a load (e.g., because it's a macro, or with
> > LTO and inlining), and it's not marked as an atomic access, it can be
> > free to reload it.  Which could lead to partially reading from the old
> > and new locale.
> 
> Yes, but only if there's more than one use (thus marked locale).  If
> there's only one use, the compiler could, but would not do something
> that stupid.

Register pressure?

Whenever you say "something that stupid", it should have a very simple
reason.  So if you can't give a one-sentence reply why reload would be
"that stupid", then maybe you're wrong, huh?

> >> Some functions access ctype data multiple times; given the above, and
> >> because the locale structures are accessed in a way that enable the
> >> compiler to load the global locale pointer only once, and the compiler
> >> performs this optimization
> 
> > So correctness applies in some cases on certain, optional compiler
> > optimizations to be performed?
> 
> That is glibc's locale design, yes.  Sane compilers help keep glibc sane
> and safe.  We are indeed relying on compiler sanity.

Sanity is not defined by adhering to the hacks you have in mind but by
adhering to the standards and following the conventions that all the
involved projects have agreed on.  Should we make a poll with the gcc
folks to see how many would agree reloading a nonatomic / non-shared mem
location would be insane?

> > Then please refer me to the concrete old standard (and we should support
> > it, actually) and the wording in there that *requires* strcpy to issue a
> > certain set of stores instead of just, for example, requiring that when
> > the function returns, the string has been copied.
> 
> These are equivalent requirements IMHO, because neither makes other
> allowances for using the user-visible storage as scratch space, and
> both, because of asynchronous signals, rule this possibility out for
> storage that the signal handler could observe.  Anyway, let's leave this
> point for the other sub-thread, to avoid duplication, shall we?

Fine, let's continue there...

> > Second, when you've done that, could you please explain to me how a
> > compiler is supposed to optimize code without something like an as-if
> > rule?
> 
> The key is external observability, and ordering requirements.
> 
> strcpy's sequential specification does not mandate chars to be copied in
> any predetermined order,

But it's not explicitly allowed either.  This contradicts with what you
said above.  Please make a consistent argument.  Otherwise, I'll reply:

strcpy's sequential specification does not mandata chars to be copied
atomically, so we can copy by adding 1 to each char until it reaches the
final value.

> so strcpy is free to reorder and regroup loads
> and stores as it sees fit.  None of this steps out of its explicit
> specification.  Writing garbage, however, would step out, but it might
> still be allowed under the as-if rule if this couldn't be legitimately
> observed, e.g. if any attempt to observe it would invoke undefined
> behavior.

If that is how you interpret the language standard, then please tell me
why we need volatile.  Seriously.

> >> and the
> >> no-data-races mandate.
> 
> > For there to be data races, the standard must actually acknowledge that
> > things are supposed to work in a multi-threaded setting.  Could you
> > refer me to the respective wording too, please?
> 
> Why are you doing this?  You know where this requirement is in POSIX!
> 
> For a long time we have had threads as a POSIX add-on to C standards
> that said nothing about threads.  POSIX imports (defers to) standard C
> without conflicting with it.  It logically follows from these two
> statements that all requirements from standard C on strcpy
> implementations still apply under POSIX.  If you agree that a signal
> handlers' ability to observe deviations from standard-mandated behavior

The question is still what standard-mandated behavior is.  Which you
don't constrain by bringing in POSIX.

> indicate deviation from the standard, rather than something that could
> be tolerated under the as-if rule, then this strcpy requirement carries
> over to the multi-thread extensions to C specified in POSIX.

Also, think about the compiler example with strcpy being replaced by the
compiler, that *you* brought up.  Do you think the compiler agrees with,
or is at least aware of your opinion, that it has to make strcpy
volatile because POSIX uses C and you interpret it to mean that every
handler can peek into intermediate state and find something that you
think makes sense?


A side note: We can keep discussing this, but I can't imagine any
further additional reasons you could bring up why either the ctermid
MT-Safety annotation is incomplete or the glibc implementation of
ctermid is wrong.  In this discussion, you and I disagree, and Mark
seems to disagree with your reasoning as well.  Maybe you should get
other opinions, or just agree that maybe your reasoning might not be as
fault-free as it may seem.

A second side note:  When us three here are discussing this for ages,
then obviously, your MT-Safety note on ctermid is NOT easy to
understand.  There should be absolutely no discussion that something
needs to change.
If any of our documentation leads to at least some disagreement between
glibc contributors, it's not clear enough.  Period.



--
To unsubscribe from this list: send the line "unsubscribe linux-man" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Kernel Documentation]     [Netdev]     [Linux Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux