2016-04-11 7 views
1

Ich habe A.so, die auf eine bestimmte versionierte libstdc++.so.6 in einem eigenen Verzeichnis (über rpath auf $ORIGIN gesetzt).dlopen respektiert `RTLD_LOCAL` nicht?

Wenn ich dlopenA.so allein, funktioniert es gut.

Wenn ich mein System des libstdc++.so.6dlopen (die von anderen Version ist) in RTLD_LOCAL Modus, und dann dlopenA.so

OSError: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by A.so) 

Warum dlopen nicht Respekt RTLD_LOCAL?

Antwort

4

Warum dlopen nicht Respekt RTLD_LOCAL

RTLD_LOCAL bedeutet nicht, was Sie denken, es bedeutet. Von man dlopen:

RTLD_LOCAL 
      This is the converse of RTLD_GLOBAL, and the default if 
      neither flag is specified. Symbols defined in this shared 
      object are not made available to resolve references in 
      subsequently loaded shared objects. 

Beachten Sie, dass dies sagt nichts über die Bibliothek der Lader geladen wird.

Der Lader wird nie Last mehr als eine Instanz eines gegebenen SONAME (es sei denn, Sie verwenden einen anderen Umfang Linker dlmopen verwendet wird), so dass, wenn Sie dlopen System libstdc++.so.6, ist, dass die nurlibstdc++.so.6 Sie werden jemals bekommen. Wenn Sie später dlopen("A.so", ...), die Laufzeitlader:

  1. für Bibliotheken Looks, die A.so hängt davon ab, findet heraus, dass libstdc++.so.6 unter ihnen ist, und findet heraus, dass es bereits hat libstdc++.so.6 geladen, so wird die Suche es nicht, noch laden Sie eine andere Kopie,
  2. Looks für Version Symbole, die A.so erfordert. Es ist an diesem Punkt, dass Sie den Fehler erhalten, da A.so erfordert GLIBCXX_3.4.20 von libsstdc++.so.6, und da das bereits geladene System libstdc++.so.6 ist älter und bietet keine GLIBCXX_3.4.20 Version.
  3. Da Schritt # 2 fehlgeschlagen ist, wird Ihre dlopen abgelehnt.

Beachten Sie, dass Sie nie zu lösen keine Symbole von libstdc++.so.6 erhalten (wo RTLD_LOCAL würde Materie); Sie scheitern lange vor das.

Nun, was Sie wahrscheinlich versuchen zu tun, baut A.so so dass es dynamisch in ein beliebiges Programm geladen werden, möglicherweise ein eine ältere Version von libstdc++.so.6 verwenden, ohne dass der Endnutzer aktualisieren System libstdc++.so.6. Leider kann dies einfach nicht getan werden.