diff options
Diffstat (limited to 'de_DE.ISO8859-1/books/developers-handbook/kerneldebug/chapter.xml')
-rw-r--r-- | de_DE.ISO8859-1/books/developers-handbook/kerneldebug/chapter.xml | 1110 |
1 files changed, 0 insertions, 1110 deletions
diff --git a/de_DE.ISO8859-1/books/developers-handbook/kerneldebug/chapter.xml b/de_DE.ISO8859-1/books/developers-handbook/kerneldebug/chapter.xml deleted file mode 100644 index 1c72228e32..0000000000 --- a/de_DE.ISO8859-1/books/developers-handbook/kerneldebug/chapter.xml +++ /dev/null @@ -1,1110 +0,0 @@ -<?xml version="1.0" encoding="iso-8859-1"?> -<!-- - The FreeBSD Documentation Project - The FreeBSD German Documentation Project - - $FreeBSD$ - $FreeBSDde: de-docproj/books/developers-handbook/kerneldebug/chapter.xml,v 1.16 2012/03/25 14:33:52 bcr Exp $ - basiert auf: 1.81 ---> -<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="kerneldebug"> - <info><title>Kernel-Fehlersuche</title> - <authorgroup> - <author><personname><firstname>Paul</firstname><surname>Richards</surname></personname><contrib>Contributed by </contrib></author> - <author><personname><firstname>Jörg</firstname><surname>Wunsch</surname></personname></author> - <author><personname><firstname>Robert</firstname><surname>Watson</surname></personname></author> - </authorgroup> - <authorgroup> - <author><personname><firstname>Fabian</firstname><surname>Ruch</surname></personname><contrib>Übersetzt von </contrib></author> - </authorgroup> - </info> - - - - <sect1 xml:id="kerneldebug-obtain"> - <title>Besorgen eines Speicherauszugs nach einem - Kernel-Absturz (Kernel-Crash-Dump)</title> - - <para>Wenn ein Entwicklungs-Kernel (z.B. &os.current;) wie zum - Beispiel ein Kernel unter Extrembedingungen (z.B. sehr hohe - Belastungsraten (Load), eine äußerst hohe Anzahl an - gleichzeitigen Benutzern, Hunderte &man.jail.8;s usw.) - eingesetzt oder eine neue Funktion oder ein neuer - Gerätetreiber in &os.stable; verwendet wird (z.B. - <acronym>PAE</acronym>), tritt manchmal eine Kernel-Panic ein. - In einem solchen Fall zeigt dieses Kapitel, wie dem Absturz - nützliche Informationen entnommen werden - können.</para> - - <para>Bei Kernel-Panics ist ein Neustart unvermeidlich. Nachdem - ein System neu gestartet wurde, ist der Inhalt des - physikalischen Speichers (<acronym>RAM</acronym>), genauso wie - jedes Bit, das sich vor der Panic auf dem Swap-Gerät - befand, verloren. Um die Bits im physikalischen Speicher zu - erhalten, zieht der Kernel Nutzen aus dem Swap-Gerät als - vorübergehenden Ablageort, wo die Bits, welche sich im RAM - befinden, auch nach einem Neustart nach einem Absturz - verfügbar sind. Durch diese Vorgehensweise kann ein - Kernel-Abbild, wenn &os; nach einem Absturz startet, abgezogen - und mit der Fehlersuche begonnen werden.</para> - - <note> - <para>Ein Swap-Gerät, das als Ausgabegerät - (Dump-Device) konfiguriert wurde, verhält sich immer noch - wie ein Swap-Gerät. Die Ausgabe auf - Nicht-Swap-Geräte (wie zum Beispiel Bänder oder - CDRWs) wird zur Zeit nicht unterstützt. Ein - <quote>Swap-Gerät</quote> ist gleichbedeutend mit einer - <quote>Swap-Partition</quote>.</para> - </note> - - <para>Es stehen verschiedene Arten von Speicherabzügen zur - Verfügung: komplette Speicherabzüge (full memory dumps), welche - den gesamten Inhalt des physischen Speichers beinhalten, Miniauszüge - (minidumps), die nur die gerade verwendeten Speicherseiten des Kernels - enthalten (&os; 6.2 und höhere Versionen) und Textauszüge - (textdumps), welche geskriptete oder Debugger-Ausgaben enthalten - (&os; 7.1 und höher). Miniauszüge sind der Standardtyp - der Abzüge seit &os; 7.0 und fangen in den meisten Fällen - alle nötigen Informationen ein, die in einem kompletten - Kernel-Speicherabzug enthalten sind, da die meisten Probleme nur durch - den Zustand des Kernels isoliert werden können.</para> - - <sect2 xml:id="config-dumpdev"> - <title>Konfigurieren des Ausgabegeräts</title> - - <para>Bevor der Kernel den Inhalt seines physikalischen - Speichers auf einem Ausgabegerät ablegt, muss ein solches - konfiguriert werden. Ein Ausgabegerät wird durch Benutzen - des &man.dumpon.8;-Befehls festgelegt, um dem Kernel - mitzuteilen, wohin die Speicherauszüge bei einem - Kernel-Absturz gesichert werden sollen. Das - &man.dumpon.8;-Programm muss aufgerufen werden, nachdem die - Swap-Partition mit &man.swapon.8; konfiguriert wurde. Dies - wird normalerweise durch Setzen der - <varname>dumpdev</varname>-Variable in &man.rc.conf.5; auf den - Pfad des Swap-Geräts (der empfohlene Weg, um einen - Kernel-Speicherauszug zu entnehmen) bewerkstelligt, oder über - <literal>AUTO</literal>, um die erste konfigurierte Swap-Partition - zu verwenden. In HEAD ist die Standardeinstellung für - <varname>dumpdev</varname> <filename>AUTO</filename> und - änderte sich in den RELENG_*-Zweigen (mit Ausnahme von - RELENG_7, bei dem <literal>AUTO</literal> beibehalten wurde) auf - <literal>NO</literal>. In &os; 9.0-RELEASE und späteren - Versionen fragt <application>bsdinstall</application>, ob - Speicherauszüge für das Zielsystem während des - Installationsvorgangs aktiviert werden sollen.</para> - - <tip> - <para>Vergleichen Sie <filename>/etc/fstab</filename> oder - &man.swapinfo.8; für eine Liste der - Swap-Geräte.</para> - </tip> - - <important> - <para>Stellen Sie sicher, dass das in &man.rc.conf.5; - festgelegte <varname>dumpdir</varname> vor einem - Kernel-Absturz vorhanden ist.</para> - - <screen>&prompt.root; <userinput>mkdir /var/crash</userinput> -&prompt.root; <userinput>chmod 700 /var/crash</userinput></screen> - - <para>Denken Sie auch daran, dass der Inhalt von - <filename>/var/crash</filename> heikel ist und sehr - wahrscheinlich vertrauliche Informationen wie - Passwörter enthält.</para> - </important> - </sect2> - - <sect2 xml:id="extract-dump"> - <title>Entnehmen eines Kernel-Speicherauszugs - (Kernel-Dump)</title> - - <para>Sobald ein Speicherauszug auf ein Ausgabegerät - geschrieben wurde, muss er entnommen werden, bevor das - Swap-Gerät eingehängt wird. Um einen Speicherauszug - aus einem Ausgabegerät zu entnehmen, benutzen Sie das - &man.savecore.8;-Programm. Falls <varname>dumpdev</varname> in - &man.rc.conf.5; gesetzt wurde, wird &man.savecore.8; - automatisch beim ersten Start in den Multiuser-Modus nach dem - Absturz und vor dem Einhängen des Swap-Geräts - aufgerufen. Der Speicherort des entnommenen Kernels ist im - &man.rc.conf.5;-Wert <varname>dumpdir</varname>, - standardmäßig <filename>/var/crash</filename>, - festgelegt und der Dateiname wird - <filename>vmcore.0</filename> sein.</para> - - <para>In dem Fall, dass bereits eine Datei mit dem Namen - <filename>vmcore.0</filename> in - <filename>/var/crash</filename> (oder auf was auch immer - <varname>dumpdir</varname> gesetzt ist) vorhanden ist, - erhöht der Kernel die angehängte Zahl bei jedem - Absturz um eins und verhindert damit, dass ein vorhandener - <filename>vmcore</filename> (z.B. - <filename>vmcore.1</filename>) überschrieben wird. - Während der Fehlersuche, möchten Sie höchst - wahrscheinlich den <filename>vmcore</filename> mit der - höchsten Version in <filename>/var/crash</filename> - benutzen, wenn Sie den passenden <filename>vmcore</filename> - suchen.</para> - - <tip> - <para>Falls Sie einen neuen Kernel testen, aber einen anderen - starten müssen, um Ihr System wieder in Gang zu - bringen, starten Sie es nur in den Singleuser-Modus, indem - Sie das <option>-s</option>-Flag an der - Boot-Eingabeaufforderung benutzen, und nehmen dann folgende - Schritte vor:</para> - - <screen>&prompt.root; <userinput>fsck -p</userinput> -&prompt.root; <userinput>mount -a -t ufs</userinput> # make sure /var/crash is writable -&prompt.root; <userinput>savecore /var/crash /dev/ad0s1b</userinput> -&prompt.root; <userinput>exit</userinput> # exit to multi-user</screen> - - <para>Dies weist &man.savecore.8; an, einen - Kernel-Speicherauszug aus <filename>/dev/ad0s1b</filename> - zu entnehmen und den Inhalt in - <filename>/var/crash</filename> abzulegen. Vergessen Sie - nicht sicherzustellen, dass das Zielverzeichnis - <filename>/var/crash</filename> genug freien Speicherplatz - für den Speicherauszug zur Verfügung hat. - Vergessen Sie auch nicht, den korrekten Pfad des - Swap-Geräts anzugeben, da es sehr wahrscheinlich anders - als <filename>/dev/ad0s1b</filename> lautet!</para> - </tip> - </sect2> - </sect1> - - <sect1 xml:id="kerneldebug-gdb"> - <title>Fehlersuche in einem Speicherauszug nach einem - Kernel-Absturz mit <command>kgdb</command></title> - - <note> - <para>Dieser Abschnitt deckt &man.kgdb.1; ab, wie es in &os; 5.3 - und später zu finden ist. In früheren Versionen muss - <command>gdb -k</command> benutzt werden, um einen - Kernspeicherauszug auszulesen.</para> - </note> - - <para>Sobald ein Speicherauszug zur Verfügung steht, ist es - recht einfach nützliche Informationen für einfache - Probleme daraus zu bekommen. Bevor Sie sich auf die Interna von - &man.kgdb.1; stürzen, um die Fehler im Kernspeicherauszug - zu suchen und zu beheben, machen Sie die Debug-Version Ihres - Kernels (normalerweise <filename>kernel.debug</filename> - genannt) und den Pfad der Quelldateien, die zum Bau Ihres - Kernels verwendet wurden (normalerweise - <filename>/usr/obj/usr/src/sys/KERNCONF</filename>, - wobei <filename>KERNCONF</filename> - das in einer Kernel-&man.config.5; festgelegte - <varname>ident</varname> ist), ausfindig. Mit diesen beiden - Informationen kann die Fehlersuche beginnen.</para> - - <para>Um in den Debugger zu gelangen und mit dem - Informationserhalt aus dem Speicherauszug zu beginnen, sind - zumindest folgende Schritte nötig:</para> - - <screen>&prompt.root; <userinput>cd /usr/obj/usr/src/sys/KERNCONF</userinput> -&prompt.root; <userinput>kgdb kernel.debug /var/crash/vmcore.0</userinput></screen> - - <para>Sie können Fehler im Speicherauszug nach dem Absturz - suchen, indem Sie die Kernel-Quellen benutzen, genauso wie Sie - es bei jedem anderen Programm können.</para> - - <para>Dieser erste Speicherauszug ist aus einem 5.2-BETA-Kernel - und der Absturz ist tief im Kernel begründet. Die Ausgabe - unten wurde dahingehend bearbeitet, dass sie nun Zeilennummern - auf der linken Seite einschließt. Diese erste - Ablaufverfolgung (Trace) untersucht den Befehlszeiger - (Instruction-Pointer) und beschafft eine Zurückverfolgung - (Back-Trace). Die Adresse, die in Zeile 41 für den - <command>list</command>-Befehl benutzt wird, ist der - Befehlszeiger und kann in Zeile 17 gefunden werden. Die meisten - Entwickler wollen zumindest dies zugesendet bekommen, falls Sie - das Problem nicht selber untersuchen und beheben können. - Falls Sie jedoch das Problem lösen, stellen Sie sicher, - dass Ihr Patch seinen Weg in den Quellbaum mittels eines - Fehlerberichts, den Mailinglisten oder ihres Privilegs, zu - committen, findet!</para> - - <screen> 1:&prompt.root; <userinput>cd /usr/obj/usr/src/sys/KERNCONF</userinput> - 2:&prompt.root; <userinput>kgdb kernel.debug /var/crash/vmcore.0</userinput> - 3:GNU gdb 5.2.1 (FreeBSD) - 4:Copyright 2002 Free Software Foundation, Inc. - 5:GDB is free software, covered by the GNU General Public License, and you are - 6:welcome to change it and/or distribute copies of it under certain conditions. - 7:Type "show copying" to see the conditions. - 8:There is absolutely no warranty for GDB. Type "show warranty" for details. - 9:This GDB was configured as "i386-undermydesk-freebsd"... -10:panic: page fault -11:panic messages: -12:--- -13:Fatal trap 12: page fault while in kernel mode -14:cpuid = 0; apic id = 00 -15:fault virtual address = 0x300 -16:fault code: = supervisor read, page not present -17:instruction pointer = 0x8:0xc0713860 -18:stack pointer = 0x10:0xdc1d0b70 -19:frame pointer = 0x10:0xdc1d0b7c -20:code segment = base 0x0, limit 0xfffff, type 0x1b -21: = DPL 0, pres 1, def32 1, gran 1 -22:processor eflags = resume, IOPL = 0 -23:current process = 14394 (uname) -24:trap number = 12 -25:panic: page fault -26 cpuid = 0; -27:Stack backtrace: -28 -29:syncing disks, buffers remaining... 2199 2199 panic: mi_switch: switch in a critical section -30:cpuid = 0; -31:Uptime: 2h43m19s -32:Dumping 255 MB -33: 16 32 48 64 80 96 112 128 144 160 176 192 208 224 240 -34:--- -35:Reading symbols from /boot/kernel/snd_maestro3.ko...done. -36:Loaded symbols for /boot/kernel/snd_maestro3.ko -37:Reading symbols from /boot/kernel/snd_pcm.ko...done. -38:Loaded symbols for /boot/kernel/snd_pcm.ko -39:#0 doadump () at /usr/src/sys/kern/kern_shutdown.c:240 -40:240 dumping++; -41:<prompt>(kgdb)</prompt> <userinput>list *0xc0713860</userinput> -42:0xc0713860 is in lapic_ipi_wait (/usr/src/sys/i386/i386/local_apic.c:663). -43:658 incr = 0; -44:659 delay = 1; -45:660 } else -46:661 incr = 1; -47:662 for (x = 0; x < delay; x += incr) { -48:663 if ((lapic->icr_lo & APIC_DELSTAT_MASK) == APIC_DELSTAT_IDLE) -49:664 return (1); -50:665 ia32_pause(); -51:666 } -52:667 return (0); -53:<prompt>(kgdb)</prompt> <userinput>backtrace</userinput> -54:#0 doadump () at /usr/src/sys/kern/kern_shutdown.c:240 -55:#1 0xc055fd9b in boot (howto=260) at /usr/src/sys/kern/kern_shutdown.c:372 -56:#2 0xc056019d in panic () at /usr/src/sys/kern/kern_shutdown.c:550 -57:#3 0xc0567ef5 in mi_switch () at /usr/src/sys/kern/kern_synch.c:470 -58:#4 0xc055fa87 in boot (howto=256) at /usr/src/sys/kern/kern_shutdown.c:312 -59:#5 0xc056019d in panic () at /usr/src/sys/kern/kern_shutdown.c:550 -60:#6 0xc0720c66 in trap_fatal (frame=0xdc1d0b30, eva=0) -61: at /usr/src/sys/i386/i386/trap.c:821 -62:#7 0xc07202b3 in trap (frame= -63: {tf_fs = -1065484264, tf_es = -1065484272, tf_ds = -1065484272, tf_edi = 1, tf_esi = 0, tf_ebp = -602076292, tf_isp = -602076324, tf_ebx = 0, tf_edx = 0, tf_ecx = 1000000, tf_eax = 243, tf_trapno = 12, tf_err = 0, tf_eip = -1066321824, tf_cs = 8, tf_eflags = 65671, tf_esp = 243, tf_ss = 0}) -64: at /usr/src/sys/i386/i386/trap.c:250 -65:#8 0xc070c9f8 in calltrap () at {standard input}:94 -66:#9 0xc07139f3 in lapic_ipi_vectored (vector=0, dest=0) -67: at /usr/src/sys/i386/i386/local_apic.c:733 -68:#10 0xc0718b23 in ipi_selected (cpus=1, ipi=1) -69: at /usr/src/sys/i386/i386/mp_machdep.c:1115 -70:#11 0xc057473e in kseq_notify (ke=0xcc05e360, cpu=0) -71: at /usr/src/sys/kern/sched_ule.c:520 -72:#12 0xc0575cad in sched_add (td=0xcbcf5c80) -73: at /usr/src/sys/kern/sched_ule.c:1366 -74:#13 0xc05666c6 in setrunqueue (td=0xcc05e360) -75: at /usr/src/sys/kern/kern_switch.c:422 -76:#14 0xc05752f4 in sched_wakeup (td=0xcbcf5c80) -77: at /usr/src/sys/kern/sched_ule.c:999 -78:#15 0xc056816c in setrunnable (td=0xcbcf5c80) -79: at /usr/src/sys/kern/kern_synch.c:570 -80:#16 0xc0567d53 in wakeup (ident=0xcbcf5c80) -81: at /usr/src/sys/kern/kern_synch.c:411 -82:#17 0xc05490a8 in exit1 (td=0xcbcf5b40, rv=0) -83: at /usr/src/sys/kern/kern_exit.c:509 -84:#18 0xc0548011 in sys_exit () at /usr/src/sys/kern/kern_exit.c:102 -85:#19 0xc0720fd0 in syscall (frame= -86: {tf_fs = 47, tf_es = 47, tf_ds = 47, tf_edi = 0, tf_esi = -1, tf_ebp = -1077940712, tf_isp = -602075788, tf_ebx = 672411944, tf_edx = 10, tf_ecx = 672411600, tf_eax = 1, tf_trapno = 12, tf_err = 2, tf_eip = 671899563, tf_cs = 31, tf_eflags = 642, tf_esp = -1077940740, tf_ss = 47}) -87: at /usr/src/sys/i386/i386/trap.c:1010 -88:#20 0xc070ca4d in Xint0x80_syscall () at {standard input}:136 -89:---Can't read userspace from dump, or kernel process--- -90:<prompt>(kgdb)</prompt> <userinput>quit</userinput></screen> - - <para>Diese nächste Ablaufverfolgung ist ein älterer - Speicherauszug aus FreeBSD 2-Zeiten, aber ist komplizierter und - zeigt mehr der <command>gdb</command>-Funktionen. Lange Zeilen - wurden gefaltet, um die Lesbarkeit zu verbessern, und die Zeilen - wurden zur Verweisung nummeriert. Trotzdem ist es eine reale - Fehlerverfolgung (Error-Trace), die während der Entwicklung - des pcvt-Konsolentreibers entstanden ist.</para> - -<screen> 1:Script started on Fri Dec 30 23:15:22 1994 - 2:&prompt.root; <userinput>cd /sys/compile/URIAH</userinput> - 3:&prompt.root; <userinput>gdb -k kernel /var/crash/vmcore.1</userinput> - 4:Reading symbol data from /usr/src/sys/compile/URIAH/kernel -...done. - 5:IdlePTD 1f3000 - 6:panic: because you said to! - 7:current pcb at 1e3f70 - 8:Reading in symbols for ../../i386/i386/machdep.c...done. - 9:<prompt>(kgdb)</prompt> <userinput>backtrace</userinput> -10:#0 boot (arghowto=256) (../../i386/i386/machdep.c line 767) -11:#1 0xf0115159 in panic () -12:#2 0xf01955bd in diediedie () (../../i386/i386/machdep.c line 698) -13:#3 0xf010185e in db_fncall () -14:#4 0xf0101586 in db_command (-266509132, -266509516, -267381073) -15:#5 0xf0101711 in db_command_loop () -16:#6 0xf01040a0 in db_trap () -17:#7 0xf0192976 in kdb_trap (12, 0, -272630436, -266743723) -18:#8 0xf019d2eb in trap_fatal (...) -19:#9 0xf019ce60 in trap_pfault (...) -20:#10 0xf019cb2f in trap (...) -21:#11 0xf01932a1 in exception:calltrap () -22:#12 0xf0191503 in cnopen (...) -23:#13 0xf0132c34 in spec_open () -24:#14 0xf012d014 in vn_open () -25:#15 0xf012a183 in open () -26:#16 0xf019d4eb in syscall (...) -27:<prompt>(kgdb)</prompt> <userinput>up 10</userinput> -28:Reading in symbols for ../../i386/i386/trap.c...done. -29:#10 0xf019cb2f in trap (frame={tf_es = -260440048, tf_ds = 16, tf_\ -30:edi = 3072, tf_esi = -266445372, tf_ebp = -272630356, tf_isp = -27\ -31:2630396, tf_ebx = -266427884, tf_edx = 12, tf_ecx = -266427884, tf\ -32:_eax = 64772224, tf_trapno = 12, tf_err = -272695296, tf_eip = -26\ -33:6672343, tf_cs = -266469368, tf_eflags = 66066, tf_esp = 3072, tf_\ -34:ss = -266427884}) (../../i386/i386/trap.c line 283) -35:283 (void) trap_pfault(&frame, FALSE); -36:<prompt>(kgdb)</prompt> <userinput>frame frame->tf_ebp frame->tf_eip</userinput> -37:Reading in symbols for ../../i386/isa/pcvt/pcvt_drv.c...done. -38:#0 0xf01ae729 in pcopen (dev=3072, flag=3, mode=8192, p=(struct p\ -39:roc *) 0xf07c0c00) (../../i386/isa/pcvt/pcvt_drv.c line 403) -40:403 return ((*linesw[tp->t_line].l_open)(dev, tp)); -41:<prompt>(kgdb)</prompt> <userinput>list</userinput> -42:398 -43:399 tp->t_state |= TS_CARR_ON; -44:400 tp->t_cflag |= CLOCAL; /* cannot be a modem (:-) */ -45:401 -46:402 #if PCVT_NETBSD || (PCVT_FREEBSD >= 200) -47:403 return ((*linesw[tp->t_line].l_open)(dev, tp)); -48:404 #else -49:405 return ((*linesw[tp->t_line].l_open)(dev, tp, flag)); -50:406 #endif /* PCVT_NETBSD || (PCVT_FREEBSD >= 200) */ -51:407 } -52:<prompt>(kgdb)</prompt> <userinput>print tp</userinput> -53:Reading in symbols for ../../i386/i386/cons.c...done. -54:$1 = (struct tty *) 0x1bae -55:<prompt>(kgdb)</prompt> <userinput>print tp->t_line</userinput> -56:$2 = 1767990816 -57:<prompt>(kgdb)</prompt> <userinput>up</userinput> -58:#1 0xf0191503 in cnopen (dev=0x00000000, flag=3, mode=8192, p=(st\ -59:ruct proc *) 0xf07c0c00) (../../i386/i386/cons.c line 126) -60: return ((*cdevsw[major(dev)].d_open)(dev, flag, mode, p)); -61:<prompt>(kgdb)</prompt> <userinput>up</userinput> -62:#2 0xf0132c34 in spec_open () -63:<prompt>(kgdb)</prompt> <userinput>up</userinput> -64:#3 0xf012d014 in vn_open () -65:<prompt>(kgdb)</prompt> <userinput>up</userinput> -66:#4 0xf012a183 in open () -67:<prompt>(kgdb)</prompt> <userinput>up</userinput> -68:#5 0xf019d4eb in syscall (frame={tf_es = 39, tf_ds = 39, tf_edi =\ -69: 2158592, tf_esi = 0, tf_ebp = -272638436, tf_isp = -272629788, tf\ -70:_ebx = 7086, tf_edx = 1, tf_ecx = 0, tf_eax = 5, tf_trapno = 582, \ -71:tf_err = 582, tf_eip = 75749, tf_cs = 31, tf_eflags = 582, tf_esp \ -72:= -272638456, tf_ss = 39}) (../../i386/i386/trap.c line 673) -73:673 error = (*callp->sy_call)(p, args, rval); -74:<prompt>(kgdb)</prompt> <userinput>up</userinput> -75:Initial frame selected; you cannot go up. -76:<prompt>(kgdb)</prompt> <userinput>quit</userinput></screen> - - <para>Kommentare zum Skript oben:</para> - - <variablelist> - <varlistentry> - <term>Zeile 6:</term> - - <listitem> - <para>Dies ist ein Speicherauszug, der innerhalb von DDB - genommen wurde (siehe unten), deswegen der Kommentar zur - Panic <quote>because you said to!</quote> und die eher - lange Stack-Ablaufverfolgung (Stack-Trace); der - anfängliche Grund für das Starten von DDB war - jedoch ein Seitenfehler-Trap (Page-Fault-Trap).</para> - </listitem> - </varlistentry> - - <varlistentry> - <term>Zeile 20:</term> - - <listitem> - <para>Dies ist die Position der Funktion - <function>trap()</function> in der - Stack-Ablaufverfolgung.</para> - </listitem> - </varlistentry> - - <varlistentry> - <term>Zeile 36:</term> - - <listitem> - <para>Erzwingt die Benutzung eines neuen Stack-Frames; dies - ist nicht mehr notwendig. Die Stack-Frames sollen jetzt an - die richtige Stelle im Speicher zeigen, selbst im Falle - eines Traps. Nach einem Blick auf den Code in Zeile 403 - ergibt sich mit hoher Wahrscheinlichkeit, dass entweder - der Zeigerzugriff auf <quote>tp</quote> fehlerbehaftet - oder der Array-Zugriff unerlaubt war.</para> - </listitem> - </varlistentry> - - <varlistentry> - <term>Zeile 52:</term> - - <listitem> - <para>Der Zeiger scheint verdächtig, aber besitzt - zufällig eine gültige Adresse.</para> - </listitem> - </varlistentry> - - <varlistentry> - <term>Zeile 56:</term> - - <listitem> - <para>Jedoch zeigt er offensichtlich auf nichts und so haben - wir unseren Fehler gefunden! (Für diejenigen, die - nichts mit diesem speziellen Stück Code anfangen - können: <literal>tp->t_line</literal> verweist - hier auf das Zeilenverhalten (Line-Discipline) des - Konsolen-Geräts, was eine ziemlich kleine Ganzzahl - (Integer) sein muss.)</para> - </listitem> - </varlistentry> - </variablelist> - - <tip> - <para>Falls Ihr System regelmäßig abstürzt und - und Sie bald keinen freien Speicherplatz mehr zur - Verfügung haben, könnte das Löschen alter - <filename>vmcore</filename>-Dateien in - <filename>/var/core</filename> einen beträchtlichen - Betrag an Speicherplatz einsparen.</para> - </tip> - </sect1> - - <sect1 xml:id="kerneldebug-ddd"> - <title>Fehlersuche in einem Speicherauszug nach einem Absturz mit - DDD</title> - - <para>Die Untersuchung eines Speicherauszugs nach einem - Kernel-Absturz mit einem grafischen Debugger wie - <command>ddd</command> ist auch möglich (Sie müssen - den <package>devel/ddd</package>-Port - installieren, um den <command>ddd</command>-Debugger benutzen zu - können). Nehmen Sie die <option>-k</option> mit in die - <command>ddd</command>-Kommandozeile auf, die Sie normalerweise - benutzen würden. Zum Beispiel:</para> - - <screen>&prompt.root; <userinput>ddd --debugger kgdb kernel.debug /var/crash/vmcore.0</userinput></screen> - - <para>Sie sollten nun in der Lage sein, die Untersuchung des - Speicherauszugs nach dem Absturz unter Benutzung der grafischen - Schnittstelle von <command>ddd</command> anzugehen.</para> - </sect1> - - - - <sect1 xml:id="kerneldebug-online-ddb"> - <title>Online-Kernel-Fehlersuche mit DDB</title> - - <para>Während <command>kgdb</command> als Offline-Debugger - eine Benutzerschnittstelle auf höchster Ebene bietet, gibt - es einige Dinge, die es nicht kann. Die wichtigsten sind das - Setzen von Breakpoints und das Abarbeiten des Kernel-Codes in - Einzelschritten (Single-Stepping).</para> - - <para>Falls Sie eine systemnahe Fehlersuche an Ihrem Kernel - vorhaben, steht Ihnen ein Online-Debugger mit dem Namen DDB zur - Verfügung. Er erlaubt Ihnen das Setzen von Breakpoints, die - Abarbeitung von Kernel-Funktionen in Einzelschritten, das - Untersuchen und Verändern von Kernel-Variablen usw. Jedoch - hat er keinen Zugriff auf Kernel-Quelldateien, sondern kann nur, - im Gegensatz zu <command>gdb</command>, welches auf die ganzen - Informationen zur Fehlersuche zurückgreifen kann, auf - globale und statische Symbole zugreifen.</para> - - <para>Um DDB in Ihren Kernel einzubinden, fügen Sie die - Optionen - - <programlisting>options KDB</programlisting> - <programlisting>options DDB</programlisting> - - Ihrer Konfigurationsdatei hinzu und bauen Sie den Kernel neu. - (Details zur Konfiguration des FreeBSD-Kernels finden Sie im - <link xlink:href="&url.books.handbook;/index.html">&os;-Handbuch</link>).</para> - - <note> - <para>Falls Sie eine ältere Version des Boot-Blocks haben, - könnte es sein, dass Ihre Symbole zur Fehlersuche noch - nicht einmal geladen werden. Aktualisieren Sie den Boot-Block; - aktuelle Versionen laden die DDB-Symbole automatisch.</para> - </note> - - <para>Sobald Ihr Kernel mit DDB startet, gibt es mehrere Wege, um - in DDB zu gelangen. Der erste und früheste Weg ist, das - Boot-Flag <option>-d</option> gleich an der - Boot-Eingabeaufforderung einzugeben. Der Kernel startet dann in - den Debug-Modus und betritt DDB noch vor jedweder - Gerätesuche. Somit können Sie Funktionen zur - Gerätesuche/-bereitstellung auf Fehler untersuchen. - &os.current;-Benutzer müssen die sechste Option im - Boot-Menü auswählen, um an eine Eingabeaufforderung zu - gelangen.</para> - - <para>Das zweite Szenario ist der Gang in den Debugger, sobald das - System schon gestartet ist. Es gibt zwei einfache Wege dies zu - erreichen. Falls Sie von der Eingabeaufforderung aus in den - Debugger gelangen möchten, geben Sie einfach folgenden - Befehl ab:</para> - - <screen>&prompt.root; <userinput>sysctl debug.kdb.enter=1</userinput></screen> - - <note> - <para>Um eine schnelle Panic zu erzwingen, geben Sie das folgende - Kommando ein:</para> - <screen>&prompt.root; <userinput>sysctl debug.kdb.panic=1</userinput></screen> - </note> - - <para>Anderenfalls können Sie ein Tastenkürzel auf der - Tastatur benutzen, wenn Sie an der Systemkonsole sind. Die - Voreinstellung für die break-to-debugger-Sequenz ist - <keycombo action="simul"><keycap>Ctrl</keycap><keycap>Alt</keycap><keycap>ESC</keycap></keycombo>. - In syscons kann diese Sequenz auf eine andere Tastenkombination - gelegt werden (remap) und manche der verfügbaren - Tastaturlayouts tun dies, stellen Sie also sicher, dass Sie die - richtige Sequenz kennen, die benutzt werden soll. Für - serielle Konsolen ist eine Option vorhanden, die die Benutzung - einer Unterbrechung der seriellen Verbindung (BREAK) auf der - Kommandozeile erlaubt, um in DDB zu gelangen (<literal>options - BREAK_TO_DEBUGGER</literal> in der Kernel-Konfigurationsdatei). - Dies ist jedoch nicht der Standard, da viele serielle Adapter in - Verwendung sind, die grundlos eine BREAK-Bedingung erzeugen, zum - Beispiel bei Ziehen des Kabels.</para> - - <para>Die dritte Möglichkeit ist, dass jede Panic-Bedingung - in DDB springt, falls der Kernel hierfür konfiguriert ist. - Aus diesem Grund ist es nicht sinnvoll einen Kernel mit DDB - für ein unbeaufsichtigtes System zu konfigurieren.</para> - - <para>Um die unbeaufsichtigte Funktionsweise zu erreichen - fügen Sie:</para> - - <programlisting>options KDB_UNATTENDED</programlisting> - - <para>der Kernel-Konfigurationsdatei hinzu und bauen/installieren - Sie den Kernel neu.</para> - - <para>Die DDB-Befehle ähneln grob einigen - <command>gdb</command>-Befehlen. Das Erste, das Sie vermutlich - tun müssen, ist einen Breakpoint zu setzen:</para> - - <screen><userinput>break function-name address</userinput></screen> - - <para>Zahlen werden standardmäßig hexadezimal - angegeben, aber um sie von Symbolnamen zu unterscheiden, muss - Zahlen, die mit den Buchstaben <literal>a-f</literal> beginnen, - <literal>0x</literal> vorangehen (dies ist für andere - Zahlen beliebig). Einfache Ausdrücke sind erlaubt, zum - Beispiel: <literal>function-name + 0x103</literal>.</para> - - <para>Um den Debugger zu verlassen und mit der Abarbeitung - fortzufahren, geben Sie ein:</para> - - <screen><userinput>continue</userinput></screen> - - <para>Um eine Stack-Ablaufverfolgung zu erhalten, benutzen - Sie:</para> - - <screen><userinput>trace</userinput></screen> - - <note> - <para>Beachten Sie, dass wenn Sie DDB mittels einer - Schnelltaste betreten, der Kernel zurzeit einen Interrupt - bereitstellt, sodass die Stack-Ablaufverfolgung Ihnen nicht - viel nützen könnte.</para> - </note> - - <para>Falls Sie einen Breakpoint entfernen möchten, benutzen - Sie</para> - - <screen><userinput>del</userinput> -<userinput>del address-expression</userinput></screen> - - <para>Die erste Form wird direkt, nachdem ein Breakpoint anschlug, - angenommen und entfernt den aktuellen Breakpoint. Die zweite - kann jeden Breakpoint löschen, aber Sie müssen die - genaue Adresse angeben; diese kann bezogen werden durch:</para> - - <screen><userinput>show b</userinput></screen> - - <para>oder:</para> - - <screen><userinput>show break</userinput></screen> - - <para>Um den Kernel in Einzelschritten auszuführen, probieren - Sie:</para> - - <screen><userinput>s</userinput></screen> - - <para>Dies springt in Funktionen, aber Sie können DDB - veranlassen, diese schrittweise zu verfolgen, bis die passende - Rückkehranweisung (Return-Statement) erreicht ist. Nutzen - Sie hierzu:</para> - - <screen><userinput>n</userinput></screen> - - <note> - <para>Dies ist nicht das gleiche wie die - <command>next</command>-Anweisung von <command>gdb</command>; - es ist wie <command>gdb</command>s <command>finish</command>. - Mehrmaliges Drücken von <keycap>n</keycap> führt zu - einer Fortsetzung.</para> - </note> - - <para>Um Daten aus dem Speicher zu untersuchen, benutzen Sie (zum - Beispiel): - - <screen><userinput>x/wx 0xf0133fe0,40</userinput> -<userinput>x/hd db_symtab_space</userinput> -<userinput>x/bc termbuf,10</userinput> -<userinput>x/s stringbuf</userinput></screen> - - für Word/Halfword/Byte-Zugriff und - Hexadezimal/Dezimal/Character/String-Ausgabe. Die Zahl nach dem - Komma ist der Objektzähler. Um die nächsten 0x10 - Objekte anzuzeigen benutzen Sie einfach:</para> - - <screen><userinput>x ,10</userinput></screen> - - <para>Gleichermaßen benutzen Sie - - <screen><userinput>x/ia foofunc,10</userinput></screen> - - um die ersten 0x10 Anweisungen aus <function>foofunc</function> - zu zerlegen (disassemble) und Sie zusammen mit ihrem - Adressabstand (Offset) vom Anfang von - <function>foofunc</function> auszugeben.</para> - - <para>Um Speicher zu verändern benutzen Sie den - Schreibbefehl:</para> - - <screen><userinput>w/b termbuf 0xa 0xb 0</userinput> -<userinput>w/w 0xf0010030 0 0</userinput></screen> - - <para>Die Befehlsoption - (<literal>b</literal>/<literal>h</literal>/<literal>w</literal>) - legt die Größe der Daten fest, die geschrieben werden - sollen, der erste Ausdruck danach ist die Adresse, wohin - geschrieben werden soll, und der Rest wird als Daten - verarbeitet, die in aufeinander folgende Speicherstellen - geschrieben werden.</para> - - <para>Falls Sie die aktuellen Register wissen möchten, - benutzen Sie:</para> - - <screen><userinput>show reg</userinput></screen> - - <para>Alternativ können Sie den Inhalt eines einzelnen - Registers ausgeben mit z.B. - - <screen><userinput>p $eax</userinput></screen> - - und ihn bearbeiten mit:</para> - - <screen><userinput>set $eax new-value</userinput></screen> - - <para>Sollten Sie irgendeine Kernel-Funktion aus DDB heraus - aufrufen wollen, geben Sie einfach ein:</para> - - <screen><userinput>call func(arg1, arg2, ...)</userinput></screen> - - <para>Der Rückgabewert wird ausgegeben.</para> - - <para>Für eine Zusammenfassung aller laufenden Prozesse im - Stil von &man.ps.1; benutzen Sie:</para> - - <screen><userinput>ps</userinput></screen> - - <para>Nun haben Sie herausgefunden, warum Ihr Kernel - fehlschlägt, und möchten neu starten. Denken Sie - daran, dass, abhängig von der Schwere vorhergehender - Störungen, nicht alle Teile des Kernels wie gewohnt - funktionieren könnten. Führen Sie eine der folgenden - Aktionen durch, um Ihr System herunterzufahren und neu zu - starten:</para> - - <screen><userinput>panic</userinput></screen> - - <para>Dies wird Ihren Kernel dazu veranlassen abzustürzen, - einen Speicherauszug abzulegen und neu zu starten, sodass Sie - den Kernspeicherauszug später auf höherer Ebene mit - <command>gdb</command> auswerten können. Diesem Befehl muss - normalerweise eine weitere <command>continue</command>-Anweisung - folgen.</para> - - <screen><userinput>call boot(0)</userinput></screen> - - <para>Dürfte ein guter Weg sein, um das laufende System - sauber herunterzufahren, alle Festplatten mittels - <function>sync()</function> zu schreiben und schließlich, - in manchen Fällen, neu zu starten. Solange die Festplatten- - und Dateisystemschnittstellen des Kernels nicht beschädigt - sind, könnte dies ein guter Weg für ein beinahe - sauberes Abschalten sein.</para> - - <screen><userinput>call cpu_reset()</userinput></screen> - - <para>Dies ist der letzte Ausweg aus der Katastrophe und kommt - beinahe dem Drücken des Ausschaltknopfes gleich.</para> - - <para>Falls Sie eine kurze Zusammenfassung aller Befehle - benötigen, geben Sie einfach ein:</para> - - <screen><userinput>help</userinput></screen> - - <para>Es ist strengstens empfohlen, eine ausgedruckte Version der - &man.ddb.4;-Manualpage während der Fehlersuche neben sich - liegen zu haben. Denken Sie daran, dass es schwer ist, die - Online-Hilfe zu lesen, während der Ausführung des - Kernels in Einzelschritten.</para> - </sect1> - - <sect1 xml:id="kerneldebug-online-gdb"> - <title>Online-Kernel-Fehlersuche mit GDB auf einem entfernten - System</title> - - <para>Diese Funktion wird seit FreeBSD 2.2 unterstützt und - ist wirklich sehr geschickt.</para> - - <para>GDB unterstützt <emphasis>die Fehlersuche von einem - entfernten System aus</emphasis> bereits einige Zeit. Dies - geschieht unter Benutzung eines sehr einfachen Protokolls - über eine serielle Verbindung. Anders als bei den anderen, - oben beschriebenen, Vorgehensweisen werden hier zwei Systeme - benötigt. Das eine ist das Hostsystem, welches die Umgebung - zur Fehlersuche, einschließlich aller Quellen und einer - Kopie der Kernel-Binärdatei mit allen Symbolen - bereitstellt, und das andere das Zielsystem, welches einfach nur - eine Kopie desselben Kernels ausführt (ohne die - Informationen zur Fehlersuche).</para> - - <para>Sie sollten den Kernel im Zweifelsfall mit <command>config - -g</command> konfigurieren, <option>DDB</option> in die - Konfiguration aufnehmen und den Kernel, wie sonst auch, - kompilieren. Dies ergibt, aufgrund der zusätzlichen - Informationen zur Fehlersuche, eine umfangreiche - Binärdatei. Kopieren Sie diesen Kernel auf das Zielsystem, - entfernen Sie die Symbole zur Fehlersuche mit <command>strip - -x</command> und starten Sie ihn mit der - <option>-d</option>-Boot-Option. Stellen Sie die serielle - Verbindung zwischen dem Zielsystem, welches "flags 80" für - dessen sio-Gerät gesetzt hat, und dem Hostsystem, welches - die Fehlersuche übernimmt, her. Nun wechseln Sie auf dem - Hostsystem in das Bauverzeichnis des Ziel-Kernels und starten - <command>gdb</command>:</para> - - <screen>&prompt.user; <userinput>kgdb kernel</userinput> -GDB is free software and you are welcome to distribute copies of it - under certain conditions; type "show copying" to see the conditions. -There is absolutely no warranty for GDB; type "show warranty" for details. -GDB 4.16 (i386-unknown-freebsd), -Copyright 1996 Free Software Foundation, Inc... -<prompt>(kgdb)</prompt> </screen> - - <para>Stellen Sie die entfernte Sitzung zur Fehlersuche ein mit - (angenommen, der erste serielle Port ist in Verwendung):</para> - - <screen><prompt>(kgdb)</prompt> <userinput>target remote /dev/cuaa0</userinput></screen> - - <para>Jetzt geben Sie auf dem Zielsystem, welches noch vor Beginn - der Gerätesuche in DDB gelangt ist, ein:</para> - - <screen>Debugger("Boot flags requested debugger") -Stopped at Debugger+0x35: movb $0, edata+0x51bc -<prompt>db></prompt> <userinput>gdb</userinput></screen> - - <para>DDB antwortet dann mit:</para> - - <screen>Next trap will enter GDB remote protocol mode</screen> - - <para>Jedesmal wenn Sie <command>gdb</command> eingeben, wird - zwischen dem lokalen DDB und entfernten GDB umgeschaltet. Um - einen nächsten Trap sofort zu erzwingen, geben Sie einfach - <command>s</command> (step) ein. Ihr GDB auf dem Hostsystem - erhält nun die Kontrolle über den Ziel-Kernel:</para> - - <screen>Remote debugging using /dev/cuaa0 -Debugger (msg=0xf01b0383 "Boot flags requested debugger") - at ../../i386/i386/db_interface.c:257 -<prompt>(kgdb)</prompt></screen> - - <para>Sie können mit dieser Sitzung wie mit jeder anderen - GDB-Sitzung umgehen, einschließlich vollem Zugriff auf die - Quellen, Starten im gud-Modus innerhalb eines Emacs-Fensters - (was Ihnen automatische Quelltext-Ausgabe in einem weiteren - Emacs-Fenster bietet), usw.</para> - </sect1> - - <sect1 xml:id="kerneldebug-console"> - <title>Fehlersuche bei einem Konsolen-Treiber</title> - - <para>Da Sie nunmal einen Konsolen-Treiber benötigen, um DDB - zu starten, ist alles ein wenig komplizierter, sobald der - Konsolen-Treiber selbst versagt. Sie erinnern sich vielleicht an - die Benutzung einer seriellen Konsole (entweder durch - Verändern des Boot-Blocks oder Eingabe von - <option>-h</option> an der - <prompt>Boot:</prompt>-Eingabeaufforderung) und das - Anschließen eines Standard-Terminals an Ihren ersten - seriellen Port. DDB funktioniert auf jedem konfigurierten - Konsolen-Treiber, auch auf einer seriellen Konsole.</para> - </sect1> - - <sect1 xml:id="kerneldebug-deadlocks"> - <title>Fehlersuche bei Deadlocks</title> - - <para>Sie erleben vielleicht mal sogenannte Deadlocks, wobei ein - System aufhört, nützliche Arbeit zu machen. Um in - einer solchen Situation einen hilfreichen Fehlerbericht zu - liefern, benutzen Sie &man.ddb.4;, wie oben beschrieben. - Hängen Sie die Ausgabe von <command>ps</command> und - <command>trace</command> für verdächtige Prozesse an - den Bericht an.</para> - - <para>Falls möglich, versuchen Sie, weitere Untersuchungen - anzustellen. Der Empfang der Ausgaben unten ist besonders dann - nützlich, wenn Sie den Auslöser für die Blockade - des Systems auf VFS-Ebene vermuten. Fügen Sie die folgenden - Optionen - - <programlisting>makeoptions DEBUG=-g - options INVARIANTS - options INVARIANT_SUPPORT - options WITNESS - options DEBUG_LOCKS - options DEBUG_VFS_LOCKS - options DIAGNOSTIC</programlisting> - - der Kernel-Konfigurationsdatei hinzu. Wenn die Blockade - ausgelöst wird, stellen Sie, zusätzlich der Ausgabe - vom <command>ps</command>-Befehl, die Informationen aus - <command>show pcpu</command>, <command>show allpcpu</command>, - <command>show locks</command>, <command>show alllocks</command>, - <command>show lockedvnods</command> und - <command>alltrace</command> bereit.</para> - - <para>Um aussagekräftige Zurückverfolgungen von in - Threads aufgeteilten Prozesse zu erhalten, benutzen Sie - <command>thread thread-id</command>, um zum Thread-Stack zu - wechseln und eine Zurückverfolgung mit - <command>where</command> anzustellen.</para> - </sect1> - - <sect1 xml:id="kerneldebug-options"> - <title>Glossar der Kernel-Optionen zur Fehlersuche</title> - - <para>Dieser Abschnitt bietet ein kurzes Glossar der zur - Kompilierzeit verfügbaren Kernel-Optionen, die die - Fehlersuche unterstützen:</para> - - <itemizedlist> - <listitem> - <para><literal>options KDB</literal>: Kompiliert das - Kernel-Debugger-Framework ein. Wird von <literal>options - DDB</literal> und <literal>options GDB</literal> - benötigt. Kein oder nur geringer Leistungs-Overhead. - Standardmäßig wird bei einer Panic der Debugger - gestartet, anstatt automatisch neu zu starten.</para> - </listitem> - - <listitem> - <para><literal>options KDB_UNATTENDED</literal>: Setzt den - Standard des - <literal>debug.debugger_on_panic</literal>-sysctl-Werts auf - 0, welcher regelt, ob der Debugger bei einer Panic gestartet - wird. Solange <literal>options KDB</literal> nicht in den - Kernel einkompiliert ist, wird bei einer Panic automatisch - neu gestartet; sobald es in den Kernel einkompiliert ist, - wird standardmäßig der Debugger gestartet, - solange <literal>options KDB_UNATTENDED</literal> nicht - einkompiliert ist. Falls Sie den Kernel-Debugger in den - Kernel einkompiliert lassen wollen, aber möchten, dass - das System neu startet, wenn Sie nicht zur Stelle sind, um - den Debugger zur Diagnose zu benutzen, wählen Sie diese - Option.</para> - </listitem> - - <listitem> - <para><literal>options KDB_TRACE</literal>: Setzt den Standard - des <literal>debug.trace_on_panic</literal>-sysctl-Werts auf - 1, welcher regelt, ob der Debugger bei einer Panic - automatisch eine Stack-Ablaufverfolgung ausgibt. Besonders - wenn der Kernel mit <literal>KDB_UNATTENDED</literal> - läuft, kann dies hilfreich sein, um grundlegende - Informationen zur Fehlersuche auf der seriellen oder - Firewire-Konsole zu erhalten, während immer noch zur - Wiederherstellung neu gestartet wird.</para> - </listitem> - - <listitem> - <para><literal>options DDB</literal>: Kompiliert die - Unterstützung für den Konsolen-Debugger DDB ein. - Dieser interaktive Debugger läuft auf was auch immer - die aktive Konsole des Systems auf niedrigster Ebene ist, - dazu gehören die Video-, serielle und Firewire-Konsole. - Er bietet grundlegende, eingebaute Möglichkeiten zur - Fehlersuche wie zum Beispiel das Erstellen von - Stack-Ablaufverfolgungen, das Auflisten von Prozessen und - Threads, das Ablegen des Lock-, VM- und Dateisystemstatus - und die Verwaltung des Kernel-Speichers. DDB benötigt - keine Software, die auf einem zweiten System läuft, - oder die Fähigkeit, einen Kernspeicherauszug oder - Kernel-Symbole zur vollen Fehlersuche zu erzeugen und bietet - detaillierte Fehlerdiagnose des Kernels zur Laufzeit. Viele - Fehler können allein unter Benutzung der DDB-Ausgabe - untersucht werden. Diese Option hängt von - <literal>options KDB</literal> ab.</para> - </listitem> - - <listitem> - <para><literal>options GDB</literal>: Kompiliert die - Unterstützung für den Debugger GDB ein, welcher - von einem entfernten System aus über ein serielles - Kabel oder Firewire agieren kann. Wenn der Debugger - gestartet ist, kann GDB dazu verwendet werden, um - Struktur-Inhalte einzusehen, Stack-Ablaufverfolgungen zu - erzeugen, usw. Bei manchem Kernel-Status ist der Zugriff - ungeschickter als mit DDB, welcher dazu in der Lage ist, - nützliche Zusammenfassungen des Kernel-Status - automatisch zu erstellen wie zum Beispiel das automatische - Abgehen der Lock-Fehlersuche oder der Strukturen zur - Kernel-Speicher-Verwaltung, und es wird ein zweites System - benötigt. Auf der anderen Seite verbindet GDB - Informationen aus den Kernel-Quellen mit vollständigen - Symbolen zur Fehlersuche, erkennt komplette - Datenstrukturdefinitionen, lokale Variablen und ist in - Skripten einsetzbar. Diese Option hängt von - <literal>options KDB</literal> ab, ist aber nicht zur - Benutzung von GDB auf einem Kernel-Kernspeicherauszug - nötig.</para> - </listitem> - - <listitem> - <para><literal>options BREAK_TO_DEBUGGER</literal>, - <literal>options ALT_BREAK_TO_DEBUGGER</literal>: Erlaubt - ein Abbruch- oder Alternativ-Signal auf der Konsole, um in - den Debugger zu gelangen. Falls sich das System ohne eine - Panic aufhängt, ist dies ein nützlicher Weg, um - den Debugger zu erreichen. Aufgrund der aktuellen - Verriegelung durch den Kernel ist ein Abbruch-Signal, das - auf einer seriellen Konsole erzeugt wurde, deutlich - vertrauenswürdiger beim Gelangen in den Debugger und - wird allgemein empfohlen. Diese Option hat kaum oder keine - Auswirkung auf den Durchsatz.</para> - </listitem> - - <listitem> - <para><literal>options INVARIANTS</literal>: Kompiliert eine - große Anzahl an Aussageprüfungen und -tests - (Assertion-Checks und -Tests) ein, welche ständig die - Intaktheit der Kernel-Datenstrukturen und die Invarianten - der Kernel-Algorithmen prüfen. Diese Tests können - aufwendig sein und sind deswegen nicht von Anfang an - einkompiliert, aber helfen nützliches "fail - stop"-Verhalten, wobei bestimmte Gruppen nicht - erwünschten Verhaltens den Debugger öffnen, bevor - Beschädigungen an Kernel-Daten auftreten, - bereitzustellen, welches es einfacher macht, diese auf - Fehler hin zu untersuchen. Die Tests beinhalten Säubern - von Speicher und use-after-free-Prüfungen, was eine der - bedeutenderen Quellen von Overhead ist. Diese Option - hängt von <literal>options INVARIANT_SUPPORT</literal> - ab.</para> - </listitem> - - <listitem> - <para><literal>options INVARIANT_SUPPORT</literal>: Viele der - in <literal>options INVARIANTS</literal> vorhandenen Tests - benötigen veränderte Datenstrukturen und - zusätzliche Kernel-Symbole, die festgelegt werden - müssen.</para> - </listitem> - - <listitem> - <para><literal>options WITNESS</literal>: Diese Option - aktiviert Verfolgung und Prüfung von Lock-Anforderungen - zur Laufzeit und ist als Werkzeug für die - Deadlock-Diagnose von unschätzbarem Wert. WITNESS - pflegt ein Diagramm mit erworbenen Lock-Anträgen nach - Typ geordnet und prüft bei jedem Erwerb nach Zyklen - (implizit oder explizit). Falls ein Zyklus entdeckt wird, - werden eine Warnung und eine Stack-Ablaufverfolgung erzeugt - und als Hinweis, dass ein möglicher Deadlock gefunden - wurde, auf der Konsole ausgegeben. WITNESS wird - benötigt, um die DDB-Befehle <command>show - locks</command>, <command>show witness</command> und - <command>show alllocks</command> benutzen zu können. - Diese Debug-Option hat einen bedeutenden Leistung-Overhead, - welcher ein ein wenig durch Benutzung von <literal>options - WITNESS_SKIPSPIN</literal> gemildert werden kann. - Detaillierte Dokumentation kann in &man.witness.4; gefunden - werden.</para> - </listitem> - - <listitem> - <para><literal>options WITNESS_SKIPSPIN</literal>: Deaktiviert - die Prüfung von Spinlock-Lock-Anforderungen mit WITNESS - zur Laufzeit. Da Spinlocks am häufigsten im Scheduler - angefordert werden und Scheduler-Ereignisse oft auftreten, - kann diese Option Systeme, die mit WITNESS laufen, merklich - beschleunigen. Diese Option hängt von <literal>options - WITNESS</literal> ab.</para> - </listitem> - - <listitem> - <para><literal>options WITNESS_KDB</literal>: Setzt den - Standard des - <literal>debug.witness.kdb</literal>-sysctl-Werts auf 1, was - bewirkt, dass WITNESS den Debugger aufruft, sobald eine - Lock-Anforderungsverletzung vorliegt, anstatt einfach nur - eine Warnung auszugeben. Diese Option hängt von - <literal>options WITNESS</literal> ab.</para> - </listitem> - - <listitem> - <para><literal>options SOCKBUF_DEBUG</literal>: Führt - umfassende Beschaffenheitsprüfungen in Socket-Puffern - durch, was nützlich zur Fehlersuche bei Socket-Fehlern - und Anzeichen für Ressourceblockaden (Race) in - Protokollen und Gerätetreibern, die mit Sockets - arbeiten, sein kann. Diese Option hat bedeutende Auswirkung - auf die Netzwerkleistung und kann die Zeitverhältnisse - bei gegenseitiger Ressourceblockade in Gerätetreibern - ändern.</para> - </listitem> - - <listitem> - <para><literal>options DEBUG_VFS_LOCKS</literal>: Verfolgt - Lock-Anforderungs-Einzelheiten bei lockmgr/vnode-Locks, was - die Menge der Informationen, die von <command>show - lockdevnods</command> in DDB angezeigt werden, - vergrößert. Diese Option hat messbare Auswirkung - auf die Leistung.</para> - </listitem> - - <listitem> - <para><literal>options DEBUG_MEMGUARD</literal>: Ein Ersatz - für die Kernel-Speicher-Zuweisung durch &man.malloc.9;, - die das VM-System benutzt, um Lese- und Schreibzugriffe auf - zugewiesenen Speicher nach der Freigabe zu entdecken. - Details können in &man.memguard.9; gefunden werden. - Diese Option hat bedeutende Auswirkung auf die Leistung, - aber kann sehr nützlich bei der Fehlersuche sein, wenn - Kernel-Speicher-Beschädigungen durch Fehler verursacht - werden.</para> - </listitem> - - <listitem> - <para><literal>options DIAGNOSTIC</literal>: Aktiviert - zusätzliche, aufwendigere Diagnosetests analog zu - <literal>options INVARIANTS</literal>.</para> - </listitem> - </itemizedlist> - </sect1> -</chapter> |