2013-10-03 12 views
6

Napisałem wspólną bibliotekę z kilkoma niekompatybilnymi wersjami. Zmieniłem SONAME, więc są one nazywane:Wykryj dwie niezgodne z ABI wersje mojej biblioteki współużytkowanej załadowane do pojedynczego programu

  • lib_mylib.so.1.0.0 (starsze biblioteki)
  • lib_mylib.so.2.0.0

Istnieją pewne funkcje tylko w myLib. so.1, inne są tylko w mylib.so.2 i wiele funkcji jest wspólnych (ale kilka zmieniło liczbę argumentów)

I obawiam się, że możliwe jest połączenie obu wersji mylib w jedną aplikację, na przykład kiedy sama aplikacja jest duża i składa się z wielu bibliotek. Gdy aplikacja jest częściowo odbudowane, nie może być taka sytuacja:

  • Zastosowanie
  • app_lib1.so (został zbudowany z mylib.so.1 - pierwsza wersja mojego lib)
  • app_lib2.so (przebudowano z mylib.so.2 - druga wersja)

Już widziałem aplikację załadowaną do obu wersji (ldd zgłasza oba).

Czy istnieje możliwość dodania kodu do pliku mylib.so.2 w celu wykrycia, że ​​są już załadowane obie wersje biblioteki i mają konflikt ABI/Interface. (Nie mogę zmodyfikować biblioteki lib_mylib.so.1, aby dodać coś do niej)

Odpowiedz

1

Można przeanalizować /proc/self/maps, aby uzyskać listę aktualnie załadowanych obiektów.

+0

Potrafię tylko parsować '/ proc/self/maps' w konstruktorze mojej biblioteki. Myślę, że jest możliwe, że w momencie uruchomienia mojego konstruktora z drugiej biblioteki, pierwsza biblioteka nie zostanie jeszcze załadowana do pamięci (case 1: mylib2 jest wcześniejsza niż mylib1 na liście bibliotek; case 2: mylib1 zostanie załadowana za pomocą dlopen at jakiś czas później) – osgx

3

Możesz zmodyfikować bibliotekę wersji 2, aby rozwiązać jakiś symbol specyficzny dla wersji 1 (dlsym(3)) podczas inicjowania i awarii po znalezieniu.

przykład:

extern __attribute__((constructor)) void _version_check2() 
{ 
    if (dlsym(RTLD_DEFAULT, "version_1_function")) 
     abort(); 
} 

na bardziej elegancki rozwiązań jest umożliwienie wersja 2 biblioteki naśladować działanie wersji 1, ale który wprowadza kod starszych.

EDIT

Aby mieć możliwość rozbudowy, można również wprowadzić zmienną statyczną wersji i wszystkie wywołania funkcji byłoby sprawdzić, czy jest on zgodny z prądu. Następnie w przyszłych wersjach wystarczy zmienić wartość tej zmiennej i awarię, jeśli niezgodność.

EDIT 2

Można również wywołać tę funkcję na każdy wersja 2 funkcja tak, że prędzej czy później, gdy wersja 1 zostanie załadowana swoje awarie aplikacji.

+0

A może specyficzne dla Linuksa 'dlopen (RTLD_NOLOAD," lib_mylib.so.1.0.0 ")'. – rodrigo