2012-06-12 18 views
7

Mam obiekt współdzielony, który statycznie łączy się z libssl.a & innym udostępnionym obiektem B.to, który również statycznie łączy libssl.a.Biblioteka statyczna załadowana dwukrotnie

A.so & B.to ma symbole z biblioteki libssl.a w zasięgu GLOBAL. Sprawdziłem to przez readelf -s A.so

Mam plik wykonywalny a.out, który ładuje A.so i B.so. Po zakończeniu a.out otrzymuję podwójnie wolny błąd w jednym z symboli z biblioteki libssl.a w A.so.

Mimo że biblioteka libssl.a jest statycznie połączona z każdym obiektem udostępnionym, ponieważ są one udostępnione na całym świecie, to jest możliwe, że ten sam symbol jest udostępniany zamiast wybierania jego lokalnej kopii.

Co to jest obejście tego problemu? Jak ustawić tutaj symbole?

Proszę pomóc

+0

Polecam użycie debuggera do potwierdzenia twojej teorii. – jdigital

+0

Czy mógłbyś rozwinąć? – KodeWarrior

+0

To tylko mała rzecz, ponieważ nie mam pojęcia, jak zastosować ją do twojej sytuacji: 'dlopen' ma flagę RTLD_LOCAL, która w pewnych okolicznościach może pomóc w tej właśnie sytuacji. Więc jeśli otworzyłeś te biblioteki z 'dlopen', prawdopodobnie nie powinny w tym czasie ingerować. – liori

Odpowiedz

5

Jest to rzeczywiście oczekiwane. Jedna instancja libssl.a zakłada (prawdopodobnie podzbiór) drugą, a wyniki nie są ładne. Możesz użyć skryptu wersji (--version-script do ld, z -Wl, dla cc), aby kontrolować, co jest eksportowane z A.so i B.so. Jeśli coś nie jest eksportowane, nie można go również wstawić.

Alternatywnie można skompilować libssl.a z flagami widoczności, takimi jak -fvisibility=hidden. Te flagi mają wpływ tylko na dynamiczny linker, a nie na statyczne łączenie. Najprawdopodobniej będziesz musiał sam ją skompilować, ponieważ wysłane pliki .a zawierają kod zależny od pozycji, przeznaczony do łączenia się z plikami wykonywalnymi. Tylko niektóre platformy, na przykład 32-bitowe x86, pozwalają uniknąć łączenia takich kodów z obiektami udostępnionymi i kosztem przeniesienia tekstu.

Polecenie dlopen z RTLD_LOCAL, jak zasugerowano w komentarzu, powinno również działać, ale wydaje się hackish używać w tym celu dlopen.

Inną opcją jest użycie tego samego udostępnionego pliku libssl.so w obu bibliotekach.

Powiązane problemy