error()/error_at_line() and threads
enh
enh@google.com
Thu Jun 11 16:15:03 GMT 2026
what's the behavior of <error.h> functions called from more than one
thread supposed to be? bionic has its own implementation of this api
(for source portability but also because i personally find it so much
easier to read/remember than the bsd <err.h> stuff) and i was recently
asked why there's no locking.
afaict the glibc implementation _does_ fsetlock() the stream, but
_does not_ guard access to globals, including most notably
error_message_count.
the glibc manual says:
Function: void error (int status, int errnum, const char *format, …)
Preliminary: | MT-Safe locale | AS-Unsafe corrupt heap i18n | AC-Safe
| See POSIX Safety Concepts.
Function: void error_at_line (int status, int errnum, const char
*fname, unsigned int lineno, const char *format, …)
Preliminary: | MT-Unsafe race:error_at_line/error_one_per_line locale
| AS-Unsafe corrupt heap i18n | AC-Unsafe corrupt/error_one_per_line |
See POSIX Safety Concepts.
the man page further has the rather over-optimistic:
The internal error_one_per_line variable is accessed (without any
form of synchronization, but since it's an int used once, it
should be safe enough), and if error_one_per_line is set nonzero,
the internal static variables (not exposed to users) used to hold
the last printed filename and line number are accessed and
modified without synchronization; the update is not atomic and it
occurs before disabling cancelation, so it can be interrupted only
after one of the two variables is modified. After that,
error_at_line() is very much like error().
but neither say anything about error_message_count. a quick test
program shows that, as you'd expect, some increments get lost in the
presence of many threads.
i'm guessing no-one's ever noticed or cared because <error.h> is
mostly useful for command-line programs and they tend not to use
threads (and even when they do, are likely to leave error reporting to
the main thread).
thoughts? "WAI but the documentation could be improved"? "yeah, it
doesn't really matter, but let's just add the obvious lock to
error()/error_at_line()"?
i'm torn myself, so i'm leaning towards "i'll care exactly as much as
glibc choose to do" :-)
More information about the Libc-alpha
mailing list