Inhaltsverzeichnis
DLLs / dynamische Libraries / DSOs / shared libraries
DLL: Dynamic Link Library (Windows)
DSO: Dynamic Shared Object (ELF, Posix)
- Unix/Linux: dlopen(), dlsym(), dlclose(), dlerror(): http://linux.die.net/man/3/dlopen
- Mit Beispielen: http://tldp.org/HOWTO/C++-dlopen/thesolution.html
- Entwicklung von DLLs in Windows: Linking an Executable to a DLL
- Building Windows DLLs with MinGW: http://www.transmissionzero.co.uk/computing/building-dlls-with-mingw/ - Ein sehr guter Artikel!
- Shared libraries with GCC on Linux: https://www.cprogramming.com/tutorial/shared-libraries-linux-gcc.html
- Workaround beim Kompilieren/Linken von mqic.dll/.lib mit GCC unter Windows
- Initialisierung und Deinitialisierung von dynamischen Libraries (Initialization and finalization functions / Library constructor and destructor functions / DllMain)
- Export von Funktionen in den Libraries (GCC, Posix + Plattformübergreifend)
- Konflikte wegen den gleichen Namen:
- Shared Library Symbol Conflicts (on Linux): https://holtstrom.com/michael/blog/post/437/Shared-Library-Symbol-Conflicts-%28on-Linux%29.html
- Shared Library Symbol Conflicts (on Solaris): https://holtstrom.com/michael/blog/post/446/Shared-Library-Symbol-Conflicts-%28on-Solaris%29.html
- Solaris Export Symbols: https://holtstrom.com/michael/blog/post/455/Solaris-Export-Symbols.html
- Auf AIX in Kombination mit GCC unbedingt folgende Hinweise beachten:
- Using the GNU C/C++ compiler on AIX: http://www.ibm.com/developerworks/aix/library/au-gnu.html
- Auf AIX haben üblicherweise beide Libraries-Typen die Endung ".a" - sowohl die statischen als auch die dynamischen.
- AIX-spezifisches ld: https://www.ibm.com/support/knowledgecenter/ssw_aix_61/com.ibm.aix.cmds3/ld.htm
- AIX® Linking and Loading Mechanisms: http://download.boulder.ibm.com/ibmdl/pub/software/dw/aix/es-aix_ll.pdf
Wenn aus der DLL/SO Symbole/Funktionen referenziert werden, die in der Executable definiert sind (also, Referenzierung in "umgekehrter" Richtung), dann hilft die Option "-rdynamic" beim Linken (GCC) weiter. Wie und warum, erklärt sehr anschaulich folgender Beitrag:
http://stackoverflow.com/questions/36692315/what-exactly-does-rdynamic-do-and-when-exactly-is-it-needed
Abhängigkeiten
Die Abhängigkeiten eines ausführbares Programms oder einer dynamischen Libraries werden mit ldd angezeigt:
juergen@developing:~> ldd /usr/lib/libglib-2.0.so /usr/lib/libglib-2.0.so needs: /usr/lib/libc.a(shr.o) /usr/lib/libpthread.a(shr_xpg5.o) /opt/freeware/lib/libintl.a(libintl.so.1) /opt/freeware/lib/libiconv.a(libiconv.so.2) /unix /usr/lib/libcrypt.a(shr.o) /usr/lib/libpthreads.a(shr_comm.o) /opt/freeware/lib/libiconv.a(shr4.o) juergen@developing:~>
Per Voreinstellung sucht der Loader nur in /lib und /usr/lib. Die Umgebungsvariable LD_LIBRARY_PATH ergänzt diese Suche um weitere (durch Doppelpunkte getrennte) Verzeichnisse.
Inhalt / enthaltene Funktionen / Symbols
Den Inhalt (die Symbols) einer Libraries mit dem Befehl nm anzeigen lassen:
juergen@developing:~> nm -g /usr/lib/libglib-2.0.so | head -10 .$PTRGL T 268536464 ._Errno T 268482448 .__divi64 T 268633312 .__divss U 12800 .__divu64 T 268532584 .__divus U 12928 .__f64toi64rz T 268805056 .__f64tou64rz T 268643292 .__itrunc T 268643008 202 .__mulh U 12544 nm: /usr/lib/libglib-2.0.so: 0654-207 The sort process was stopped prematurely. juergen@developing:~>
Falls sich nm mit folgender Fehlermeldung beschwert:
0654-210 xxxxx.o is not valid in the current object file mode. Use the -X option to specify the desired object mode.
…dann nach dem "-g" mit dem zusätzlichen Parameter -X64 versuchen (für AIX relevant).
Mit der Option "-g" werden nur die externen Symbole angezeigt.
Mit der Option "-D" werden anstelle "normaler" Symbole die dynamischen Symbole angezeigt.
Auch der Befehl dump ist in diesem Zusammenhang sehr nützlich.
Debugging von DLLs/DSOs
Beim Laden eines DSOs wird der Initialisierungscode innerhalb des DSOs aufgerufen, bevor die dlopen() zurückkehrt. Diese Initialisierung ist UserCode und kann Fehler erzeugen, die nicht von dlopen() gefangen werden können. Beispielsweise wird ein mit RTLD_LAZY geladenes Objekt, das versucht, eine Funktion aufzurufen, die nicht lokalisiert werden kann, zu einer Prozessbeendigung führen. Fehlerhafte Programmierpraktiken innerhalb des Initialisierungscodes können auch zur Prozessbeendigung führen. Die "runtime linkers debugging"-Funktion kann helfen, diese Art von Fehler zu identifizieren. Eine davon ist die Environment-Variable LD_DEBUG.
LD_DEBUG (Environment-Variable)
Die Environment-Variable LD_DEBUG (bzw. LD_DEBUG_32 und LD_DEBUG_64), die als Argument eine durch Komma oder Doppelpunkt getrennte Liste von Tokens hat, veranlasst den RunTime-Linker, Debugging-Informationen auf stderr auszugeben.
Die Environment-Variable LD_DEBUG_OUTPUT kann ebenfalls definiert werden, um eine Datei anzugeben, an die die Debugging-Informationen gesendet werden sollen.
Hier ist ein Beispiel:
LD_DEBUG=files,bindings,detail LD_DEBUG_OUTPUT=lari.dbg
Die Debug-Ausgabe wird ins File lari.dbg.PID geschrieben (PID ist die Prozess-ID).
Die Tokens files,bindings sind i.d.R. völlig ausreichend. Das Token detail bläht das Ausgabe-File sehr stark auf (die Adressinformationen) und ist normalerweise verzichtbar.
Quelle: Oracle man pages - section 3: Basic Library Functions
- dlopen (gain access to an executable object file): https://docs.oracle.com/cd/E26502_01/html/E29034/dlopen-3c.html
- ld.so.1 (runtime linker for dynamic objects): https://docs.oracle.com/cd/E26502_01/html/E29030/ld.so.1-1.html#REFMAN1ld.so.1-1
- lari (link analysis of runtime interfaces): https://docs.oracle.com/cd/E26502_01/html/E29030/lari-1.html#scrolltoc
Stand: 27.09.2019
— : Jürgen Kreick
EOF