Kapitel 18. Weiterführende Themen

18.1. Wie kann ich mehr über die Interna von FreeBSD erfahren?
18.2. Wie kann ich bei der Entwicklung von FreeBSD mithelfen?
18.3. Was sind Snapshots und Releases?
18.4. Ich habe eine Kernelerweiterung geschrieben. An wen sende ich sie?
18.5. Wie kann ich optimalen Nutzen aus einer kernel panic ziehen?
18.6. Wieso funktioniert dlsym() nicht mehr für ELF-Executables?
18.7. Wie kann ich den Adressraum des Kernels auf i386 vergrössern oder verkleinern?

18.1.

Wie kann ich mehr über die Interna von FreeBSD erfahren?

Lesen Sie das FreeBSD Architecture Handbook.

Allgemeines Wissen über UNIX® kann allerdings in den meisten Fällen auf FreeBSD angewendet werden.

18.2.

Wie kann ich bei der Entwicklung von FreeBSD mithelfen?

Genauere Informationen finden Sie im Artikel FreeBSD unterstützen. Wir können Hilfe immer gut gebrauchen!

18.3.

Was sind Snapshots und Releases?

Derzeit existieren drei aktive/halbaktive Zweige im FreeBSD Subversion Repository. In früheren Zweigen ändert sich wenig, daher gibt es nur drei aktive Entwicklungszweige:

  • stable/9/ bzw. 9-STABLE

  • stable/10/ bzw. 10-STABLE

  • head/ bzw. -CURRENT oder auch 11-CURRENT

HEAD ist keine wirkliche Bezeichnung für einen Zweig. Es ist lediglich eine symbolische Konstante für den aktuellen, nicht verzweigten Entwicklungsstrom, auf den wir uns einfach als -CURRENT beziehen.

Derzeit steht -CURRENT für den 11.X-Entwicklungsstrom. Der 10-STABLE-Zweig (stable/10) wurde von -CURRENT im Januar 2014 und der 9-STABLE-Zweig (stable/9) im September 2011 von -CURRENT abgespalten.

18.4.

Ich habe eine Kernelerweiterung geschrieben. An wen sende ich sie?

Lesen Sie den Artikel FreeBSD unterstützen.

Und Danke, dass Sie darüber nachdenken!

18.5.

Wie kann ich optimalen Nutzen aus einer kernel panic ziehen?

Hier ist eine typische Kernel-Panic:

Fatal trap 12: page fault while in kernel mode
fault virtual address   = 0x40
fault code              = supervisor read, page not present
instruction pointer     = 0x8:0xf014a7e5
stack pointer           = 0x10:0xf4ed6f24
frame pointer           = 0x10:0xf4ed6f28
code segment            = base 0x0, limit 0xfffff, type 0x1b
                        = DPL 0, pres 1, def32 1, gran 1
processor eflags        = interrupt enabled, resume, IOPL = 0
current process         = 80 (mount)
interrupt mask          =
trap number             = 12
panic: page fault

Bei Meldungen wie dieser, reicht es nicht, sie einfach zu reproduzieren und sie einzusenden. Der Wert des Instruktionszeigers ist wichtig; leider ist er auch konfigurationsabhängig. Mit anderen Worten variieren die Werte abhängig von dem Kernel-Image, das Sie tatsächlich benutzen. Wenn Sie ein GENERIC Kernelimage von einem der Snapshots benutzen, dann ist es für jemand anderen möglich, die fehlerhafte Instruktion herauszufinden, aber wenn Sie einen angepassten Kernel benutzen, können nur Sie uns sagen, wo der Fehler auftrat.

Was Sie tun sollten, ist folgendes:

  1. Notieren Sie sich den Wert des Instruktionszeigers. Beachten Sie, dass der Teil 0x8: am Anfang in diesem Fall nicht von Bedeutung ist; der Teil 0xf0xxxxxx ist der, den wir wollen.

  2. Tun Sie folgendes, wenn das System rebootet:

    % nm -n kernel.that.caused.the.panic | grep f0xxxxxx

    wobei 0xf0xxxxxx der Wert des Instruktionszeigers ist. Es besteht die Möglichkeit, dass Sie keinen exakten Treffer erzielen, weil die Symbole in der Symboltabelle des Kernels Funktionseinstiegspunkte sind und die Adresse des Instruktionszeigers irgendwo innerhalb einer Funktion liegen wird und nicht am Anfang. Falls sie keinen exakten Treffer erzielen, lassen Sie den letzten Teil des Werts des Instruktionszeigers weg und versuchen es noch einmal, z.B.:

    % nm -n kernel.that.caused.the.panic | grep f0xxxxx

    Falls das kein Ergebnis liefert, hacken Sie eine weitere Ziffer ab. Wiederholen Sie die Schritte, bis Sie irgendeine Ausgabe erhalten. Das Ergebnis wird eine Liste möglicher Funktionen sein, die die Panik verursacht haben. Das ist zwar kein absolut genauer Mechanismus, um die Fehlerursache ausfindig zu machen, aber es ist besser als gar nichts.

Wie dem auch sei, der beste Weg, den Grund für eine Panik herauszufinden, ist der, einen Crash-Dump festzuhalten und dann kgdb(1) zu benutzen, um den Stack im Crash-Dump zurückzuverfolgen.

