2016-02-02 9 views
6

Mam prosty program testowy, wywołujący pthread_cond_broadcast.Różne symbole z glibc/pthreads używane podczas używania linku złotego vs Ld

W połączeniu z ld łącznika, co pokazuje:

Przypadek 1:

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

W połączeniu z gold łącznik pokazuje:

Przypadek 2:

$ nm gold-test | grep cond_broadcast 
U pthread_cond_broadcast 

pthread/libc zawiera kilka symboli pthread_cond_broadcast wi różne symbole wersji prawdopodobnie od czasu zmiany 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 

więc pytania są:

  1. Dlaczego różne zachowanie między gold i starego/normalnej ld.
  2. Który symbol pthread_cond_broadcast jest używany w środowisku wykonawczym w przypadku 2, gdy plik binarny jest połączony z niewersjonowanym symbolem pthread_cond_broadcast. Najnowsza implementacja pthread_cond_broadcast? Najstarszy ?

ta używa gcc 4.9.2 a łącznik złoto/ld z binutils 2.24

Odpowiedz

1

najpierw wyjaśnienie (jako część devtoolset-3 z Red Hat.): Pliki ELF mają często dwie tabele symboli. jest plik "gruby" lub "pełny", który zawiera wszystkie wewnętrzne symbole (zwykle w sekcji o nazwie .symtab typu SHT_SYMTAB), a tam jest "szczupła", która zawiera tylko szczegóły środowiska wykonawczego (zwykle w sekcji o nazwie .dynsym typu SHT_DYNSYM). nm analizuje tylko pierwszy, więc często nie jest dobrym wskaźnikiem zachowania środowiska wykonawczego. zamiast tego chcesz użyć readelf -s i spojrzeć na tabelę .dynsym, aby zobaczyć, co naprawdę ma znaczenie w środowisku wykonawczym.

(1) Nie wiem, dlaczego tabela symboli debugowania nie uwzględnia pełnej wersji symbolu podczas korzystania ze złota. wydaje mi się, że to błąd.

(2) Gdy spojrzysz na tabelę symboli runtime, twoja odpowiedź pojawi się sama: zostanie użyty [email protected]_2.3.2.

(2a), dla którego symbol zostanie załadowany, to zależy całkowicie od sposobu połączenia ELF i jego środowiska wykonawczego. zignorujmy wszystkie możliwości i skoncentrujmy się na wspólnym: jeśli użyjesz opcji -lpthread, zostanie użyta wersja w libpthread.so. jeśli nie, wówczas zostanie użyta wersja w libc.so.

(2b) Dlaczego pojedynczy biblioteka mieć więcej niż jednej wersji (np libc.so ma [email protected]@GLIBC_2.2.5 i [email protected]@GLIBC_2.3.2)? poprawnie domyśliłeś się, że jest to kompatybilność wsteczna. W pewnym momencie w przeszłości zmieniono ABI, więc zamiast łamać wszystkie istniejące aplikacje, zaktualizowano wersję. wszystkie programy, które były połączone ze starą wersją glibc będą używać starych wersji symboli, podczas gdy nowe programy będą używać nowych symboli.Zgodnie z polityką, glibc udostępnia najnowszą wersję symbolu jako domyślną, więc jeśli użyjesz pthread_cond_broadcast, zostaniesz połączony z numerem [email protected]@GLIBC_2.3.2. jest to wyłącznie konwencja, z której korzysta większość osób ... chociaż technicznie możliwe jest ujawnienie któregokolwiek z nich jako wersji domyślnej.

(2c) dlaczego symbol istnieje zarówno w libc.so & libpthread.so? dzięki temu biblioteki mogą obsługiwać wielowątkowe środowiska bez karania w środowisku singlethreaded lub bez konieczności pisania dwóch różnych bibliotek, np. jeden o nazwie libfoo.so i jeden o nazwie libfoo_thread.so. symbole w libc.so są symbolami dummy - zawsze zwracają "sukces". więc jeśli twój program główny nie jest wielowątkowy, wszystkie wywołania w libfoo.so zostaną zgaszone. ale jeśli twój główny program jest wielowątkowy (tzn. łącza przeciwko -lpthread), wtedy symbole będą przezroczyście automatycznie kierowane do libpthread.so, a wszystkie wywołania w libfoo.so będą DTRT (tj. grab mutexes/etc ...).

Powiązane problemy