This is the mail archive of the
mailing list for the glibc project.
[Bug nss/19341] statically linked multi-threaded program fails to initialize ctype info in existing threads
- From: "carlos at redhat dot com" <sourceware-bugzilla at sourceware dot org>
- To: glibc-bugs at sourceware dot org
- Date: Mon, 07 Dec 2015 19:26:17 +0000
- Subject: [Bug nss/19341] statically linked multi-threaded program fails to initialize ctype info in existing threads
- Auto-submitted: auto-generated
- References: <bug-19341-131 at http dot sourceware dot org/bugzilla/>
Carlos O'Donell <carlos at redhat dot com> changed:
What |Removed |Added
CC| |carlos at redhat dot com
--- Comment #1 from Carlos O'Donell <carlos at redhat dot com> ---
(In reply to Ian Lance Taylor from comment #0)
> This glibc bug report is extracted from https://golang.org/issue/13470.
> If you statically link the following C program and run it on Ubuntu Wily,
> which uses glibc 2.21, it will crash.
> I believe that the problem is that the ctype code relies on TLS variables
> initialized by __ctype_init. The getpwuid_r function in a statically linked
> program relies on opening a supporting shared library. The supporting
> shared library can not see the ctype information in the statically linked
> executable, which has no dynamic symbol table, and therefore has its own
> copy. That copy is correctly initialized by a call to __ctype_init.
> However, if there are any existing threads, the shared library copy of the
> TLS ctype information is never initialized. So, if the program manages to
> call getpwuid_r on a thread that existed when the shared library was opened,
> it crashes.
We first noticed this at Red Hat with the docker self tests in September.
Incarnations of this bug have been around for a long time and they have been
closed by the previous community as unsupported. The current community is
committed to supporting some kind of static linking, but with caveats and good
documentation about the limits of static linking.
Your analysis is correct (I did the same debugging myself), and I've had a fix
for this internally at Red Hat for a while. You just switch the ctype
initialization to an init-at-first-use pattern, but that doesn't solve all the
problems. You get even more breakage further on from other global state
variables which are not shared. The first one is __libc_multiple_threads, which
in the dynamic shared "namespace" is zero because no threads were created in
that namespace. It causes the dynamic namespace to avoid doing any locking
because it doesn't think there are any threads active (but there are). This
leads to race conditions in malloc and lots of problems.
We've been looking at this internally at Red Hat on-and-off for the last couple
of months. There is no easy solution. You have the same problem with errno, and
all other global state variables that need to be shared between the static
"namespace" and the dynamic "namespace." In fact I've been pondering a similar
problem for the extensions to dlmopen that I'm working on which would allow
alternate namespaces to atleast operate sensibly.
Either way there is going to be quit a bit of work required to fix this and it
won't get fixed soon. We'll need some kind of collected shared global state we
can pass to the new namespace which allows the implementation to behave
The conclusion at Red Hat was to continue to investigate the issue upstream,
but that Docker would move to a non-static linkage, and that any statically
linked applications would be very very small and not likely to use any of the
features which trigger this problem.
I don't know if that's the answer you wanted to hear, but there it is. I'm
moving this bug to SUSPENDED until someone steps up to work on the issue. I
won't get to this for a while, but I'm happy to review patches or give
technical guidance on proposed solutions.
You are receiving this mail because:
You are on the CC list for the bug.