2016-02-02 28 views
6

Ich habe ein einfaches Testprogramm Aufruf pthread_cond_broadcast.Verschiedene Symbole von glibc/pthreads verwendet, wenn Gold vs ld-Linker

Wenn mit dem ld Linker verbunden, dies zeigt:

Fall 1:

$ nm ld-test | grep cond_broadcast 
U [email protected]@GLIBC_2.3.2 

Wenn mit dem Linker gold verknüpft es zeigt:

Fall 2:

$ nm gold-test | grep cond_broadcast 
U pthread_cond_broadcast 

pthread/libc enthält mehrere pthread_cond_broadcast Symbole wi Die verschiedenen Versionssymbole, vermutlich seit der Änderung des ABI.

$ nm /lib64/libc.so.6 |grep cond_broadca 
00000036b84f7d30 t __pthread_cond_broadcast 
00000036b85278f0 t __pthread_cond_broadcast_2_0 
00000036b84f7d30 T [email protected]@GLIBC_2.3.2 
00000036b85278f0 T [email protected]_2.2.5 
$ nm /lib64/libpthread.so.0 |grep cond_broadcast 
00000036b880bee0 t __pthread_cond_broadcast 
00000036b880c250 t __pthread_cond_broadcast_2_0 
00000036b880bee0 T [email protected]@GLIBC_2.3.2 
00000036b880c250 T [email protected]_2.2.5 

So sind die Fragen:

  1. Warum das unterschiedliche Verhalten zwischen gold und dem alten/normal ld.
  2. Welches Symbol pthread_cond_broadcast wird zur Laufzeit im Fall 2 verwendet, wenn die Binärdatei mit einem unversionierten Symbol pthread_cond_broadcast verknüpft ist. Die neueste Implementierung von pthread_cond_broadcast? Der älteste ?

Dies wird mit gcc 4.9.2 und dem Gold/ld Linker aus binutils 2,24

Antwort

1

zunächst eine Klarstellung (als Teil der devtoolset-3 von Red Hat.): ELF-Dateien haben oft zwei Symboltabellen. Es gibt die "fette" oder "volle", die alle internen Symbole enthält (normalerweise in einem Abschnitt namens .symtab vom Typ SHT_SYMTAB), und es gibt die "schlanke", die nur Laufzeitdetails enthält (normalerweise in einem Abschnitt .dynsym vom Typ SHT_DYNSYM)). nm analysiert nur die erste, daher ist es oft kein guter Indikator für das Laufzeitverhalten. Sie möchten stattdessen readelf -s verwenden und in der .dynsym Tabelle nachsehen, was zur Laufzeit wirklich zählt.

(1) Ich weiß nicht, warum die Debug-Symbol-Tabelle nicht die vollständige Symbol-Versionierung bei der Verwendung von Gold enthält. scheint für mich wie ein Käfer.

(2) Wenn Sie sich einmal die Runtime-Symboltabelle ansehen, wird Ihre Antwort von selbst angezeigt: [email protected]_2.3.2 wird verwendet.

(2a) wie für welche Bibliothek dieses Symbol geladen wird, das hängt vollständig davon ab, wie die ELF und seine Laufzeitumgebung verknüpft wurde. Lassen Sie uns alle Möglichkeiten ignorieren und konzentrieren uns auf das Gemeinsame: Wenn Sie mit -lpthread verbunden sind, wird die Version in libpthread.so verwendet. Wenn nicht, wird die Version in libc.so verwendet.

(2b) Warum hat eine einzelne Bibliothek mehr als eine Version (z. B. libc.so hat [email protected]@GLIBC_2.2.5 und [email protected]@GLIBC_2.3.2)? Sie haben richtig geraten, dass es für die Rückwärtskompatibilität ist. Irgendwann in der Vergangenheit wurde die ABI geändert, anstatt die bestehenden Apps zu brechen, wurde die Version aktualisiert. Alle Programme, die mit einer alten glibc-Version verknüpft wurden, verwenden die alten Symbolversionen, während neue Programme die neuen Symbole verwenden.Als Richtlinie stellt Glibc die neueste Symbolversion als Standardversion zur Verfügung. Wenn Sie also pthread_cond_broadcast verwenden, werden Sie mit der [email protected]@GLIBC_2.3.2 verknüpft. Das ist eine Konvention, die fast jeder benutzt ... obwohl es technisch möglich ist, eine davon als Standardversion zu veröffentlichen.

(2c) Warum existiert das Symbol in beiden libc.so & libpthread.so? dies erlaubt Bibliotheken Multithread-Umgebungen zu unterstützen, ohne in einer Ein-Thread-Umgebung benachteiligt zu werden, oder ohne zwei verschiedene Bibliotheken schreiben zu müssen, z. eine benannte libfoo.so und eine benannte libfoo_thread.so. Die Symbole in libc.so sind Dummy-Symbole - sie geben immer "Erfolg" zurück. Wenn Ihr Hauptprogramm nicht Multithread ist, werden alle Aufrufe in libfoo.so unterdrückt. aber wenn Ihr Hauptprogramm Multithread ist (d. h. Links gegen -lpthread), dann werden die Symbole transparent & automatisch zu libpthread.so geroutet und alle Aufrufe in libfoo.so werden DTRT (d. h. Mutexe/etc ...).