ltrace ... oder was macht ein Programm
Zitat von Juhu am 15. Oktober 2026, 14:31 UhrMit strace haben wir uns die Schnittstelle zum Kern angeschaut und die syscall-Aufrufe protokolliert. Nun, das ist die eine Hälfte eines Programmes. Der andere Teil sind die Aufrufe von Funktionen.
Für jene, die noch nicht so sattelfest im Programmieren sind, denen sei in Stammbuch geschrieben. Programmierer sind faule Leute (es gibt aber noch andere Gründe ,-), und wenn man etwas mehrfach braucht, dann macht man eine Funktion daraus.
Ein Beispiel: getipnodebyaddr und getipnodebyname
Wir nehmen die C-Funktionen getipnodebyaddr und getipnodebyname als Beispiel. Beim Aufruf geben wir eine IP-Adresse mit und bekommen den Namen zurück. bzw geben wir den Namen an und bekommen die IP-Adresse. Woher der kommt wissen wir nicht. DNS-Server wären eine Option, /etc/hosts eine andere. Wir fragen nach der "www.linux-bibel.at" und bekommen "5.132.191.10" zurück.
Diese Funktion(en) kann man jetzt im Mail-Programm und im Browser-Programm verwenden. Daher lagert man, die Routinen in eigene library-Dateien aus und bindet die Library in beide Programme ein. Diese librarys erkennt man an der Namenskonversation .so bzw .a und sind oft unter /usr/lib gesammelt. Unter Windows ist dieses Prinzip unter dem Kürzel DLL bekannt.
Es gibt jetzt ein Programm namens ltrace. ltrace zeigt an, welche dieser Funktionen verwendet werden.
ltrace lsUnd man bekommt diese Ausgabe......
strrchr("ls", '/') = nil
setlocale(LC_ALL, "") = "de_AT.UTF-8"
bindtextdomain("coreutils", "/usr/share/locale") = "/usr/share/locale"
textdomain("coreutils") = "coreutils"
__cxa_atexit(0x562858ba2e00, 0, 0x562858bba008, 0) = 0
getopt_long(1, 0x7ffd9d019388, "abcdfghiklmnopqrstuvw:xABCDFGHI:"..., 0x562858bb9340, -1) = -1
getenv("LS_BLOCK_SIZE") = nil
getenv("BLOCK_SIZE") = nil
getenv("BLOCKSIZE") = nil
getenv("POSIXLY_CORRECT") = nil
getenv("BLOCK_SIZE") = nil
isatty(1) = 1
ioctl(1, 21523, 0x7ffd9d019220) = 0
getenv("TABSIZE") = nil
getenv("QUOTING_STYLE") = nilmit dem Kommando man <Funktion> bekommen wir eine Übersicht, was diese Funktion ausführt soll(te). Ansonsten ist der Funktionsumfang ähnlich dem Programm strace nur das es Lib-Aufrufe protokolliert.
Ja es könnte sein, dass sie das Programm installieren müssen. Dann gilt
sudo apt install ltraceUnd jetzt der nicht so schöne Harken an der Sache. Die Standard-Linux-Librarys sind alle wohl dokumentiert. Ich kann aber auch eigene Libs schreiben. Die Dokumentation muss ich nicht als man-page offen legen. Genau so wenig wie eine Firma ihren Source-Code veröffentlichen muss. Und damit beginnt das Problem. Projekt A benutzt "getipnodebyname" ein anderes Projekt benutzt eine andere Funktion die das gleiche machen könnte. Ich kann auch eine Funktion so kapseln, dass ich sie für andere Sprachen zur Verfügung stelle (z.B. Python, Java ). Wenn man ein Wayland-Programm über ltrace aufruft findet man jede Menge Funktionen, die u.U. nicht so einfach zu finden sind.
Vorteil an der Sache ist, dass Programmieren faule Leute sind und Dokumentationen nicht lieben. Bevor ich eine Funktion "xy123" überlege ich mir einen sprechenden Namen wie get_ip_node_by_name und damit ist der Name schon Dokumentation. 😉
Und wenn ich jetzt noch das _ Zeichen weg lasse..... 😀Zurück den Funktionen. Ich kann jetzt 3 Arten von Funktionen schreiben.
- In meinem Sourcecode direkt. Dann sind sie auch nur für mein eigenes Programm aufrufbar.
Verwendet für spezielle Berechnungen oder Abläufe die für das eine Programm spezialisiert sind.- Die statisch gelinkten .a Files
Diese werden zu meinen Source-Code "dazukopiert" und sind Bestandteil des Programmes. Ein Bespiel sind die "Notlauf-Programme" beim boot, wie fsck. Dieses muss alle Funktionen inkludieren, auch wenn das root-Filesystem nicht zur Verfügung steht. Bei Änderungen muss alles mindestens neu gelinkt werden. Die Programmgröße steigt beim statischen Linken.- Die shared-Library ist die 3. und letzte Art der Aufbewahrung. Vereinfacht dargestellt, wird die Library (.so Datei) einmal in den Speicher geladen und jedes Programm bekommt eine Kopie der Funktionen zur Laufzeit die es benötigt.
Vorteil dabei ist, dass bei Updates diese im laufenden Betrieb durchgeführt werden können. Sobald die Funktion geladen wird ist die Neue verfügbar.Für Anwenderprogramme werden Shared-Liberay hauptsächlich verwendet. Diese sind leicht auszutauschen und somit leicht und flexibel. Von der Laufzeit kann man Unterschiede messen, im praktischen Betrieb sind diese allerdings minimalst
ltrace zeigt uns alle "externen" dazu gelinkten Arten an.
In diesem Zusammenhang sind 2 weitere Programme sehr nützlich.
- Das programm "type"
type zweigt an, wo im Filesystem sich das Programm befindet. Und ggf den Type des Programmes.
eintype ls
liefert die Ausgabe
ls ist /usr/bin/ls
- ldd ist das zweite Programm.
Das Programm ldd liefert alle Shared-Library, die verwendet werden. ldd muss allerdings mit dem vollen Path angegeben werden. Wo das Programm zu Hause ist, haben wir gerade in Punkt 1 festgestellt. 😉ldd /usr/bin/ls
Du bekommst jetzt folgende Übersicht:
linux-vdso.so.1 (0x00007fd173302000)libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007fd17327e000)libcap.so.2 => /lib/x86_64-linux-gnu/libcap.so.2 (0x00007fd173272000)libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fd17307e000)libpcre2-8.so.0 => /lib/x86_64-linux-gnu/libpcre2-8.so.0 (0x00007fd172fcf000)/lib64/ld-linux-x86-64.so.2 (0x00007fd173304000)
Diese Library werden von ls benutzt, das wissen wir jetzt. Welche Funktionen inkludiert jetzt eine solche Library? Das ist gar nicht so einfach herauszufinden. Am einfachsten funktioniert es mit dem Kommando "objdump -T <path/library>"
Allerdings können sich auch weiterer Code in solchen Lib befinden.Anhand der Returncodes können wir eine Ahnung bekommen, wo der Fehler liegen könnte. Es sei nicht verschwiegen, dass es weitere Möglichkeiten gibt tiefer in den Code einzudringen. Aber das wird vielleicht ein weiterer Artikel.
Ich könnte mir vorstellen, dass die beiden Programme strace und ltrace euch helfen könnten, Probleme etwas einfacher aufzudecken.
Viel Spass dabei.
Mit strace haben wir uns die Schnittstelle zum Kern angeschaut und die syscall-Aufrufe protokolliert. Nun, das ist die eine Hälfte eines Programmes. Der andere Teil sind die Aufrufe von Funktionen.
Für jene, die noch nicht so sattelfest im Programmieren sind, denen sei in Stammbuch geschrieben. Programmierer sind faule Leute (es gibt aber noch andere Gründe ,-), und wenn man etwas mehrfach braucht, dann macht man eine Funktion daraus.
Ein Beispiel: getipnodebyaddr und getipnodebyname
Wir nehmen die C-Funktionen getipnodebyaddr und getipnodebyname als Beispiel. Beim Aufruf geben wir eine IP-Adresse mit und bekommen den Namen zurück. bzw geben wir den Namen an und bekommen die IP-Adresse. Woher der kommt wissen wir nicht. DNS-Server wären eine Option, /etc/hosts eine andere. Wir fragen nach der "www.linux-bibel.at" und bekommen "5.132.191.10" zurück.
Diese Funktion(en) kann man jetzt im Mail-Programm und im Browser-Programm verwenden. Daher lagert man, die Routinen in eigene library-Dateien aus und bindet die Library in beide Programme ein. Diese librarys erkennt man an der Namenskonversation .so bzw .a und sind oft unter /usr/lib gesammelt. Unter Windows ist dieses Prinzip unter dem Kürzel DLL bekannt.
Es gibt jetzt ein Programm namens ltrace. ltrace zeigt an, welche dieser Funktionen verwendet werden.
ltrace ls
Und man bekommt diese Ausgabe......
strrchr("ls", '/') = nil
setlocale(LC_ALL, "") = "de_AT.UTF-8"
bindtextdomain("coreutils", "/usr/share/locale") = "/usr/share/locale"
textdomain("coreutils") = "coreutils"
__cxa_atexit(0x562858ba2e00, 0, 0x562858bba008, 0) = 0
getopt_long(1, 0x7ffd9d019388, "abcdfghiklmnopqrstuvw:xABCDFGHI:"..., 0x562858bb9340, -1) = -1
getenv("LS_BLOCK_SIZE") = nil
getenv("BLOCK_SIZE") = nil
getenv("BLOCKSIZE") = nil
getenv("POSIXLY_CORRECT") = nil
getenv("BLOCK_SIZE") = nil
isatty(1) = 1
ioctl(1, 21523, 0x7ffd9d019220) = 0
getenv("TABSIZE") = nil
getenv("QUOTING_STYLE") = nil
mit dem Kommando man <Funktion> bekommen wir eine Übersicht, was diese Funktion ausführt soll(te). Ansonsten ist der Funktionsumfang ähnlich dem Programm strace nur das es Lib-Aufrufe protokolliert.
Ja es könnte sein, dass sie das Programm installieren müssen. Dann gilt
sudo apt install ltrace
Und jetzt der nicht so schöne Harken an der Sache. Die Standard-Linux-Librarys sind alle wohl dokumentiert. Ich kann aber auch eigene Libs schreiben. Die Dokumentation muss ich nicht als man-page offen legen. Genau so wenig wie eine Firma ihren Source-Code veröffentlichen muss. Und damit beginnt das Problem. Projekt A benutzt "getipnodebyname" ein anderes Projekt benutzt eine andere Funktion die das gleiche machen könnte. Ich kann auch eine Funktion so kapseln, dass ich sie für andere Sprachen zur Verfügung stelle (z.B. Python, Java ). Wenn man ein Wayland-Programm über ltrace aufruft findet man jede Menge Funktionen, die u.U. nicht so einfach zu finden sind.
Vorteil an der Sache ist, dass Programmieren faule Leute sind und Dokumentationen nicht lieben. Bevor ich eine Funktion "xy123" überlege ich mir einen sprechenden Namen wie get_ip_node_by_name und damit ist der Name schon Dokumentation. 😉
Und wenn ich jetzt noch das _ Zeichen weg lasse..... 😀
Zurück den Funktionen. Ich kann jetzt 3 Arten von Funktionen schreiben.
- In meinem Sourcecode direkt. Dann sind sie auch nur für mein eigenes Programm aufrufbar.
Verwendet für spezielle Berechnungen oder Abläufe die für das eine Programm spezialisiert sind. - Die statisch gelinkten .a Files
Diese werden zu meinen Source-Code "dazukopiert" und sind Bestandteil des Programmes. Ein Bespiel sind die "Notlauf-Programme" beim boot, wie fsck. Dieses muss alle Funktionen inkludieren, auch wenn das root-Filesystem nicht zur Verfügung steht. Bei Änderungen muss alles mindestens neu gelinkt werden. Die Programmgröße steigt beim statischen Linken. - Die shared-Library ist die 3. und letzte Art der Aufbewahrung. Vereinfacht dargestellt, wird die Library (.so Datei) einmal in den Speicher geladen und jedes Programm bekommt eine Kopie der Funktionen zur Laufzeit die es benötigt.
Vorteil dabei ist, dass bei Updates diese im laufenden Betrieb durchgeführt werden können. Sobald die Funktion geladen wird ist die Neue verfügbar.
Für Anwenderprogramme werden Shared-Liberay hauptsächlich verwendet. Diese sind leicht auszutauschen und somit leicht und flexibel. Von der Laufzeit kann man Unterschiede messen, im praktischen Betrieb sind diese allerdings minimalst
ltrace zeigt uns alle "externen" dazu gelinkten Arten an.
In diesem Zusammenhang sind 2 weitere Programme sehr nützlich.
- Das programm "type"
type zweigt an, wo im Filesystem sich das Programm befindet. Und ggf den Type des Programmes.
eintype ls
liefert die Ausgabe
ls ist /usr/bin/ls
- ldd ist das zweite Programm.
Das Programm ldd liefert alle Shared-Library, die verwendet werden. ldd muss allerdings mit dem vollen Path angegeben werden. Wo das Programm zu Hause ist, haben wir gerade in Punkt 1 festgestellt. 😉ldd /usr/bin/ls
Du bekommst jetzt folgende Übersicht:
linux-vdso.so.1 (0x00007fd173302000)libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007fd17327e000)libcap.so.2 => /lib/x86_64-linux-gnu/libcap.so.2 (0x00007fd173272000)libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fd17307e000)libpcre2-8.so.0 => /lib/x86_64-linux-gnu/libpcre2-8.so.0 (0x00007fd172fcf000)/lib64/ld-linux-x86-64.so.2 (0x00007fd173304000)
Diese Library werden von ls benutzt, das wissen wir jetzt. Welche Funktionen inkludiert jetzt eine solche Library? Das ist gar nicht so einfach herauszufinden. Am einfachsten funktioniert es mit dem Kommando "objdump -T <path/library>"
Allerdings können sich auch weiterer Code in solchen Lib befinden.
Anhand der Returncodes können wir eine Ahnung bekommen, wo der Fehler liegen könnte. Es sei nicht verschwiegen, dass es weitere Möglichkeiten gibt tiefer in den Code einzudringen. Aber das wird vielleicht ein weiterer Artikel.
Ich könnte mir vorstellen, dass die beiden Programme strace und ltrace euch helfen könnten, Probleme etwas einfacher aufzudecken.
Viel Spass dabei.