Bug 8029

Summary: errno_location() problems in constructor functions
Product: [Retired] Red Hat Linux Reporter: marcushall
Component: glibcAssignee: Jakub Jelinek <jakub>
Status: CLOSED CURRENTRELEASE QA Contact:
Severity: medium Docs Contact:
Priority: medium    
Version: 6.1   
Target Milestone: ---   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2000-05-22 14:53:19 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description marcushall 1999-12-28 22:53:50 UTC
When creating constructor functions (at least within a shared library, not
sure about within a mainline program), that is, a function with an
attribute "constructor", the order of constructor execution is
undetermined.  This causes a problem if you link with the pthread library
and perform any significant action within another constructor.  The
pthread library's pthread_initialize() function initializes the initial
thread's struct _ptheread_descr_struct.p_errnop member to point to _errno,
but if your constructor runs before pthread_initialize, then it is still
at its default initial value of NULL.

This causes probelems if your constructor makes a system call that fails
and attempts to set errno, or calls any of the printf family, or probably
other functions that touch errno.

I think that this could be easily fixed if the initializer for
__pthread_initial_thread specified &_errno for p_errnop (and &_h_errno
for p_h_errnop) instead of NULL.  I don't see any reason that it
needs to be initialized to NULL.

A way to produce the problem is:
static void myfunc() __attribute__((constructor));
static void myfunc() {
	printf("hello");
}

Build this into a shared library.  Build another process that links
with this library and the pthread library.  If myfunc() runs before
pthread_initialize(), then the printf() will try to touch errno and
will cause a segmentation violation.

Comment 1 Cristian Gafton 2000-05-22 14:53:59 UTC
assign to jakub

Comment 2 Jakub Jelinek 2000-12-19 18:11:17 UTC
This is fixed in glibc-2.1.92-14 and above.