Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger

 << zurück
Linux-UNIX-Programmierung von Jürgen Wolf
Das umfassende Handbuch – 2., aktualisierte und erweiterte Auflage 2006
Buch: Linux-UNIX-Programmierung

Linux-UNIX-Programmierung
1216 S., mit CD, 49,90 Euro
Rheinwerk Computing
ISBN 3-89842-749-8
gp Kapitel 17 Werkzeuge für Programmierer
  gp 17.1 Make
    gp 17.1.1 Erzeugen eines Makefiles
    gp 17.1.2 Variablen, Makros und Abkürzungen
    gp 17.1.3 Implizite Regeln
    gp 17.1.4 Musterregeln
    gp 17.1.5 make zur Installation verwenden
    gp 17.1.6 make-Optionen
    gp 17.1.7 Ausblick
  gp 17.2 Bibliotheken erstellen
    gp 17.2.1 Statische Bibliotheken erstellen
    gp 17.2.2 Dynamische Bibliotheken (Shared Libraries) erstellen
    gp 17.2.3 Dynamisches Nachladen von Bibliotheken
  gp 17.3 RPM
    gp 17.3.1 Verzeichnisse, die RPM benötigt
    gp 17.3.2 Ein eigenes RPM-Paket erstellen
    gp 17.3.3 Sources
    gp 17.3.4 Die Spec-Datei
    gp 17.3.5 Paket erstellen
    gp 17.3.6 Das Paket installieren
  gp 17.4 RCS und CVS
    gp 17.4.1 Software-Configuration-Management-Systeme (SCM)
    gp 17.4.2 RCS
    gp 17.4.3 CVS
  gp 17.5 Zeitmessung von Programmen
    gp 17.5.1 Einfache Zeitmessung mit TIME – Laufzeit von Prozessen
    gp 17.5.2 Profiling mit GPROF – Laufzeit von Funktionen
    gp 17.5.3 Analyse mit GCOV
  gp 17.6 Debuggen mit gdb und ddd
  gp 17.7 STRACE – Systemaufrufe verfolgen
  gp 17.8 Memory Leaks und unerlaubte Speicherzugriffe
    gp 17.8.1 efence
    gp 17.8.2 valgrind
  gp 17.9 Ausblick


Rheinwerk Computing

17.7 STRACE – Systemaufrufe verfolgen  toptop

STRACE ist ein Werkzeug, das konsequent die Systemaufrufe anzeigt, die ein laufendes Programm ausführt. Dabei befindet sich STRACE praktisch als Schnittstelle zwischen dem Programm und dem Kernel. Wird beispielsweise ein einfacher printf()-Aufruf verwendet, können Sie sich mit STRACE anzeigen lassen, wie die Ausgabe eigentlich stattfindet – sprich, wie es z. B. von der Funktion printf() zum eigentlichen Systemcall kommt. Sie wissen zwar wahrscheinlich, dass printf() mit write() realisiert wurde, aber dessen sind sich viele Programmierer nicht bewusst. STRACE wird gerne für folgende Aufgabe verwendet:

gp  Personen, die sich mit der Kernel-Programmierung auseinander setzen wollen, lernen mit STRACE die Systemaufrufe und Programmiertechniken kennen, die für das Zusammenspiel von Software und dem Betriebssystem (Kernel) nötig sind.
gp  Debuggen von Software, wenn sich diese ein wenig seltsam verhält oder dauernd abstürtzt – was mit STRACE auch ohne den Quelltext möglich ist!
gp  Herausfinden von Geschwindigkeitsbremsen von Software, deren Quelltext nicht vorhanden ist.

Hinweis   Damit STRACE auch die Systemaufrufe, die eine Software abgibt, protokollieren kann, muss dies der Kernel natürlich auch unterstützen. Diese Unterstützung wird letztendlich auch nur wieder mit einem Systemaufruf (ptrace()) realisiert.


Die Ausgabe des STRACE-Protokolls kann enorm lang werden, weshalb hier nur als Beispiel die Ausgabe des Protokolls vom Hallo Welt-Programm erfolgt.

#include <stdio.h>
int main(void) {
 printf("Hallo Welt\n");
 return 0;
}

Hierzu das STRACE-Protokoll:

