| 1 Los geht's | 1 |
| 1.1 Die Sache mit der Armbanduhr | 1 |
| 1.2 Das Besondere an Linux | 2 |
| 1.3 Den Fehler reproduzieren | 3 |
| 1.4 Die exakte Ursache finden | 5 |
| 1.4.1 | Der Einblick | 5 |
| 1.4.2 | Spurensuche | 6 |
| 1.4.3 | Die Wirkungskette | 6 |
| 1.4.4 | Der wandernde Fehler | 8 |
| 1.4.5 | Wechselnde Umstände | 8 |
| 1.4.6 | Reine Geisteskraft | 9 |
| 1.5 Den Fehler beheben | 9 |
| 1.6 Ein Wort zur 2. Auflage | 10 |
| 2 Dokumentation und Recherche | 13 |
| 2.1 Dokumentation | 14 |
| 2.1.1 | Erste und zweite Hand | 14 |
| 2.1.2 | Bücher | 15 |
| 2.1.3 | Man-Seiten | 15 |
| 2.1.4 | GNU Texinfo | 18 |
| 2.1.5 | Artikel aus dem Internet | 19 |
| 2.1.6 | Dokumentation in RPM-Paketen | 20 |
| 2.1.7 | Request For Comments (RFC) | 21 |
| 2.1.8 | Dateien unter /usr/share/doc | 21 |
| 2.2 Hilfeartikel, HOWTOs und FAQs | 22 |
| 2.2.1 | HOWTOs | 22 |
| 2.2.2 | SUSE-{Supportdatenbank} (SDB) | 22 |
| 2.2.3 | Die Linux Problem Base | 23 |
| 2.2.4 | FAQs | 23 |
| 2.3 Newsgruppen und Mailinglisten | 23 |
| 2.4 Das Linux Documentation Project (LDP) | 24 |
| 2.5 Quellcode | 25 |
| 3 Logdateien und Debugausgabe | 27 |
| 3.1 Der System Logging Daemon | 28 |
| 3.1.1 | Funktionsweise des syslogd | 28 |
| 3.1.2 | Loggen über das Netzwerk | 29 |
| 3.1.3 | Meldungen sortieren | 30 |
| 3.1.4 | Meldungen speichern oder weiterleiten | 33 |
| 3.1.5 | Erzeugen von Logmeldungen aus Shellskripten | 34 |
| 3.1.6 | Erzeugen von Logmeldungen aus C-Programmen | 36 |
| 3.2 Logdateien analysieren mit logsurfer | 36 |
| 3.2.1 | Funktionsweise von logsurfer | 36 |
| 3.2.2 | logsurfer vorbereiten | 37 |
| 3.2.3 | logsurfer aufrufen | 38 |
| 3.2.4 | logsurfer an syslogd anbinden | 39 |
| 3.3 Shellskripte verfolgen mit bash -x | 41 |
| 4 Aktive Diagnose | 45 |
| 4.1 Dateien | 46 |
| 4.1.1 | Textdateien effizient anzeigen mit less}} | 48 |
| 4.1.2 | Logdateien anzeigen mit tail -f oder less +F | 49 |
| 4.1.3 | Sich ändernde Ausgaben anzeigen mit watch | 50 |
| 4.1.4 | Dateityp feststellen mittels file | 51 |
| 4.1.5 | Suche innerhalb von Textdateien mit grep | 52 |
| 4.1.6 | {Konfigurationsdateien abspecken mit grep -Ev '^(#|$)'}} | 54 |
| 4.1.7 | Dateien dem Namen und Typ nach finden mit find | 56 |
| 4.1.8 | Schnelles Suchen mit locate statt find | 58 |
| 4.1.9 | Die Nadel finden: grep, find und xargs | 60 |
| 4.1.10 | Dateien aus RPM -Paketen untersuchen mit rpm | 61 |
| 4.1.11 | Fehlende Dateien finden auf der SUSE-CD/DVD | 63 |
| 4.1.12 | Ort eines Befehls feststellen mit which | 64 |
| 4.1.13 | änderungen in Textdateien aufspüren mit diff | 65 |
| 4.1.14 | Texte in Binärdateien finden mittels strings | 66 |
| 4.1.15 | Binärdateien anzeigen mit hexdump | 68 |
| 4.1.16 | änderungen in Binärdateien vornehmen | 69 |
| 4.1.17 | Binärdateien vergleichen mit cmp | 71 |
| 4.2 Festplatten und Dateisysteme | 72 |
| 4.2.1 | Festplatten und Partitionen anzeigen mit fdisk | 72 |
| 4.2.2 | Gemountete Dateisysteme anzeigen mit mount | 74 |
| 4.2.3 | Freien Platz anzeigen mit df | 75 |
| 4.3 Prozesse | 78 |
| 4.3.1 | Prozessbaum anzeigen mit pstree | 78 |
| 4.3.2 | Prozessliste mit {ps} | 80 |
| 4.3.3 | Prozessmonitor top | 81 |
| 4.3.4 | Prozess-IDs ermitteln mit pidof | 84 |
| 4.3.5 | Offene Dateien anzeigen mit lsof | 84 |
| 4.3.6 | Alle Informationen aus erster Hand unter /proc | 86 |
| 4.4 Benutzer und Gruppen | 88 |
| 4.4.1 | Gruppen eines Benutzers anzeigen mit id | 88 |
| 4.4.2 | Benutzer und Gruppe eines Prozesses anzeigen mit ps | 89 |
| 4.4.3 | Alle Gruppen eines Prozesses anzeigen | 90 |
| 4.5 Der Bootvorgang | 91 |
| 4.5.1 | Der Bootvorgang im kurzen überblick | 91 |
| 4.5.2 | Bootmeldungen | 94 |
| 4.5.3 | Booten in andere Runlevel | 94 |
| 4.5.4 | Systemrettung im Runlevel S | 96 |
| 4.5.5 | Booten ohne Passwort | 98 |
| 4.5.6 | Booten ohne Bibliotheken mit der sash | 99 |
| 4.5.7 | Das SUSE-Rettungssystem | 102 |
| 4.6 Kernel | 104 |
| 4.6.1 | Version, Lebensalter und Speicherverbrauch | 105 |
| 4.6.2 | Module | 106 |
| 4.6.3 | Kernelparameter | 108 |
| 5 Hardwarediagnose | 109 |
| 5.1 Prozessor, Speicher und andere innere Werte | 110 |
| 5.1.1 | Der Prozessor und /proc/cpuinfo | 110 |
| 5.1.2 | Informationen aus ACPI | 111 |
| 5.1.3 | ACPI: Prozessor | 112 |
| 5.1.4 | ACPI: Stromverbrauch und Akkus | 113 |
| 5.1.5 | ACPI: Temperatur | 115 |
| 5.1.6 | Hauptspeicher | 116 |
| 5.1.7 | Hardwareuhr und Systemzeit , hwclock und date | 116 |
| 5.2 Allgemeines zur Peripherie | 118 |
| 5.2.1 | Grundprinzip des Prozessorbus | 118 |
| 5.2.2 | Zugriff auf Peripheriebausteine | 119 |
| 5.2.3 | Interrupts und /proc/interrupts | 120 |
| 5.2.4 | IO-Ports und /proc/ioports | 121 |
| 5.3 Bussysteme und Steckkarten | 122 |
| 5.3.1 | Grundprinzip des Erweiterungsbus | 122 |
| 5.3.2 | Verschiedene Bussysteme | 123 |
| 5.3.3 | PCI | 124 |
| 5.3.4 | Liste aller PCI-Geräte mit lspci | 125 |
| 5.3.5 | PCI Vendor- und Device-IDs | 128 |
| 5.4 Externe Schnittstellen | 128 |
| 5.4.1 | Grundprinzip der seriellen Datenübertragung | 128 |
| 5.4.2 | Serielle Schnittstellen testen mit echo und cat | 130 |
| 5.4.3 | Serielle Geräte testen über Interrupts | 132 |
| 5.4.4 | Serielle Geräte testen mit minicom | 133 |
| 5.4.5 | Die parallele Schnittstelle | 134 |
| 5.4.6 | Die Tastatur | 136 |
| 5.4.7 | PS/2 -Maus | 137 |
| 5.4.8 | Allgemeines zu USB | 138 |
| 5.4.9 | USB-Diagnose unter Linux | 143 |
| 5.5 Laufwerke | 148 |
| 5.5.1 | Das Diskettenlaufwerk | 148 |
| 5.5.2 | Allgemeines zu IDE /ATA und ATAPI | 151 |
| 5.5.3 | IDE-Diagnose mit Linux | 152 |
| 5.5.4 | Performancekontrolle bei DMA und PIO | 156 |
| 5.5.5 | Allgemeines zu SCSI | 158 |
| 5.5.6 | Einfache SCSI-Diagnose unter Linux | 158 |
| 5.5.7 | Informationen aus /proc/scsi | 160 |
| 6 Netzwerkdiagnose | 163 |
| 6.1 Einteilung in Schichten | 163 |
| 6.2 Die Hardwareschicht | 165 |
| 6.2.1 | Netzwerkgeräte | 165 |
| 6.2.2 | Aktivierung und Konfiguration der Geräte mit ifconfig | 166 |
| 6.2.3 | Medium und übetragungsart ermitteln mit mii-diag | 167 |
| 6.2.4 | MAC-Adressen und ARP | 169 |
| 6.2.5 | Punkt-zu-Punkt Verbindungen mit PPP | 170 |
| 6.3 Das Internetprotokoll (IP) | 174 |
| 6.3.1 | Grundsätzliches zu IP | 174 |
| 6.3.2 | Internetadressen | 175 |
| 6.3.3 | Verbindungstest mit ping | 182 |
| 6.3.4 | Weitere Möglichkeiten von ping | 184 |
| 6.3.5 | Bandbreitenschätzung mit bing | 187 |
| 6.3.6 | Routen verfolgen mit traceroute | 189 |
| 6.4 TCP und UDP | 191 |
| 6.4.1 | Grundsätzliches zu TCP | 191 |
| 6.4.2 | TCP-Verbindungen testen mit telnet | 192 |
| 6.4.3 | Grundsätzliches zu UDP | 196 |
| 6.4.4 | TCP und UDP testen mit netcat / nc | 198 |
| 6.4.5 | Sockets und Verbindungen beobachten mit netstat | 201 |
| 6.4.6 | Offene Ports finden mit nmap | 204 |
| 6.4.7 | Netzwerkverkehr mithören mit tcpdump | 206 |
| 6.5 Namensauflösung mittels DNS | 213 |
| 6.5.1 | DNS-Anfrage in Einzelschritten | 214 |
| 6.5.2 | Probleme mit DNS: Zwei unterschiedliche Symptome | 215 |
| 6.5.3 | Diagnose von DNS-Problemen | 216 |
| 6.5.4 | DNS Anfragen mit tcpdump analysieren | 217 |
| 6.6 Diagnose von iptables | 220 |
| 6.6.1 | Paketfilter und Firewall | 220 |
| 6.6.2 | Die drei Regelketten | 221 |
| 6.6.3 | Ketten anzeigen | 222 |
| 6.6.4 | Paketzähler | 223 |
| 6.6.5 | Logmeldungen | 224 |
| 6.7 Weitere Diagnosewerkzeuge | 225 |
| 6.8 Ein ausführliches Beispiel | 226 |
| 6.8.1 | Das Beispiel | 226 |
| 6.8.2 | Die Wirkungskette | 227 |
| 6.8.3 | Diagnose mit ping | 227 |
| 6.8.4 | Link testen mit mii-diag | 229 |
| 6.8.5 | Routingprobleme | 229 |
| 6.8.6 | Einwahl per DSL | 230 |
| 6.8.7 | DNS | 232 |
| 6.8.8 | POP3-Server | 233 |
| 6.8.9 | Fazit | 234 |
| 7 Programme und Prozesse | 235 |
| 7.1 Untersuchen von Binaries | 235 |
| 7.1.1 | Dynamische Bibliotheken unter Linux | 235 |
| 7.1.2 | Verwendete Bibliotheken auflisten mit ldd | 238 |
| 7.1.3 | Binaries analysieren mit objdump | 239 |
| 7.2 System- und Bibliotheksaufrufe | 241 |
| 7.2.1 | Grundsätzliches zu Systemaufrufen | 241 |
| 7.2.2 | Systemaufrufe protokollieren mit strace | 242 |
| 7.2.3 | Wichtige Systemaufrufe | 245 |
| 7.2.4 | Systemaufrufe: Dateizugriffe | 245 |
| 7.2.5 | Systemaufrufe: Verzeichnisse und Dateiattribute | 248 |
| 7.2.6 | Systemaufrufe: Netzwerk | 249 |
| 7.2.7 | Systemaufrufe: UIDs und GIDs | 250 |
| 7.2.8 | Systemaufrufe: Warten | 251 |
| 7.2.9 | Systemaufrufe: Erzeugen und Beenden von Prozessen | 254 |
| 7.2.10 | Systemaufrufe: Speicherverwaltung und übriges | 257 |
| 7.2.11 | strace in der Praxis | 258 |
| 7.2.12 | Beispiel: xscanimage als normaler Benutzer verwenden | 261 |
| 7.2.13 | Bibliotheksaufrufe anzeigen mit ltrace | 263 |
| 7.3 Signale | 265 |
| 7.3.1 | Was sind Signale? | 265 |
| 7.3.2 | Signale senden mit kill und killall | 269 |
| 7.3.3 | Ein kleines Programm zum Testen von Signalen | 270 |
| 7.3.4 | Segmentfehler (segmentation fault) | 271 |
| 7.3.5 | Möglichkeiten, mit einem Segmentfehler umzugehen | 272 |
| 7.4 Debugging unter Linux | 273 |
| 7.4.1 | Was ist ein Debugger? | 273 |
| 7.4.2 | Der GNU-Debugger gdb | 274 |
| 7.4.3 | Starten von Programmen unter gdb | 274 |
| 7.4.4 | Allgemeines zum Aufrufstapel | 276 |
| 7.4.5 | Aufrufstapel mit gdb untersuchen | 278 |
| 7.4.6 | Ein chirurgischer Eingriff | 279 |
| 7.4.7 | Andocken an laufende Prozesse | 281 |
| 7.4.8 | Untersuchen von Coredumps | 282 |
| 7.4.9 | Die Bedienung des GNU-Debuggers | 284 |
| 7.4.10 | Eine spektakuläre Rettungsaktion | 285 |
| 8 An die Quellen | 291 |
| 8.1 Nur kein Respekt! | 291 |
| 8.2 Interpretersprachen vs. Compilersprachen | 292 |
| 8.3 Interpretersprachen | 293 |
| 8.3.1 | Allgemeines zu Interpretersprachen | 293 |
| 8.3.2 | Shellskripte | 294 |
| 8.3.3 | Perl | 297 |
| 8.3.4 | PHP | 299 |
| 8.3.5 | Python | 300 |
| 8.4 Compilersprachen | 302 |
| 8.4.1 | Quellcodes besorgen | 303 |
| 8.4.2 | Entwicklungswerkzeuge vorbereiten | 303 |
| 8.4.3 | Fremde Quellen auspacken | 304 |
| 8.4.4 | In den Quellen recherchieren | 309 |
| 8.4.5 | Fundstellen im Linux-Kernel | 314 |
| 8.4.6 | übersetzen der Quellen bei Tarbällen mittels make | 317 |
| 8.4.7 | autoconf und automake | 319 |
| 8.4.8 | übersetzen der Quellen bei Source-RPMs | 324 |
| 8.4.9 | überprüfen der Kompilation | 326 |
| 8.4.10 | Installieren | 326 |
| 8.4.11 | Den Fehler festnageln | 327 |
| 8.4.12 | änderungen machen | 327 |
| 8.4.13 | printf-Debugging | 328 |
| 8.4.14 | Debug-Ausgabe in C und C++ | 329 |
| 8.5 printf-Debugging im Kernel | 332 |
| 8.5.1 | Vorbereitungen | 332 |
| 8.5.2 | Den Kernel übersetzen | 333 |
| 8.5.3 | Den Kernel installieren | 333 |
| 8.5.4 | Meldungen ausgeben mit printk | 334 |
| 8.5.5 | Ein komplettes Beispiel | 335 |
| 8.6 Den Fehler beheben | 338 |
| 8.6.1 | Einen Patch erstellen | 338 |
| 8.6.2 | Den Patch testen | 340 |
| 8.6.3 | Den Patch in das RPM einbauen | 341 |
| 8.6.4 | Dem Autor den Patch schicken | 343 |
| 9 Performanceprobleme | 345 |
| 9.1 Zeitmessung | 346 |
| 9.1.1 | Zeitmessung bei Befehlen | 346 |
| 9.1.2 | Differentielle Zeitmessung | 349 |
| 9.1.3 | Zeitmessung bei Serverdiensten | 351 |
| 9.1.4 | Zeitmessung von laufenden Prozessen | 353 |
| 9.2 Speicherengpässe und Swappen | 356 |
| 9.3 Festplatten | 359 |
| 9.3.1 | Lese- und Positionierungsgeschwindigkeit | 359 |
| 9.3.2 | Partitionsgrößen | 360 |
| 9.3.3 | Der Einfluss von Caches | 360 |
| 9.3.4 | Raw-Devices | 362 |
| 9.4 Einfluss des Dateisystems | 362 |
| 9.5 Netzwerk | 364 |
| 9.5.1 | Bandbreitenmessung mit iptraf | 365 |
| 9.5.2 | Laufzeiten messen mit ping | 371 |
| 9.5.3 | Wartezeiten | 373 |
| 9.5.4 | Zusammenfassung | 376 |
| 9.6 Kompression von Daten | 376 |
| 9.6.1 | Grundüberlegungen | 376 |
| 9.6.2 | OpenSSH | 377 |
| 9.7 Verschlüsselung | 379 |
| 9.7.1 | Performance unterschiedlicher Algorithmen | 379 |
| 9.7.2 | Algorithmus wählen bei OpenSSH | 380 |
| A Handwerkszeug | 383 |
| A.1 Effizientes Arbeiten mit der Bash | 383 |
| A.1.1 | Die Tabulatortaste | 383 |
| A.1.2 | Die Historie | 385 |
| A.1.3 | Die geschweiften Klammern { und }} | 386 |
| A.2 Wichtige Funktionen der Shell | 388 |
| A.2.1 | Backslashes und Anführungszeichen | 388 |
| A.2.2 | Ausgabeumlenkung | 390 |
| A.2.3 | Pipes | 391 |
| A.2.4 | Kommandoersetzung | 391 |
| A.3 Texteditoren | 393 |
| A.3.1 | vi | 394 |
| A.3.2 | joe | 395 |
| A.3.3 | jmacs | 396 |
| A.3.4 | zile | 397 |
| A.3.5 | mcedit | 398 |
| A.4 Reguläre Ausdrücke | 399 |
| A.4.1 | Regeln | 399 |
| A.4.2 | weitere Beispiele | 404 |
| A.4.3 | einfache und erweiterte reguläre Ausdrücke | 404 |
| A.5 Hexadezimalzahlen | 405 |
| A.5.1 | Der Name | 405 |
| A.5.2 | Der Sinn | 405 |
| A.5.3 | Das Umrechnen | 406 |
| A.6 Die Verzeichnisstruktur von Linux | 407 |
| A.6.1 | Der Filesystem Hierarchy Standard | 407 |
| A.6.2 | Die Rootpartition | 408 |
| A.6.3 | Das Wurzelverzeichnis | 408 |
| A.6.4 | Die /usr-Hierarchie | 411 |
| A.6.5 | Die /var-Hierarchie | 413 |
| B Alle Werkzeuge | 415 |
| B.1 Nachinstallieren von Software | 415 |
| B.2 Diagnosewerkzeuge | 416 |
| B.3 Entwicklungswerkzeuge | 423 |