Jedenfalls funktioniert die Methode wie folgt:

  1. Sorgen Sie dafür, dass die folgende Zeile in der Kernelkonfigurationsdatei enthalten ist:

    makeoptions     DEBUG=-g          # Build kernel with gdb(1) debug symbols
  2. Wechseln Sie in das Verzeichnis /usr/src:

    # cd /usr/src
  3. Erstellen Sie den Kernel:

    # make buildkernel KERNCONF=MYKERNEL
  4. Warten Sie, bis make(1) den Kernel fertig kompiliert hat.

  5. # make installkernel KERNCONF=MYKERNEL
  6. Starten Sie das System neu.

Anmerkung:

Falls Sie KERNCONF nicht verwenden, wird ein GENERIC Kernel gebaut und installiert.

Der make(1)-Prozess wird zwei Kernel erstellen: /usr/obj/usr/src/sys/MYKERNEL/kernel und /usr/obj/usr/src/sys/MYKERNEL/kernel.debug. kernel wurde als /boot/kernel installiert, während kernel.debug als Quelle für Debuggersymbole für kgdb(1) benutzt werden kann.

Damit ein Crash-Dump erhalten bleibt, müssen Sie /etc/rc.config editieren und dumpdev so setzen, dass es entweder auf die Swap-Partition, oder auf AUTO zeigt. Das bewirkt, dass die rc(8)-Skripte den Befehl dumpon(8) benutzen, um Crash-Dumps zu ermöglichen. Sie können den Befehl auch manuell ausführen. Nach einer Panik kann der Crash-Dump mit savecore(8) wiederhergestellt werden; wenn dumpdev in /etc/rc.conf gesetzt ist, werden die rc(8)-Skripte savecore(8) automatisch ausführen und den Crash-Dump unter /var/crash ablegen.

Anmerkung:

FreeBSD Crash-Dumps sind für gewöhnlich genauso groß wie der physikalische Hauptspeicher des Rechners. Deshalb müssen Sie dafür sorgen, dass genügend Speicherplatz in /var/crash zur Verfügung steht, um den Dump aufnehmen zu können. Alternativ führen Sie savecore(8) manuell aus und lassen es den Crash-Dump in einem anderen Verzeichnis mit mehr Platz wiederherstellen Es ist möglich, die Größe des Crash-Dumps zu begrenzen, indem options MAXMEM=N, wobei N die Größe des verwendeten Kernelspeichers in KBs ist. Wenn Sie z.B. 1 GB RAM haben, können Sie die Speicherbenutzung des Kernels damit auf 128 MB begrenzen, so dass die Größe des Crash-Dumps 128 MB anstatt 1 GB betragen wird.

Sobald der Crash-Dump wiederhergestellt wurde, können Sie den Stack zurückverfolgen:

% kgdb /usr/obj/usr/src/sys/MYKERNEL/kernel.debug /var/crash/vmcore.0
(kgdb) backtrace

Beachten Sie, dass es mehrere Seiten mit wertvollen Informationen geben könnte; idealerweise sollten Sie script(1) benutzen, um sie alle festzuhalten. Wenn Sie das vollständige Kernelimage mit allen Debugginginformationen benutzen, müssten Sie exakt die Zeile des Kernel-Quellcodes finden, wo die Panik aufgetreten ist. Für gewöhnlich müssen Sie den Stack von unten an zurückverfolgen, um die genaue Ereignisabfolge, die zum Crash führte, zurückzuverfolgen. Sie können kgdb(1) auch zum Ausdrucken der Inhalte verschiedener Variablen oder Strukturen benutzen, um den Systemstatus zum Zeitpunkt des Absturzes zu untersuchen.

Tipp:

Wenn Sie einen zweiten Rechner haben, können Sie kgdb(1) auch für entferntes Debugging konfigurieren, einschließlich dem Setzen von Haltepunkten und dem Bewegen in Einzelschritten durch den Kernelcode.

Anmerkung:

Wenn Sie DDB aktiviert haben und der Kernel im Debugger landet, können Sie eine Panik und einen Crash-Dump erzwingen, indem Sie einfach panic am ddb-Prompt eingeben. Er könnte während der Panikphase wieder im Debugger stoppen. Falls er das tut, geben Sie continue ein, dann wird er den Crash-Dump beenden.

18.6.

Wieso funktioniert dlsym() nicht mehr für ELF-Executables?

Die ELF-Werkzeuge machen die in einem Executable definierten Symbole dem dynamischen Linker nicht standardmäßig sichtbar. Konsequenterweise werden dlsym()-Suchen nach Handlern aus Aufrufen von dlopen(NULL, flags) diese Symbole nicht finden können.

Wenn Sie mit dlsym() nach im Hauptexecutable eines Prozesses vorhandenen Symbolen suchen wollen, müssen Sie das Executable mit der Option --export-dynamic von ld(1) linken.

18.7.

Wie kann ich den Adressraum des Kernels auf i386 vergrössern oder verkleinern?

Standardmäßig beträgt der Adressraum des Kernels 1 GB (2 GB für PAE) auf i386. Wenn Sie einen netzwerkintensiven Server oder ZFS verwenden möchten, kann es sein, dass dies nicht ausreichend ist.

Fügen Sie die folgende Zeile zur Kernelkonfigurationsdatei hinzu, um den verfügbaren Speicher zu erhöhen und erstellen Sie dann einen neuen Kernel:

options KVA_PAGES=N

Um den richtigen Wert von N zu bestimmen, teilen Sie den gewünschte Größe des Adressraumes (in Megabyte) durch vier (z.B. beträgt er 512 für 2 GB).

Wenn Sie Fragen zu FreeBSD haben, schicken Sie eine E-Mail an <de-bsd-questions@de.FreeBSD.org>.

Wenn Sie Fragen zu dieser Dokumentation haben, schicken Sie eine E-Mail an <de-bsd-translators@de.FreeBSD.org>.