Symbole in einer gemeinsam genutzten Bibliothek unter Mac OS X ausblenden

9

Wir haben eine große Open-Source-Software auf einer Vielzahl von Plattformen (Linux, Windows, Mac OS X, 32-Bit und 64-Bit) für mehrere Jahre ohne Probleme. In letzter Zeit jedoch hat die Mac OS X Build (64-Bit) nicht mehr korrekt funktioniert und stürzte wahllos ab. Es stimmte mehr oder weniger mit einem Update von Mac OS X auf unserer Build-Maschine von 10.7 auf 10.8.2 überein (aber die Compiler-Toolchain änderte sich nicht, es ist immer noch llvm-gcc 4.2.1).

Unsere Anwendung besteht aus ein paar dynamischen (geteilten) Bibliotheken und vielen ausführbaren Dateien, die diese benutzen. Eine der gemeinsam genutzten Bibliotheken überschreibt die Operatoren new und delete aus verschiedenen Gründen. Unter Mac OS X (und Linux) werden standardmäßig alle Symbole exportiert, einschließlich unserer überladenen Operatoren new und delete . Die Abstürze unter Mac OS X scheinen auf Speicher zurückzuführen zu sein, der mit einem Speichersubsystem (nicht unserem) zugewiesen wurde und dann durch unsere eigene (und inkompatible) delete -Implementierung freigegeben wurde.

Die klarste Lösung scheint zu verhindern, dass die überladenen Operatoren für die Benutzer der gemeinsam genutzten Bibliothek sichtbar sind. Dies kann auf zwei Arten erfolgen: Markieren der Operatoren mit __attribute__((visibility("hidden"))) oder Verwenden der Befehlszeilenoption -unexported_symbols_list linker, um zu verhindern, dass einige Symbole exportiert werden. Die erste Lösung funktioniert leider nicht: gcc gibt Warnungen aus, dass die Operatoren anders deklariert wurden (in <new> ) und somit die Attribute ignoriert werden. Aus meinen Lesungen an verschiedenen Orten scheint die zweite Lösung die richtige für dieses Problem zu sein. Aus irgendeinem Grund können wir es jedoch nicht schaffen .

Wenn Sie die gemeinsam genutzte Bibliothek verknüpfen, übergeben wir die Option -Wl,-unexported_symbols_list unexported_symbols_list.txt an g ++, die wiederum an ld übergeben werden soll. Die Datei unexported_symbols_list.txt enthält die folgende Symbolliste:

%Vor%

Dies sind alle Variationen von new und delete , die wir überschreiben und die ausgeblendet werden sollen. Wir haben diese Symbole gefunden, indem wir nm libappleseed.dylib gemacht haben und dann die Symbolnamen mit c++filt entfernt haben.

Hier ist die Befehlszeile, die von CMake generiert wurde, um libappeseed.dylib :

zu verknüpfen %Vor%

Leider scheint es, trotz all unserer Bemühungen, dass die Symbole erhalten bleiben (wie nm zeigt).

Irgendeine Idee, was wir falsch machen? Gibt es einen anderen Ansatz, den wir ausprobieren könnten?

UPDATE Dez. 19, 2012:

Unser Problem und die vermeintliche Lösung sind in dieser technischen Anmerkung von Apple gut beschrieben: Ссылка (Abschnitt "Überschreiben / Löschen").

Zeiger auf relevanten Quellcode:

Fragment der Ausgabe von operator delete nach dem Erstellen von libappleseed.dylib mit nm und laufendem -fvisibility=hidden :

%Vor%     
François Beaune 10.12.2012, 00:13
quelle

2 Antworten

5

Sie sollten mit -fvisibility=hidden aufbauen und dann nur das exportieren, was Sie wollen. Lesen Sie hier:

Ссылка

Es erklärt auch -fvisibility-inlines-hidden . Viele große Bibliotheken (z. B. Qt) nutzen dies. Die Vorteile sind ziemlich beträchtlich.

    
Nikos C. 10.12.2012 10:09
quelle
0

Sie können sich die Symbolkarten / Versionierung ansehen (Option --version-script ld)

Ссылка

    
alexp 19.12.2012 17:25
quelle