15

Why glibc and pthread library both defined same APIs ? Here is the snapshot

ubuntu@ubuntu:/lib$ objdump -T /lib/i386-linux-gnu/libc.so.6 |grep pthread_cond_signal
000f8360 g    DF .text  00000039  GLIBC_2.3.2 pthread_cond_signal
0012b940 g    DF .text  00000039 (GLIBC_2.0)  pthread_cond_signal

ubuntu@ubuntu:/lib$ objdump -T /lib/i386-linux-gnu/libpthread.so.0 |grep pthread_cond_signal
0000b350 g    DF .text  0000007c (GLIBC_2.0)  pthread_cond_signal
0000af90 g    DF .text  000000fc  GLIBC_2.3.2 pthread_cond_signal
Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521
Lunar Mushrooms
  • 8,358
  • 18
  • 66
  • 88

1 Answers1

17

libpthread.so is part of glibc too, and they both contain (identical) definitions of some symbols.

If you look for pthread_create instead you'll see that it's only present in libpthread.so -- this means programs must link to libpthread.so to actually create threads, but can use mutexes and condition variables in single-threaded programs that only link to libc.so. That's useful for interprocess mutexes and interprocess condition variables that live in shared memory and are used to synchronise with separate processes. (corrections thanks to Zan Lynx's comment below).

It's not a problem to link to both libpthread.so and libc.so even though they both define the symbol. ELF linkers allows several shared libraries to contain definitions of the same symbol and the linker will choose the first one it sees and use it for all references to that symbol, this is called symbol interposition. Another feature that allows multiple symbols to be defined is if one library contains weak symbols which will be overidden by non-weak symbols with the same name. In this case the definitions in the two libraries are identical, so it doesn't matter which is used libpthread.so override those in libc.so. If you use LD_DEBUG and change the order of arguments to the linker you should be able to see which library the symbol actually gets found in.

As well as the two libraries defining the same symbol, each library has two definitions of the symbol, with different symbol versions, GLIBC_2.0 and GLIBC_2.3.2. This symbol versioning allows multiple definitions to co-exist in the same library so that new, improved versions of the function to be added to the library without breaking code that is linked against the old implementation. This allows the same shared library to work for applications using LinuxThreads and applications using NPTL. The default symbol that a reference will be bound to when linking to the library is pthread_cond_signal@GLIBC_2.3.2 which corresponds to the NPTL implementation of that function (NPTL was first included in glibc 2.3.2). The older symbol, pthread_cond_signal@GLIBC_2.0, is the older LinuxThreads implementation that was the default before NPTL was provided. Applications linked against older (pre-2.3.2) versions of glibc will be bound to pthread_cond_signal@GLIBC_2.0 and will use that symbol.

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521
  • You are right , the pthread_create is not defined in libc.so.6. But why dont we get multiple definition error for pthread_cond_signal while linking ? – Lunar Mushrooms Jun 26 '12 at 18:02
  • 8
    I do not believe that this answer is entirely correct. The definitions in glibc are place-holders only and have only empty do-nothing definitions for the pthread operations. The definitions in libpthread.so override these. This is for use by libraries which want to be fast in single-threaded but thread-safe in multithreaded programs. – Zan Lynx Oct 01 '12 at 15:40
  • @ZanLynx, ah, I think you're right - my bad - I thought `pthread_mutex_lock` and similar functions could be used without linking to libpthread, but they do seem to be no-ops. – Jonathan Wakely Oct 01 '12 at 16:41