Subject: pkg/7433: pthread_init() not called
To: None <gnats-bugs@gnats.netbsd.org>
From: Andreas Gustafsson <gson@araneus.fi>
List: netbsd-bugs
Date: 04/21/1999 06:35:54
>Number: 7433
>Category: pkg
>Synopsis: pthread_init() not called
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: pkg-manager (NetBSD software packages system manager)
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Wed Apr 21 06:35:00 1999
>Last-Modified:
>Originator: Andreas Gustafsson
>Organization:
Araneus Information Systems Oy
>Release: 1.3.2
>Environment:
System: NetBSD guava.araneus.fi 1.3.2 NetBSD 1.3.2 (GUAVA) #0: Wed Feb 17 10:21:50 EET 1999 gson@guava.araneus.fi:/z/src-1.3/sys/arch/i386/compile/GUAVA i386
>Description:
When linking a C program with the pthreads shared library from the
devel/mit-pthreads package, pthread_init() is not called automatically
on startup like it is supposed to. The typical symptom of this is
that the first call to a library function using thread-specific data
leads to a core dump in pthread_getspecific().
This problem occurs on the i386, and presumably also on other
platforms using the a.out object format. It does not occur
with static linking.
The call to pthread_init() is supposed to happen by means of the C++
static constructor mechanism, but this fails on a.out platforms unless
the shared library is explicitly linked with /usr/lib/c++rt0.o as the
first object on the ld command line.
>How-To-Repeat:
$ cat test.c
#include <stdio.h>
#include <time.h>
int main(int argc, char **argv)
{
time_t now;
struct tm *tm;
time(&now);
tm = localtime(&now);
}
$ /usr/pkg/pthreads/bin/pgcc test.c
$ a.out
Segmentation fault (core dumped)
$ /usr/pkg/pthreads/bin/pgcc -static test.c
$ a.out
$
>Fix:
Depends on the NetBSD version. On NetBSD-current, add the following
patch to the /usr/pkgsrc/devel/mit-pthreads/patches directory:
--- config/Makefile.in.orig Wed Apr 21 14:11:42 1999
+++ config/Makefile.in Wed Apr 21 14:47:05 1999
@@ -41,6 +41,10 @@
.include <bsd.lib.mk>
+.if (${OBJECT_FMT} == "a.out")
+SHLIB_LDSTARTFILE = /usr/lib/c++rt0.o
+.endif
+
$(OBJS) : $(config) $(types) $(paths)
Makefile: ${srcdir}/config/Makefile.in
On 1.3.2/1.3.3, a more elaborate patch is needed because <bsd.lib.mk>
does not expand SHLIB_LDSTARTFILE on the a.out ld command line. The
following patch achieves the desired effect by duplicating some code
from bsd.lib.mk in the Makefile. It has only been tested on 1.3.2.
--- config/Makefile.in.orig Wed Apr 21 12:14:21 1999
+++ config/Makefile.in Wed Apr 21 16:01:07 1999
@@ -39,6 +39,25 @@
.include "${srcdir}/net/Makefile.inc"
.include "${srcdir}/scripts/Makefile.inc"
+# On a.out platforms, override the shared library linking rule to
+# link with c++rt0.o so that pthread_init() gets called.
+# On -current we could just set SHLIB_LDSTARTFILE=/usr/lib/c++rt0.o,
+# but the SHLIB_LDSTARTFILE macro is not expanded on the a.out linker
+# command line in 1.3.2 or 1.3.3.
+
+.if (${MACHINE_ARCH} != "alpha" && ${MACHINE_ARCH} != "mips")
+
+SHLIB_MAJOR != . ${.CURDIR}/shlib_version ; echo $$major
+SHLIB_MINOR != . ${.CURDIR}/shlib_version ; echo $$minor
+
+lib${LIB}.so.${SHLIB_MAJOR}.${SHLIB_MINOR}: lib${LIB}_pic.a ${DPADD}
+ @echo building shared ${LIB} library \(version ${SHLIB_MAJOR}.${SHLIB_MINOR}\)
+ @rm -f lib${LIB}.so.${SHLIB_MAJOR}.${SHLIB_MINOR}
+ $(LD) -x -Bshareable -Bforcearchive \
+ -o ${.TARGET} /usr/lib/c++rt0.o lib${LIB}_pic.a ${LDADD}
+
+.endif
+
.include <bsd.lib.mk>
$(OBJS) : $(config) $(types) $(paths)
>Audit-Trail:
>Unformatted: