2011-11-07 12 views
8

Mam projekt, który tworzy wspólną bibliotekę, która jest połączona z inną, również udostępnioną, biblioteką.Zmiany wprowadzone w gcc 4.5 w odniesieniu do łączenia?

Kiedy skompilować i połączyć go z gcc 4.4, wszystko działa:

  1. bez ostrzeżenia podczas kompilacji lub błąd,
  2. ma czasu łączenie ostrzeżenie lub błąd i
  3. ldd libmyproject.so poprawnie raportuje zależność z druga wspólna biblioteka.

Kiedy skompilować i połączyć go z gcc 4.5, z drugiej strony (z dokładnie tymi samymi flagami), mam następujące objawy:

  1. bez ostrzeżenia kompilacji lub błędów,
  2. nie łącząc razem ostrzeżenie lub błąd ale
  3. biblioteka nie jest prawidłowo połączony przeciwko drugiej udostępnionego lib: sam, gdy biegnę ldd i nie widzę związku, a także, gdy próbuję go użyć tego manifestu: while działa z gcc 4.4, ulega awarii es przy uruchomieniu z gcc 4.5 z błędem "nie znaleziono symbolu" (oczywiście z innej biblioteki).

Spojrzałem na release notes i moja intuicja jest to, że ma coś wspólnego z nowym optymalizacji łącza czasu, ale nie mogę zrozumieć ich w wystarczającej ilości szczegółów.

Czy ktoś napotkał podobną sytuację i/lub ma jakąś radę do zaoferowania?

(Należy zauważyć, że wyniki z wynikiem 4.6 są identyczne jak w przypadku wersji 4.5).

+0

Jakie są twoje flagi łączenia? Czy możesz odtworzyć problem za pomocą minimalnego programu (main.c, lib1.c, lib2.c, jedna funkcja w jednym wierszu)? –

+0

Niestety dla mnie nie mogę odtworzyć tego przy minimalnym programie. Nie ma żadnych flag łączących z wyjątkiem oczekiwanych -L i -l wymaganych do znalezienia drugiej biblioteki. Powinienem również zauważyć, że nie napisałem drugiej biblioteki i nie wiem, jak ją skompilowano (ale widzę wszystkie symbole zgodnie z oczekiwaniami, używając 'nm'). – Philippe

+0

Brzmi jak błąd gcc dla mnie ... – lvella

Odpowiedz

2

Można debugować dynamicznie połączoną aplikację ze zmienną środowiskową LD_DEBUG. Jest to opcja z ld-linux.so.2; ldd to skrypt, który ustawia taką opcję. Wszystkie opcje są opisane na stronie man http://linux.die.net/man/8/ld-linux.

Jak korzystać LD_DEBUG (w bash; najprostszy sposób):

$ LD_DEBUG=all ./your_program 

To włączy debugowania LD-linux.so.2 - w czasie wykonywania dynamicznego linkera. Będzie ona drukować dużo debugowania stdout lub stderr i będzie w stanie

  • 1) Porównaj wyjście „LD_DEBUG=all ./your_program_4.4” i „LD_DEBUG=all ./your_program_4.5
  • 2) patrz ostatnie symbole próbuje się rozwiązać i znaleźć symbol buggy.

Ponadto, powinno dać nam więcej informacji:

  • 0) Jaki jest Twój system operacyjny oraz typ procesora? (pokaż nam wyjście uname -a) Jaka jest wersja libc? (uruchom w bash for a in /lib*/libc.so.*;do echo $a; $a; done)
  • 1) Co to jest kompilacja flag samej biblioteki?
  • 2) Jaki jest dokładny błąd podczas próby uruchomienia aplikacji?
  • 3) Ostatnie linie z wyjściem LD_DEBUG mogą zawierać cenne informacje

UPDATE: Dobra i dokładna odpowiedź jest tutaj: GCC 4.5 vs 4.4 linking with dependencies (od Mat)

1

Upewnij się określić swoje współdzielone biblioteki po obiekcie (lub źródła) plików w wierszu poleceń łącznikiem.

W ten sposób trzeba było zrobić to za pomocą statycznych bibliotek w dawnych czasach. Wydaje się, że jest to szczególnie korzystne w przypadku najnowszych wersji GCC. O ile mogę powiedzieć, jeśli skanuje wspólną bibliotekę, która nie dostarcza żadnych użytecznych symboli, ignoruje całą bibliotekę, która optymalizuje liczbę bibliotek współdzielonych załadowanych w czasie wykonywania, ale wymaga, aby opcje -libname pojawiły się po pliki obiektowe.

Powiązane problemy