Pthread Stubs in C Library
By default, the compiler drivers (cc, aCC, f90) automatically pass –lc to the linker at the end of the link line of the
executables. It is not necessary to specify -lc when building a shared library because libc will be resolved by the
reference to libc in the executable build command. The libc will be resolved by -lc that is automatically passed by the
compiler drivers to the linker.
To see if a shared library was built with -lc, look at the shared library list in the chatr() output, or list the dependent
libraries with ldd(1):
$ cc +z -c lib1.c
$ ld -b -o lib1.sl lib1.o -lc
$ ldd lib1.sl
/usr/lib/libc.2 => /usr/lib/libc.2
/usr/lib/libdld.2 => /usr/lib/libdld.2
/usr/lib/libc.2 => /usr/lib/libc.2
$ cc +DA2.0W +z -c lib1.c
$ ld -b -o lib1.sl lib1.o -lc
$ ldd lib1.sl
libc.2 => /lib/pa20_64/libc.2
libdl.1 => /usr/lib/pa20_64/libdl.1
To see the order in which dependent shared libraries will be loaded at run-time (order is only valid in 64-bit mode),
use ldd(1) on the executable (ldd in 32-bit mode displays the order in which libraries are loaded in reverse order):
$ cc +DA2.0W thread.c -lpthread
$ ldd a.out
libpthread.1 => /usr/lib/pa20_64/libpthread.1
libc.2 => /usr/lib/pa20_64/libc.2
libdl.1 => /usr/lib/pa20_64/libdl.1
$ cc +DA2.0W thread.c -lc -lpthread
$ ldd a.out
libc.2 => /usr/lib/pa20_64/libc.2
libpthread.1 => /usr/lib/pa20_64/libpthread.1
libdl.1 => /usr/lib/pa20_64/libdl.1
$ cc +DA2.0W thread.c -lpthread -lc
$ ldd a.out
libpthread.1 => /usr/lib/pa20_64/libpthread.1
libc.2 => /usr/lib/pa20_64/libc.2
libdl.1 => /usr/lib/pa20_64/libdl.1
Recommendations:
·
remove -lc from the build command of all shared libraries
·
remove -lc from the build command of all executables
·
use the LD_PRELOAD environment variable set to the full pathname for libpthread or libcma, which will
cause the library to be loaded at program startup before other dependent libraries. LD_PRELOAD
functionality is available in PHSS_22478 and later Linker patches. See the dld.sl(5) man page.
·
if you link directly with ld(1) instead of with a compiler driver, add -lc as the last component on the link line.
Example 1 (64-bit):
If a 64-bit shared library is built with -lpthread but the executable is not, libc is loaded before libpthread (due to
breadth-first searching), and the pthread calls are resolved to the pthread stubs in libc. At run-time, after the a.out is
loaded, the dependencies of a.out are loaded in breadth-first order: libc is loaded as a dependent of a.out before
libpthread is loaded as a dependent of libc.2. The dependency list of the first case is:
a.out
/ / \
lib1 lib2 libc
| |