diff options
Diffstat (limited to 'es_ES.ISO8859-1/books/handbook/kerneldebug/chapter.sgml')
-rw-r--r-- | es_ES.ISO8859-1/books/handbook/kerneldebug/chapter.sgml | 625 |
1 files changed, 0 insertions, 625 deletions
diff --git a/es_ES.ISO8859-1/books/handbook/kerneldebug/chapter.sgml b/es_ES.ISO8859-1/books/handbook/kerneldebug/chapter.sgml deleted file mode 100644 index 842b21c164..0000000000 --- a/es_ES.ISO8859-1/books/handbook/kerneldebug/chapter.sgml +++ /dev/null @@ -1,625 +0,0 @@ -<!-- - The FreeBSD Documentation Project - - The FreeBSD Spanish Documentation Project - - %SOURCE% en_US.ISO8859-1/books/handbook/kerneldebug/chapter.sgml - %SRCID% 0.0 - - - $FreeBSD$ - $FreeBSDes: doc/es_ES.ISO8859-1/books/handbook/kerneldebug/chapter.sgml,v 1.2 2004/10/08 22:14:26 jesusr Exp $ ---> - -<chapter id="kerneldebug"> - <title>Depurando el Kernel</title> - - <para><emphasis>Contribución de &a.paul; y &a.joerg;</emphasis></para> - - <sect1> - <title>Depuración de un Kernel Crash Dump con <command>kgdb</command></title> - - <para>Aquí se dan instrucciones para hacer funcionar la depuración del - kernel sobre un crash dump. En ellos se asume que usted tiene suficiente - espacio de swap para un crash dump. Si usted tiene varias particiones - de swap y la primera es demasiado pequeña para albergar un dump, puede - configurar su kernel para que use un dispositivo alternativo (en la línea - <literal>config kernel</literal>=, o puede especificar una alternativa - usando el comando &man.dumpon.8;. La mejor manera de usar &man.dumpon.8; - es asignar la variable <literal>dumpdev</literal> en - <filename>/etc/rc.conf</filename>. Generalmente usted va a querer - especificar uno de los dispositivos de swap especificados en - <filename>/etc/fstab</filename>. Actualmente no se soportan dumps a - dispositivos que no sean de swap, como por ejemplo una unidad de cinta. - Configure su kernel usando <command>config -g</command>. Vea <link - linkend="kernelconfig">Configuración del Kernel</link> para más detalles - sobre la configuración del kernel FreeBSD.</para> - - <para>Use el comando &man.dumpon.8; para decirle al kernel donde hacer - el dump (Tenga en cuenta que esto debera hacerse luego de configurar - la partición como dispositivo de swap usando &man.swapon.8;). Esto se - hace normalmente usando los archivos <filename>/etc/rc.conf</filename> - y <filename>/etc/rc</filename>. Como alternativa se puede fijar el - dispositivo usando la cláusula <literal>dump</literal> en la línea - <literal>config</literal> de su archivo de configuración del kernel. - Esta práctica esta en desuso y sólo debería ser usada para obtener - un dump de un kernel que falla durante el inicio.</para> - - <note> - <para>En adelante, el término <command>kgdb</command> se referirá al - <command>gdb</command> corriendo en “kernel debug mode”. - Esto puede lograrse ya sea iniciando al <command>gdb</command> con - la opción <option>-k</option>, o enlazandolo y arrancandolo con el - nombre <command>kgdb</command>. Esto no se hace por default, y - la idea está basicamente en desuso ya que a la gente de GNU no le - gusta que sus herramientas se comporten distinto cuando se las llama - por otro nombre. Esta posibilidad podrá perfectamente ser descontinuada - en futuras versiones.</para> - </note> - - <para>Una vez que el kernel ha sido compilado haga una copia, digamos - <filename>kernel.debug</filename>, y luego corra <command>strip - -g</command> sobre el original. Instale el original normalmente. Usted - tambien podría instalar el kernel sin hacer el <command>strip</command>, - pero los tiempos de busqueda de algunos programas en la tabla de - símbolos aumentarán sensiblemente, y dado que el kernel se carga completo - en memoria durante el inicio y no puede intercambiarse a disco luego, - se desperdiciarán varios megabytes de memoria.</para> - - <para>Si usted esta probando un nuevo kernel, por ejemplo tipeando el - nombre del nuevo kernel en el prompt de inicio, pero necesita arrancar - otro para tener su sistema funcionando de nuevo, arranquelo solo en modo - monousuario usando la opción <option>-s</option> en el prompt de inicio - , y luego siga los siguientes pasos:</para> - - <screen>&prompt.root; <userinput>fsck -p</userinput> -&prompt.root; <userinput>mount -a -t ufs</userinput> # asi su file system para /var/crash se puede escribir -&prompt.root; <userinput>savecore -N /kernel.panicked /var/crash</userinput> -&prompt.root; <userinput>exit</userinput> # ...a modo multiusuario</screen> - - <para>Esto instruye a &man.savecore.8; que use otro kernel para la - extracción de nombres de símbolo. De otro modo usaria el kernel en uso - y probablemente no haga nada ya que los símbolos del kernel y los del - dump son diferentes.</para> - - <para>Ahora, luego de un crash dump, vaya a - <filename>/sys/compile/WHATEVER</filename> y corra - <command>kgdb</command>. desde <command>kgdb</command> haga: - - <screen><userinput>symbol-file kernel.debug</userinput> -<userinput>exec-file /var/crash/kernel.0</userinput> -<userinput>core-file /var/crash/vmcore.0</userinput></screen> - - y voila, ya puede depurar el crash dump usando las fuentes - del kernel como lo hace con cualquier otro programa.</para> - - <para>A continuación se muestra el log de una sesión de - <command>kgdb</command> que ilustra el procedimiento. Las líneas - fueron numeradas para referencia, y las largas fueron cortadas para - mejorar la legibilidad. Mas alla de esto es el registro de un error real - tomado durante el desarrollo del driver pcvt de consola.</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>kgdb 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>where</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> -77:&prompt.root; <userinput>exit</userinput> -78:exit -79: -80:Script done on Fri Dec 30 23:18:04 1994</screen> - <para>Comentarios al listado anterior:</para> - - <variablelist> - <varlistentry> - <term>línea 6:</term> - - <listitem> - <para>Este es un dump tomado desde el DDB (vea abajo), a partir del - comentario del panic “because you said to!”, y un - listado de la pila bastante largo; la razón incial para entrar al - DDB fue un trap de falta de pagina.</para> - </listitem> - </varlistentry> - - <varlistentry> - <term>línea 20:</term> - - <listitem> - <para>Esta es la ubicación de la función <function>trap()</function> - en el listado de la pila.</para> - </listitem> - </varlistentry> - - <varlistentry> - <term>línea 36:</term> - - <listitem> - <para>Se fuerza el uso de un nuevo marco de pila; esto ya no es - necesario ahora. Actualmente se supone que los marcos de pila apuntan a - las ubicaciones correctas, aun en caso de un trap. (No tengo un - dump más nuevo a mano <g>, mi kernel no ha hecho un panic - desde hace bastante tiempo.) Mirando al código en la línea 403 - del código fuente, hay una alta probabilidad de que la referencia - al puntero “tp” sea erronea, o el acceso al arreglo - estuviera fuera de sus límites.</para> - </listitem> - </varlistentry> - - <varlistentry> - <term>línea 52:</term> - - <listitem> - <para>El puntero se ve sospechoso, pero contiene una dirección - válida.</para> - </listitem> - </varlistentry> - - <varlistentry> - <term>línea 56:</term> - - <listitem> - <para>De todos modos, obviamente apunta a basura, asi que encontramos - nuestro error! (Para los que no esten familiarizados con esa pieza - de código en particular: <literal>tp->t_line</literal> hace - referencia a la disciplina de línea de este dispositivo de consola, - el cual debe ser un entero por demás pequeño)</para> - </listitem> - </varlistentry> - </variablelist> - </sect1> - - <sect1> - <title>Depurando un crash dump con DDD</title> - - <para>Tambien es posible examinar un crash dump del kernel con un debugger - gráfico como <command>ddd</command>. Agregue la opción <option>-k - </option> a la línea de comando del <command>ddd</command> que usaría - normalmente. Por ejemplo;</para> - - <screen>&prompt.root; <userinput>ddd -k /var/crash/kernel.0 /var/crash/vmcore.0</userinput></screen> - - <para>De esta manera usted debería poder analizar el crash dump usando - la interfaz gráfica del <command>ddd</command>.</para> - </sect1> - - <sect1> - <title>Analisis Post-mortem de un Dump</title> - - <para>Que sucede si un kernel hace un dump de su memoria que usted - no esperaba, y por lo tanto no estaba compilado usando <command> - config -g</command>? No todo esta perdido aquí. Do not panic!</para> - - <note> - <para>N.del T.: El autor hace un juego con la palabra panic! que - prefiero dejar sin traducir.</para> - </note> - - <para>Por supuesto, aun necesita habilitar los crash dumps. Vea más arriba - las opciones que debe especificar para esto.</para> - - <para>Vaya a su directorio de configuración del kernel - (<filename>/usr/src/sys/<replaceable>arq</replaceable>/conf</filename>) - y edite su archivo de configuración. Quite las marcas de comentario - (o agregue, si no existe) la siguiente línea</para> - - <programlisting> -makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols</programlisting> - - <para>Recompile el kernel. Algunos otros archivos seran recompilados, - por ejemplo <filename>trap.o</filename>, a causa del cambio de la fecha - del archivo Makefile. Con un poco de suerte, la opción <option>-g - </option> no cambiará nada del código generado, al final usted tendra - un kernel con el mismo código que tiene problemas ahora pero con ciertos - símbolos para depuración. Por lo menos usted debería verificar el tamaño - anterior y el nuevo con el comando &man.size.1;. Si hay diferencia - probablemente sea el momento de darse por vencido.</para> - - <para>Ahora puede examinar el dump como se describió anteriormente. Los - símbolos pueden estar incompletos para algunas partes, como se puede ver - en el listado de pila del ejemplo anterior donde algunas funciones - se muestran sin numeros de línea ni listas de argumentos. Si necesita - más símbolos borre los archivos objeto apropiados y repita la sesión de - <command>kgdb</command> hasta que haya averiguado lo suficiente.</para> - - <para>No se garantiza que todo esto funcione, pero irá bastante bien la - en mayoría de los casos.</para> - </sect1> - - <sect1> - <title>Depuración En-línea del Kernel Usando DDB</title> - - <para>Si bien el <command>kgdb</command> provee un muy alto nivel de - interfaz de usuario como depurador post-mortem, hay cosas que no puede - hacer. Siendo las más importantes poder marcar puntos de interrupción - y ejecutar código del kernel paso a paso.</para> - - <para>Si usted necesita hacer una depuración a bajo nivel de su kernel hay - disponible un debugger en-línea llamado DDB. Permite poner puntos de - interrupción, ejecutar paso a paso las funciones del kernel, examinar y - cambiar variables, etc. Sin embargo, no puede acceder al código fuente - del kernel y sólo tiene acceso a los símbolos globales y estáticos, no - a toda la información de depuración como el <command>kgdb</command>.</para> - - <para>Para configurar su kernel para que incluya el DDB, agregue la opción - - <programlisting> -options DDB</programlisting> - - a su archivo de configuración, y recompile (vea <link - linkend="kernelconfig">Configuración del Kernel</link> para más - detalles sobre como configurar el kernel de FreeBSD.)</para> - - <note> - <para>Notese que si usted tiene una versión vieja del boot block, - sus símbolos de debugger podrían no ser cargados. Actualize su - boot block; los mas recientes cargan los símbolos del DDB - automágicamente.</para> - </note> - - <para>Una vez que su kernel con DDB esta corriendo, hay varias maneras - de entrar al DDB. La primera y más temprana es tipear la opción - <option>-d</option> directamente en el prompt de inicio. El kernel - se iniciará en modo de depuración e ingresará al DDB antes de cualquier - detección de dispositivos. De aquí en adelante usted podrá - depurar hasta las funciones probe/attach de los dispositivos.</para> - - <para>El segundo escenario es una combinación de teclas, generalmente - Ctrl-Alt-Esc. En el caso de las syscons, esto puede modificarse, - algunos mapas de teclado distribuidos lo hacen, por lo que hay que - prestar atención. Hay disponible una opción para consolas en puertos - serie que permite el uso de la señal BREAK en la línea para entrar al - DDB (<literal>options BREAK_TO_DEBUGGER</literal> en el archivo de - configuración del kernel). Esto no es el default ya que hay un montón - de adaptadores serie dando vueltas que generan condiciones BREAK - sin necesidad, por ejemplo cuando se desenchufa el cable.</para> - - <para>La tercera forma es que un panic salte al DDB si el kernel está - configurado para usarlo. Por este motivo, no es recomendable configurar - un kernel con DDB para una máquina funcionando sin atención.</para> - - <para>Los comandos del DDB se asemejan remotamente a algunos de los - del <command>gdb</command>. Lo primero que usted probablemente - necesite hacer es poner un punto de interrupción:</para> - - <screen><userinput>b nombre-de-función</userinput> -<userinput>b dirección</userinput></screen> - - <para>Por default los números se toman en hexadecimal, pero para - distinguirlos de los nombres de símbolo los números hexadecimales - que empiezan con las letras <literal>a-f</literal> se deben preceder - con <literal>0x</literal> (para los demás números esto es opcional). - Tambien se admiten expresiones sencillas, por ejemplo: - <literal>nombre-de-función + 0x103</literal>.</para> - - <para>Para que el kernel interrumpido continue ejecutandose, solo - tipee:</para> - - <screen><userinput>c</userinput></screen> - - <para>Para ver un listado de la pila, use:</para> - - <screen><userinput>trace</userinput></screen> - - <note> - <para>Notese que cuando se entra al DDB con una combinación de teclas - el kernel está atendiendo una interrupción, por lo que el listado - de la pila podría no serle de mucha utilidad.</para> - </note> - - <para>Si quiere quitar un punto de interrupción, use</para> - - - <screen><userinput>del</userinput> -<userinput>del expresión-dirección-de-memoria</userinput></screen> - - <para>La primera forma se aceptará inmediatamente despues de llegar - a un punto de interrupción, y borra el punto actual. La segunda - puede quitar cualquier punto de interrupción, pero se debe - especificar la dirección exacta; esta se puede obtener de:</para> - - <screen><userinput>show b</userinput></screen> - - <para>Para ejecutar el kernel paso a paso, intente:</para> - - <screen><userinput>s</userinput></screen> - - <para>Esto entrará dentro de las funciones, pero puede hacer - que DDB las siga hasta llegar a la instrucción de retorno - correspondiente usando:</para> - - <screen><userinput>n</userinput></screen> - - <note> - <para>Esto es distinto de la instrucción <command>next</command> - del <command>gdb</command>; es más parecido a la instrucción - <command>finish</command>.</para> - </note> - - <para>Para examinar los datos en la memoria use (por ejemplo): - - <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> - - para acceder a palabras/medias palabras/bytes, y para mostrar - en hexadecimal/decimal/caracteres/strings. El número luego de la coma - es la cantidad de objetos. Para mostrar los siguientes 0x10 - items, simplemente use:</para> - - <screen><userinput>x ,10</userinput></screen> - - <para>Del mismo modo, use - - <screen><userinput>x/ia foofunc,10</userinput></screen> - - para desensamblar las primeras 0x10 instrucciones de - <function>foofunc</function>, y mostrarlas junto con su - desplazamiento desde el comienzo de <function>foofunc</function>.</para> - - <para>Para modificar memoria, use el comando write:</para> - - <screen><userinput>w/b termbuf 0xa 0xb 0</userinput> -<userinput>w/w 0xf0010030 0 0</userinput></screen> - - <para>El modificador - (<literal>b</literal>/<literal>h</literal>/<literal>w</literal>) - especifica el tamaño de los datos a ser escritos, la primera expresión - a continuación es la dirección donde escribir y el resto es interpretado - como datos para escribir en las direcciones de memoria sucesivas.</para> - - <para>Si quiere conocer el valor actual de los registros del - procesador, use:</para> - - <screen><userinput>show reg</userinput></screen> - - <para>O, puede mostrar un solo registro usando: - - <screen><userinput>p $eax</userinput></screen> - - y modificarlo haciendo:</para> - - <screen><userinput>set $eax new-value</userinput></screen> - - <para>Si usted quisiera llamar alguna función del kernel desde - el DDB, solo debe decir:</para> - - <screen><userinput>call func(arg1, arg2, ...)</userinput></screen> - - <para>El valor devuelto será impreso en la pantalla.</para> - - <para>Para un resumen de los procesos corriendo al estilo &man.ps.1; - use:</para> - - <screen><userinput>ps</userinput></screen> - - <para>Usted ya ha examinado la causa de que su kernel falle, y quiere - reiniciar su equipo. Recuerde que, dependiendo de lo severo de las - fallas que ocurrieron, algunas partes del kernel podrían no funcionar - como se espera. Siga una de las siguientes acciones para apagar y - reiniciar su equipo:</para> - - <screen><userinput>call diediedie()</userinput></screen> - - <para>Esto causará que su kernel haga un crash dump y reinicie, asi - luego podrá analizar el dump a un nivel más alto con el kgdb. Este - comando suele tener que acompañarse por otra instrucción <command> - continue</command>. Para hacer esto hay un alias: - <command>panic</command>.</para> - - <screen><userinput>call boot(0)</userinput></screen> - - <para>La cual podría ser una buena manera de apagar ordenadamente el - sistema, hacer un <function>sync()</function> de todos los discos, - y finalmente reiniciar. En tanto las interfaces de disco y de - filesystem del kernel no esten dañadas, esta podría ser una buena - manera de hacer un apagado bastante prolijo.</para> - - <screen><userinput>call cpu_reset()</userinput></screen> - - <para>Es la ultima salida de los desastres y es practicamente lo - mismo que presionar el Gran Boton Rojo.</para> - - <para>Si usted necesita un breve sumario de los comandos, tipee:</para> - - <screen><userinput>help</userinput></screen> - - <para>De todos modos, es altamente recomendable tener una copia impresa - de la página &man.ddb.4; del manual a mano antes de la sesión de - depuración. Recuerde que es bastante difícil leer el manual en línea - mientras se está ejecutando el kernel paso a paso.</para> - </sect1> - - <sect1> - <title>Depuración En-Línea Usando El GDB remoto</title> - - <para>Esta característica ha sido soportada desde FreeBSD 2.2, y ya está - en verdad muy bien pulida.</para> - - <para>El GDB ha soportado <emphasis>depuración remota</emphasis> desde - hace mucho tiempo. Esto se hace usando un protocolo muy simple a - traves de una línea serie. A diferencia de los otros metodos descriptos - anteriormente, hacen falta dos máquinas para hacer esto. Una va a - proveer el entorno de depuración, incluyendo todos los archivos fuente, - y una copia del ejecutable del kernel con todos los símbolos y la otra - será la máquina a depurar que simplemente corre una copia de exactamente - el mismo kernel (pero sin los símbolos de depuración).</para> - - <para>Usted debería configurar el kernel en cuestión con <command>config - -g</command>, incluir <option>DDB</option> en la configuración, y - compilarla como siempre. Esto arrojará un ejecutable enorme, debido a la - información de depuración. Copie este kernel a la máquina a depurar, - quitele los simbolos con <command>strip -x</command>, e inicielo usando - la opción <option>-d</option> en el prompt de inicio. Conecte el primer - puerto serie de la máquina a cualquier puerto serie de la máquina que - correrá el debugger. Ahora en la máquina que corre el debugger, vaya al - directorio de compilación del kernel a depurar, y arranque el gdb:</para> - - <screen>&prompt.user; <userinput>gdb -k 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>Inicie la sesión de depuración remota haciendo - (asumiendo que se usa el primer puerto serie):</para> - - <screen><prompt>(kgdb)</prompt> <userinput>target remote /dev/cuaa0</userinput></screen> - - <para>Ahora en la máquina a depurar (que entró al DDB justo antes de - empezar a detectar los dispositivos), tipee:</para> - - <screen>Debugger("Boot flags requested debugger") -Stopped at Debugger+0x35: movb $0, edata+0x51bc -<prompt>db></prompt> <userinput>gdb</userinput></screen> - - <para>El DDB responderá diciendo:</para> - - <screen>Next trap will enter GDB remote protocol mode</screen> - - <para>Cada vez que tipee <command>gdb</command>, el modo se alternará - entre el GDB remoto y el DDB local. Para forzar un siguiente trap - inmediatamente, simplemente tipee <command>s</command> (avanza un paso). - la máquina del debugger ahora ganará control sobre el kernel a depurar: - </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>Esta sesión puede usarse casi como cualquier otra sesión de GDB, - incluyendo acceso completo al código fuente, ejecutarlo en modo-gud - dentro de una ventana de Emacs (lo cual brinda la posibilidad de - mostrar automáticamente el código fuente en otra ventana de Emacs) - etc.</para> - - <para>El GDB remoto tambien puede usarse para depurar LKMs. Primero - compile el LKM con los simbolos de depuración:</para> - - <screen>&prompt.root; <userinput>cd /usr/src/lkm/linux</userinput> -&prompt.root; <userinput>make clean; make COPTS=-g</userinput></screen> - - <para>Luego instale esta versión del módulo en la máquina a depurar, - carguelo y use <command>modstat</command> para averiguar donde fue - cargado:</para> - - <screen>&prompt.root; <userinput>linux</userinput> -&prompt.root; <userinput>modstat</userinput> -Type Id Off Loadaddr Size Info Rev Module Name -EXEC 0 4 f5109000 001c f510f010 1 linux_mod</screen> - - <para>Tome la dirección de carga (loadaddr) del módulo y sumele - 0x20 (probablemente para contar el encabezado a.out). Esta es la - dirección donde el código del módulo fue reubicado. Use el comando - <command>add-symbol-file</command> en el GDB para informarle al - debugger acerca del módulo:</para> - - <screen><prompt>(kgdb)</prompt> <userinput>add-symbol-file /usr/src/lkm/linux/linux_mod.o 0xf5109020</userinput> -add symbol table from file "/usr/src/lkm/linux/linux_mod.o" at -text_addr = 0xf5109020? (y or n) <userinput>y</userinput> -<prompt>(kgdb)</prompt></screen> - - <para>Ahora tiene acceso a todos los símbolos en el LKM.</para> - </sect1> - - <sect1> - <title>Depurando Un Driver de Consola</title> - - <para>Dado que el DDB necesita un driver de consola sobre el que correr, - las cosas son mas complicadas si lo que falla es el propio driver de - consola. Usted podría entonces recordar el uso de una consola en puerto serie - (ya sea con un sector de inicio modificado, o especificando <option>-h - </option> en el prompt <prompt>Boot:</prompt>) y colgar una terminal - estándar en su primer puerto serie. El DDB funciona en cualquier - driver de consola configurado, por supuesto tambien en una consola de - puerto serie.</para> - </sect1> -</chapter> - -<!-- - Local Variables: - mode: sgml - sgml-declaration: "../chapter.decl" - sgml-indent-data: t - sgml-omittag: nil - sgml-always-quote-attributes: t - sgml-parent-document: ("../book.sgml" "part" "chapter") - End: ---> - |