Mit libtool eine doppelte Funktion Namen von einer gemeinsam genutzten Bibliothek laden
-
19-09-2019 - |
Frage
Ich versuche, eine ‚Debug‘ Shared Library zu erstellen (dh .so oder DLL-Datei), die ein anderen ‚echten‘ Shared Library aufruft, die den gleichen C-API wie die Debug-Bibliothek hat (in diesem Fall zu emulieren die PKCS # 11-API). Aber ich renne in Schwierigkeiten, wo der Link Karte der Debug-Bibliothek mit kollidiert, dass der realen Bibliothek und verursacht die Debug-Bibliothek ihre eigenen Funktionen aufrufen, anstatt die entsprechenden Funktionen in der realen Bibliothek. Ich fand eine Lösung für dieses Problem, indem Sie den POSIX dlmopen Befehl, möchte aber verstehen, wenn das gleiche möglich ist GNU libtool verwendet wird.
Auf meinem Solaris 10-System, schlägt der folgende Code die Behauptung, wenn eine Testanwendung der Debug-Bibliothek statisch verknüpft:
#include <dlfcn.h>
int MyFunctionName() {
int (*function_ptr)();
void *handle = dlopen("realsharedlibrary.so", RTDL_LAZY);
*(void **)(&function_ptr) = dlsym(handle, "MyFunctionName");
ASSERT(function_ptr != MyFunctionName); // Fails
return (*function_ptr)();
}
In diesem Fall bekomme ich einen Funktionszeiger auf dem lokal 'MyFunctionName' (in der Debug-Bibliothek) statt MyFunctionName innerhalb der realen Shared Library.
Ich habe entdeckt, dass es möglich ist, dieses Problem zu umgehen, indem Sie den Befehl ‚dlmopen‘ anstelle von ‚dlopen‘ und dlmopen sage, eine neue Link Karte erstellen (mit dem LM_ID_NEWLM
Parameter), wenn die reale Bibliothek geladen:
int MyFunctionName() {
int (*function_ptr)();
void *handle = dlmopen(LM_ID_NEWLM, "realsharedlibrary.so", RTDL_LAZY);
*(void **)(&function_ptr) = dlsym(handle, "MyFunctionName");
ASSERT(function_ptr != MyFunctionName); // succeeds
return function_ptr(); // call real function
}
Leider dlmopen scheint nicht innerhalb libtool aufgenommen werden (das heißt, ich habe nicht eine lt_dlmopen Funktion in libtool sehen).
Ist es möglich, die gleiche Sache mit libtool Befehlen zu tun - das heißt, eine neue Verbindung Karte zu erstellen, wenn die neue Bibliothek geladen, so dass sie nicht kollidieren mit der Link Karte der Debug-Bibliothek
Lösung
Ich habe nicht eine gute Art und Weise zu nutzen libtool habe dieses Problem noch zu lösen, aber es gibt einen Weg, um die Solaris-spezifischen ‚dlmopen‘ Funktion zu vermeiden, indem sie mit diesen Flags unter Verwendung dlopen:
void *handle = dlopen("realsharedlibrary.so", RTLD_NOW | RTLD_GROUP | RTLD_LOCAL)
Offensichtlich ist das Problem der Symbol-Kollisionen wird durch die Verwendung RTLD_NOW
statt RTLD_LAZY
gelöst und durch Zugabe von RTLD_GROUP
. Die RTLD_LOCAL
ist da, weil POSIX entweder RTLD_LOCAL
oder RTLD_GLOBAL
erfordert, oder das Verhalten ist nicht definiert. Für Solaris ist das Verhalten zu RTLD_LOCAL
auf Standard.
Die offene Frage ist jedoch, ob es möglich ist, diese Art von Flaggen passieren lt_dlopen.