[Top][All Lists]

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

gnulib and threaded execution

From: Ralf Wildenhues
Subject: gnulib and threaded execution
Date: Thu, 2 Dec 2010 22:47:30 +0100
User-agent: Mutt/1.5.20 (2010-08-04)

The recent coreutils sort bug related to threading made me take a look
at gnulib for similar issues.  When you try to use gnulib in threaded
code, any process-global state can potentially cause problems, whether
that be static data, file descriptor state, current directory, umask,
etc.  For a lot of these data and in a lot of the cases, gnulib is safe.
Still, it might make sense to make an effort to document exceptions to
this rule: users might not even be aware that three levels down the
module dependency tree, they are using something potentially unsafe.

I egrepped for '([       ]static |static [^()]*;)' (TAB inside) and
among the first few hits (of a few hundred) I found these issues:

* Unless STACK_DIRECTION is defined, gnulib/lib/alloca.c sets and uses
STACK_DIR and find_stack_direction:addr in the first alloca call.  When
that first call is from threads, and racing with another one, the value
for STACK_DIRECTION may be computed wrongly, and the code may corrupt
the stack.

This is an issue only when the compiler/libc doesn't provide it, and
even then, the race seems unlikely to be won, so it's not surprising we
haven't seen a report.  Still, this particular issue could be fixed by
computing STACK_DIRECTION from configure iff we choose to compile

* error_at_line.c has a function-static old_file_name, such that if
error_at_line is called concurrently with a status of 0, the global
error_one_per_line is set to nonzero, and one of the calls passes NULL
as file_name, then NULL may be passed to strcmp in the other thread, if
the race is won.  Less severely, the old_line_number static could cause
the wrong number to be compared, and since it's an int rather than a
sig_atomic_t, in theory it could even contain an inconsistent value at

Arguably, this use case is pretty contrived, since calling error_at_line
concurrently doesn't mesh with wanting only one error per line, but
IMVHO it makes sense to at least document the requirement for the caller

* in getloadavg.c, getloadavg_initialized should probably be a
sig_atomic_t not a bool (no idea whether this can ever be a problem in

* register_close_hook is not thread-safe.  Doesn't seem a big issue at
first, it's called only from gl_sockets_startup, but there is no hint
attached to the latter function about not being callable from a threaded

I'm sure a number of other issues are lurking there.  The increased use
of LTO (link-time optimization) will surely over time expose more of
these issues (also things like missing volatile) due to the compiler
being able to optimize much more aggressively.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]