$ strace hallo
execve("./hallo", ["./hallo"], [/* 65 vars */]) = 0
uname({sys="Linux", node="linux", ...}) = 0
brk(0)                                  = 0x8049548
open("/etc/ld.so.preload", O_RDONLY)    = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY)      = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=70568, ...}) = 0
old_mmap(NULL, 70568, PROT_READ, MAP_PRIVATE, 3, 0) = 0x40015000
close(3)                                = 0
open("/lib/libc.so.6", O_RDONLY)        = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0pY\1\000"..., 1024) = 1024
fstat64(3, {st_mode=S_IFREG|0755, st_size=1491599, ...}) = 0
old_mmap(NULL, 1268004, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x40027000
mprotect(0x40156000, 26916, PROT_NONE)  = 0
old_mmap(0x40156000, 16384, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 
3, 0x12f000) = 0x40156000
old_mmap(0x4015a000, 10532, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|
MAP_ANONYMOUS, -1, 0) = 0x4015a000
close(3)                                = 0
munmap(0x40015000, 70568)               = 0
fstat64(1, {st_mode=S_IFCHR|0600, st_rdev=makedev(136, 4), ...}) = 0
old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 
-1, 0) = 0x40015000
write(1, "Hallo Welt\n", 11)            = 11
munmap(0x40015000, 4096)                = 0
exit_group(0)                           = ?

Mit diesem Aufruf bekommen Sie eine Menge Systemaufrufe angezeigt, die sich gar nicht unmittelbar im Quellcode befinden und dennoch ausgeführt werden. Die komplette Ausgabe wurde auf die Standardfehlerausgabe gemacht, womit Sie die Möglichkeit haben, diese Meldungen von der Standardfehlerausgabe des Programms in eine Datei zu schreiben. Bei der Ausgabe können Sie auch erkennen, dass STRACE nicht nur die Namen der Systemcalls ausgibt, sondern auch alle Parameter und sogar die Rückgabewerte. Sie sehen dabei auch, welch ein Aufwand betrieben wird, bis es zur Ausgabe des Strings mittels

write(1, "Hallo Welt\n", 11)            = 11

kommt. Ganz zu Beginn finden Sie gewöhnlich immer den execve()-Aufruf, der das Programm selbst startet. Der komplette zusätzliche Code wird zum Starten und Ausführen des Programms benötigt. So wird z. B. die C-Standardbibliothek dynamisch in dem Speicherbereich des Prozesses eingeblendet:

open("/lib/libc.so.6", O_RDONLY)        = 3

Die anderen Systemaufrufe wie old_mmap und munmap werden für die Verwaltung von dynamischem Speicher verwendet, der für die Anwendung nötigt ist.

Neben der eben gezeigten Verwendung von STRACE, lässt sich mithilfe von verschiedenen Optionen eine noch detailliertere Ausgabe erreichen. Einige mögliche Optionen hierzu wären:


Tabelle 17.5    Einige von vielen strace-Aufrufen

Aufruf Bedeutung
strace hallo Startet hallo und gibt dessen Systemaufrufe auf dem Bildschirm aus
strace -o hallo.log hallo Ausgabe in hallo.log-Logdatei
strace -f -o hallo.log hallo Verfolgt auch Kindprozesse
strace -p pid Verfolgt die Aufrufe des laufenden Prozesses mit der PID pid
strace -e trace=open,write hallo Gibt nur Systemaufrufe aus, die das Dateimanagement betreffen (hier open und write)

Als Ausblick lässt sich zu strace sagen, dass dieses Werkzeug sehr hilfreich ist, um gewisse Abläufe zwischen dem Kernel und dem Prozess zu verstehen. Ganz klarer Vorteil von diesem Tool ist, dass hierbei der Quelltext nicht vorliegen muss, um damit arbeiten zu können. Allerdings stellt das Tool eine ziemlich hohe Anforderung an den Entwickler und richtet sich vorwiegend an Programmierer, die sich mit der Kernel-Programmierung auseinander setzen müssen.

 << zurück
  
  Zum Rheinwerk-Shop
Neuauflage: Linux-UNIX-Programmierung
Neuauflage:
Linux-UNIX-
Programmierung

bestellen
 Ihre Meinung?
Wie hat Ihnen das Openbook gefallen?
Ihre Meinung

 Buchtipps
Zum Rheinwerk-Shop: Linux-Server






 Linux-Server


Zum Rheinwerk-Shop: Das Komplettpaket LPIC-1 & LPIC-2






 Das Komplettpaket
 LPIC-1 & LPIC-2


Zum Rheinwerk-Shop: Linux-Hochverfügbarkeit






 Linux-
 Hochverfügbarkeit


Zum Rheinwerk-Shop: Shell-Programmierung






 Shell-
 Programmierung


Zum Rheinwerk-Shop: Linux Handbuch






 Linux Handbuch


 Lieferung
Versandkostenfrei bestellen in Deutschland, Österreich und der Schweiz
Info





Copyright © Rheinwerk Verlag GmbH 2006
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das Openbook denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt.
Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


Nutzungsbestimmungen | Datenschutz | Impressum

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de

Cookie-Einstellungen ändern