28 Compilar y Probar Programas
El capítulo anterior discute los comandos de Emacs que son útiles para hacer cambios en los programas. Este capítulo trata de los comandos que ayudan en el proceso de compilar y probar programas.
28.1 Ejecutar Compiladores en Emacs
Emacs puede ejecutar compiladores para lenguajes como C y Fortran, alimentando el registro de compilación en un búfer de Emacs. También puede analizar los mensajes de error y mostrarte dónde se han producido.
Alt-x compile
(M-x compile
)
Ejecuta un compilador de forma asíncrona bajo Emacs, con los mensajes de error yendo al búfer
*Compilation*
(*compilación*).
recompile
(M-x recompile
)g
, En Modo Compilación)Invoca un compilador con el mismo comando que en la última llamada a
M-x compile
.
Alt-x kill-compilation
(M-x kill-compilation
)
Mata el subproceso de compilación en ejecución.
Para ejecutar make
u otro comando de compilación, escriba Alt-x compile
(M-x compile
). Esto lee una línea de comandos de shell usando el minibúfer, y luego ejecuta el comando ejecutando un shell como un subproceso (o proceso inferior) de Emacs. La salida se inserta en un búfer llamado *compilation*
. El directorio por defecto del búfer actual se usa como directorio de trabajo para la ejecución de la orden, así que por defecto la compilación tiene lugar en ese directorio.
El comando de compilación por defecto es make -k
, que normalmente es correcto para programas compilados usando la utilidad make
(la bandera -k
le dice a make que continúe compilando tanto como sea posible después de un error). Ver Make en el Manual GNU Make. Si ha hecho M-x compile
antes, el comando que especificó se almacena automáticamente en la variable compile-command
; esto se usa por defecto la próxima vez que escriba M-x compile
. Un archivo también puede especificar un valor local para compile-command
(ver 50.2.4. Variables locales en Archivos).
Al iniciar una compilación se muestra el búfer de *compilación* (*compilation*
) en otra ventana, pero no se selecciona. Mientras se ejecuta la compilación, la palabra run
aparece en el indicador de modo principal del búfer *compilación*
, y la palabra Compiling
(Compilando) aparece en todas las líneas de modo. No es necesario mantener visible el búfer *compilation*
mientras se ejecuta la compilación; ésta continúa en cualquier caso. Cuando la compilación termina, por la razón que sea, la línea de modo del búfer de *compilación*
cambia para mostrar exit
(seguido del código de salida: [0]
para una salida normal), o signal
(si una señal terminó el proceso).
Si desea ver la transcripción de la compilación tal y como aparece, cambie al búfer compilación
y mueva punto al final del búfer. Cuando el punto está al final, la nueva salida de compilación se inserta sobre el punto, que permanece al final. En caso contrario, el punto permanece fijo mientras se añade la salida de compilación al final del búfer.
Mientras se realiza la compilación, la línea mode muestra el número de errores, advertencias y mensajes informativos emitidos por el compilador hasta el momento.
Si cambia la variable compilation-scroll-output
a un valor no nulo, el búfer *compilación*
se desplaza automáticamente para seguir la salida. Si el valor es first-error
, el desplazamiento se detiene cuando aparece el primer error, dejando el punto en ese error. Para cualquier otro valor no nulo, el desplazamiento continúa hasta que no hay más salida.
Para volver a ejecutar la última compilación con el mismo comando, escriba M-x recompile
. Esto reutiliza el comando de compilación de la última invocación de M-x compile
. También reutiliza el búfer *compilación*
e inicia la compilación en su directorio por defecto, que es el directorio en el que se inició la compilación anterior. En los búferes de *compilación*
este comando está ligado a g
.
Comenzar una nueva compilación también mata cualquier compilación que ya se esté ejecutando en el búfer *compilation*
, ya que el búfer sólo puede manejar una compilación a la vez. Sin embargo, M-x compile
y M-x recompile
piden confirmación antes de matar una compilación que se está ejecutando; para matar siempre automáticamente la compilación sin preguntar, cambie la variable compilation-always-kill
a t
. También puede matar un proceso de compilación con el comando M-x kill-compilation
.
Para ejecutar dos compilaciones a la vez, inicie la primera, luego renombre el búfer de *compilación*
(quizás usando rename-uniquely
; vea 20.3 Operaciones Varias del Búfer), luego cambie de búfer e inicie la otra compilación. Esto creará un nuevo búfer de *compilación*
.
Puede controlar el entorno que se pasa al comando de compilación con la variable compilation-environment
. Su valor es una lista de configuraciones de variables de entorno; cada elemento debe ser una cadena de la forma "envvarname=value"
. Estas configuraciones de variables de entorno anulan las habituales.
Mostrar líneas extremadamente largas en la salida de compilación puede ralentizar Emacs. Las líneas que son más largas que compilation-max-output-line-length
tendrán la porción que excede ese límite oculta detrás de un botón que puede ser pulsado para revelar la porción oculta. Establezca esta variable a nil
para no ocultar nunca nada.
28.2 Modo Compilación
El búfer *compilation*
(*compilación*) usa un modo principal llamado modo de Compilación (Compilation mode). El modo de compilación convierte cada mensaje de error del búfer en un hiperenlace; puede mover el puntero sobre él y escribir RETURN (RET
), o hacer clic sobre él con el ratón (véase 22.3 Seguir Referencias con el Ratón), para visitar el locus del mensaje de error en una ventana separada. locus es la posición específica en un archivo donde se produjo ese error.
La apariencia del búfer de *compilación* puede controlarse personalizando las caras que se usan para resaltar partes de dicho búfer, por ejemplo, compilation-error
o compilation-warning
(error-compilación o advertencia-compilación), para mensajes de error y advertencia respectivamente. Nótese que, dado que estas caras heredan de las caras de error
y warning
(advertencia), también es posible personalizar directamente la cara padre.
Use M-x customize-group RET
compilación para ver la lista completa de variables de personalización y caras.
Si cambia la variable compilation-auto-jump-to-first-error
a un valor no nulo, Emacs visita automáticamente el lugar del primer mensaje de error que aparece en el búfer de *compilación*. (Esta variable también puede tener los valores if-location-known
y first-known
, que modifican las condiciones para visitar automáticamente el lugar del error).
El modo de compilación proporciona los siguientes comandos adicionales. Estos comandos también pueden usarse en búferes *grep*
, donde los hipervínculos son coincidencias de búsqueda en lugar de mensajes de error (ver 28.4 Buscar con Grep en Emacs).
M-g M-n
)M-g n
)C-x `
)Visita La posición del siguiente mensaje de error o coincidencia (
next-error
).
M-g M-p
)M-g p
)Visita La posición del mensaje de error o coincidencia anterior (
previous-error
).
Alt-n (M-n
)
Mueve el punto al siguiente mensaje de error o coincidencia, sin visitar su posición (
compilation-next-error
).
Alt-p (M-p
)
Mueve el punto al mensaje de error o coincidencia anterior, sin visitar su posición (
compilation-previous-error
).
Alt-} (M-}
)
Mueve el punto al siguiente mensaje de error o coincidencia que se produzca en un archivo diferente (
compilation-next-file
).
Alt-{ (M-{
)
Mueve el punto al mensaje de error anterior o a la coincidencia que se produce en un archivo diferente (
compilation-previous-file
).
Ctrl-c Ctrl-f (C-c C-f
)
Conmuta al modo menor Continuar al Siguiente Error (Next Error Follow), que hace que el movimiento del cursor en el búfer de compilación produzca la visualización automática de la fuente.
g (g
)
Vuelve a ejecutar el último comando cuya salida se muestra en el búfer
*compilation*
.
Alt-x next-error-select-buffer
(M-x next-error-select-buffer
)
Selecciona un búfer para ser usado por la siguiente invocación de
next-error
yprevious-error
.
Para visitar los errores secuencialmente, escriba Ctrl-x ` (C-x `
, next-error
), o equivalentemente Alt-g Alt-n Alt-g n (M-g M-n o M-g n
) . Este comando puede invocarse desde cualquier búfer, no sólo desde un búfer del modo Compilación. La primera vez que se invoca tras una compilación, visita el lugar del primer mensaje de error. Cada M-g M-n
posterior visita el siguiente error, de forma similar. Si visita un error específico con RET
o un clic del ratón en el búfer de *compilación*
, los comandos M-g M-n
posteriores avanzan desde allí. Cuando M-g M-n
no encuentra más mensajes de error que visitar, señala un error. C-u M-g M-n
comienza de nuevo desde el principio del búfer de compilación, y visita la primera posición (locus).
M-g M-p
o M-g p
(previous-error
) itera a través de los errores en la dirección opuesta.
Los comandos next-error
y previous-error
no sólo actúan sobre los errores o coincidencias listados en los búferes *compilation*
y *grep*
; también saben cómo iterar a través de las listas de errores o coincidencias producidas por otros comandos, como M-x occur
(ver 16.11. Otros Comandos de Búsqueda y Bucle). Si el búfer actual contiene mensajes de error o coincidencias, estos comandos iterarán a través de ellos; de lo contrario, Emacs busca un búfer que contenga mensajes de error o coincidencias entre las ventanas del marco seleccionado (si la variable next-error-find-buffer-function
está personalizada al valor next-error-buffer-on-selected-frame
), luego un búfer usado previamente por next-error
o previous-error
, y finalmente todos los demás búferes. Se mostrará cualquier búfer que estos comandos recorran y que no se muestre actualmente en una ventana. Puede usar el comando next-error-select-buffer
para cambiar a un búfer diferente que será usado por la siguiente invocación de next-error.
Por defecto, los comandos next-error
y previous-error
omiten los mensajes menos importantes. La variable compilation-skip-threshold
controla esto. El valor por defecto, 1, significa saltarse cualquier cosa menos importante que una advertencia. Un valor de 2 significa saltarse cualquier cosa menos importante que un error, mientras que 0 (cero) significa no saltarse ningún mensaje.
Cuando Emacs visita el lugar de un mensaje de error, resalta momentáneamente la línea fuente relevante. La duración de este resaltado está determinada por la variable next-error-highlight
para la posición (locus) en el búfer seleccionado, y next-error-highlight-no-select
para La posición en búferes no seleccionados. También puede personalizar la variable next-error-message-highlight
que define cómo resaltar el mensaje de error actual en el búfer que contiene mensajes.
Si el búfer de *compilación* se muestra en una ventana con una franja izquierda (ver 15.15 Bordes de ventana), los comandos de visita de posiciones ponen una flecha en la franja, apuntando al mensaje de error actual. Si la ventana no tiene franja izquierda, como en un terminal de texto, estos comandos desplazan la ventana para que el mensaje actual esté en la parte superior de la ventana. Si cambia la variable compilation-context-lines
a t
, en su lugar se inserta una flecha visible antes de la columna cero. Si cambia la variable a un valor entero n, estos comandos desplazan la ventana para que el mensaje de error actual esté a n líneas de la parte superior, haya o no flecos; el valor por defecto, nil
, da el comportamiento descrito anteriormente.
La salida de la compilación puede ser a veces muy verbosa, y gran parte de ella no es de particular interés para un Usuario. La opción de Usuario compilation-hidden-output
debe ser una expresión regular o una lista de expresiones regulares, y la salida que coincida se hará invisible. Por ejemplo, para ocultar la salida detallaa de archivos make recursivos, puede escribir algo como:
(setq compilation-hidden-output
'("^make[^\n]+\n"))
Para analizar los mensajes del compilador, el modo Compilación (Compilation mode) usa la variable compilation-error-regexp-alist
que lista varios formatos de mensajes de error y le dice a Emacs cómo extraer la posición (locus) de cada uno. Una variable similar, grep-regexp-alist
, le dice a Emacs cómo analizar la salida de un comando grep (ver 28.4 Buscar con Grep en Emacs).
El modo de compilación también define las teclas SPACE (SPC
) y DEL (DEL
) para desplazarse por pantalla; M-n
(compilation-next-error
) y M-p
(compilation-previous-error
) para moverse al siguiente o anterior mensaje de error; y M-{
(compilation-next-file
) y M-}
(compilation-previous-file
) para pasar al mensaje de error siguiente o anterior de un archivo fuente diferente.
Puede teclear Ctrl-c Ctrl-f (C-c C-f
) para activar el modo de seguimiento del siguiente error. En este modo menor, el movimiento ordinario del cursor en el búfer de compilación actualiza automáticamente el búfer fuente, es decir, al mover el cursor sobre un mensaje de error se muestra el lugar de ese error.
Las funciones del modo de compilación también están disponibles en un modo secundario denominado modo secundario de compilación. Esto le permite analizar mensajes de error en cualquier búfer, no sólo en un búfer de salida de compilación normal. Escriba M-x compilation-minor-mode
para activar el modo menor. Por ejemplo, en un búfer Rlogin (véase 39.10 Shell de Host Remoto), el modo menor de Compilación accede automáticamente a los archivos fuente remotos por FTP (véase 19.1 Nombres de Archivos).
28.3 Subshells para Compilar
Esta sección incluye varias técnicas y consejos para usar un shell y sus características en búferes de compilación. Este material es específico para compilaciones locales, y muy probablemente no funcionará en (o será irrelevante para) búferes de compilación cuyo directorio por defecto esté en hosts remotos.
El comando M-x compile
usa un shell para ejecutar el comando de compilación, pero especifica la opción de un shell no interactivo. Esto significa, en particular, que el intérprete de comandos debe iniciarse sin símbolo del sistema. Si encuentra que el prompt habitual de su shell aparece en el búfer de *compilación*, significa que ha cometido un error en el archivo de init de su shell al establecer el prompt incondicionalmente. (Este archivo de init puede llamarse .bashrc
, .profile
, .cshrc
, .shrc
, etc., dependiendo del shell que use). El archivo de inicio del intérprete de comandos debe establecer el indicador sólo si ya existe un indicador. He aquí cómo hacerlo en bash:
if [ "${PS1+set}" = set ]
then PS1=…
fi
Y así es como se hace en csh:
if ($?prompt) set prompt = …
Si desea personalizar el valor de la variable de entorno TERM
que se pasa a la subshell de compilación, personalice la variable comint-terminfo-terminal
(ver 39.7 Opciones del Modo Shell).
Emacs no espera que un proceso compilador lance subprocesos asíncronos; si lo hace, y siguen ejecutándose después de que el proceso compilador principal haya terminado, Emacs puede matarlos o su salida puede no llegar a Emacs. Para evitar este problema, haga que el proceso de compilación principal espere a que sus subprocesos terminen. En un script de shell, puede hacer esto usando $!
y wait
, así:
¡(sleep 10; echo 2nd)& pid=$! # Registrar pid del subproceso
echo primer mensaje
wait $pid # Esperar subproceso
Si el proceso en segundo plano no emite al búfer de compilación, por lo que sólo necesita evitar que sea eliminado cuando finalice el proceso de compilación principal, esto es suficiente:
nohup command; sleep 1
En MS-DOS, los subprocesos asíncronos no están soportados, por lo que M-x compile
ejecuta el comando de compilación de forma síncrona (es decir, debe esperar hasta que el comando termine antes de poder hacer cualquier otra cosa en Emacs). Ver Emacs y MS-DOS.
28.4 Buscar con Grep en Emacs
Al igual que puede ejecutar un compilador desde Emacs y luego visitar las líneas con errores de compilación, también puede ejecutar grep
y luego visitar las líneas en las que se encontraron coincidencias. Esto funciona tratando las coincidencias reportadas por grep
como si fueran errores. El búfer de salida usa el modo Grep, que es una variante del modo Compilación (ver 28.2 Modo Compilación).
grep
(M-x grep
)lgrep
(M-x lgrep
)Ejecuta
grep
asíncronamente bajo Emacs, listando las líneas coincidentes en el búfer llamado*grep*
.
grep-find
(M-x grep-find
)find-grep
(M-x find-grep
)rgrep
(M-x rgrep
)Ejecuta
grep
a través defind
, y recoge la salida en el búfer*grep*
.
Alt-x zrgrep
(M-x zrgrep
)
Ejecuta
zgrep
y recoge la salida en el búfer*grep*
.
Alt-x kill-grep
(M-x kill-grep
)
Mata el subproceso
grep
en ejecución.
Para ejecutar grep
, escriba Alt-x grep
(M-x grep
) y, a continuación, introduzca una línea de comandos que especifique cómo ejecutar grep
. Utilice los mismos argumentos que le daría a grep
cuando lo ejecuta normalmente: una expresión regular estilo grep
(normalmente entre comillas simples para entrecomillar los caracteres especiales del shell) seguida de nombres de archivo, que pueden usar comodines. Si especifica un argumento de prefijo para M-x grep
, éste encuentra el identificador (vea 29.4 Buscar Referencias de Identificador) en el búfer alrededor del punto, y lo pone en el comando grep por defecto.
Su comando no necesita simplemente ejecutar grep
; puede usar cualquier comando del shell que produzca salida en el mismo formato. Por ejemplo, puede encadenar comandos grep
, de esta manera:
grep -nH -e foo *.el | grep bar | grep toto
La salida de grep
va al búfer *grep*
. Puede encontrar las líneas correspondientes en los archivos originales usando M-g M-n
, RET
, etc., como en los errores de compilación. Ver 28.2 Modo Compilación, para una descripción detallada de los comandos y combinaciones de teclas disponibles en el búfer *grep*
.
Algunos programas grep aceptan la opción --color
para mostrar marcadores especiales alrededor de las coincidencias con el propósito de resaltarlas. Puede usar esta opción poniendo grep-highlight-matches
a t
. Al mostrar una coincidencia en el búfer fuente, se resaltará la coincidencia exacta, en lugar de toda la línea fuente. El resaltado se realiza mediante las secuencias de escape ANSI emitidas por grep
. La coincidencia de las secuencias se controla mediante grep-match-regexp
, que puede personalizarse para adaptarse a diferentes programas grep
.
Al igual que con los comandos de compilación (ver 28.1 Ejecutar Compiladores en Emacs), mientras se ejecuta el comando grep
, la línea de modo muestra el número de coincidencias encontradas y resaltadas hasta el momento.
Los comandos grep
ofrecerán guardar búferes antes de ejecutarse. Esto se controla mediante la variable grep-save-buffers
. Los valores posibles son nil
(no guardar), ask
(preguntar antes de guardar), o una función que será usada como predicado (y es llamada con el nombre del archivo como parámetro y debe devolver no-nil
si el búfer debe ser guardado). Cualquier otro valor no nulo significa que todos los búferes deben guardarse sin preguntar. El valor por defecto es ask
.
El comando M-x grep-find
(también disponible como M-x find-grep
) es similar a M-x grep
, pero proporciona un valor inicial por defecto diferente para el comando-uno que ejecuta tanto find
como grep
, para buscar en todos los archivos de un árbol de directorios. Véase también el comando find-grep-dired
, en 31.17 Dired y Find (Buscar).
Los comandos M-x lgrep
(grep
local) y M-x rgrep
(grep
recursivo) son versiones de grep
y grep-find
más fáciles de usar y, que solicitan por separado la expresión regular a buscar, los archivos a buscar y el directorio base para la búsqueda. La distinción entre mayúsculas y minúsculas se controla mediante el valor actual de case-fold-search
. El comando M-x zrgrep
es similar a M-x rgrep
, pero utiliza zgrep
en lugar de grep
para buscar en el contenido de archivos comprimidos.
Estos comandos construyen los comandos del shell basándose en las variables grep-template
(para lgrep
) y grep-find-template
(para rgrep
). Los archivos a buscar pueden usar alias definidos en la variable grep-files-aliases
.
Los directorios listados en la variable grep-find-ignored-directories
son omitidos automáticamente por M-x rgrep
. El valor por defecto incluye los directorios de datos usados por varios sistemas de control de versiones.
Por defecto, los comandos de shell construidos para lgrep
, rgrep
y zgrep
se abrevian para su visualización ocultando la parte que contiene una larga lista de archivos y directorios a ignorar. Puede revelar la parte oculta haciendo clic en el botón con elipsis que los representa. También puede alternar interactivamente la visualización de la parte oculta escribiendo M-x grep-find-toggle-abbreviation
. Para desactivar esta abreviación de los comandos del shell, personalice la opción grep-find-abbreviate
a un valor nulo.
28.5 Encontrar errores de sintaxis al vuelo
El modo Flymake es un modo menor que realiza una comprobación de sintaxis sobre la marcha para muchos lenguajes de programación y marcado, incluyendo C, C++, Perl, HTML y TeX/LaTeX. Es algo análogo al modo Flyspell, que realiza la comprobación ortográfica para lenguajes humanos ordinarios de forma similar (véase 17.4 Comprobar y Corregir la Ortografía). Mientras edita un archivo, el modo Flymake ejecuta una herramienta de comprobación sintáctica apropiada en segundo plano, usando una copia temporal del búfer. A continuación, analiza los mensajes de error y advertencia, y resalta las líneas erróneas en el búfer. La herramienta de comprobación de sintaxis usada depende del lenguaje; por ejemplo, para archivos C/C++ suele ser el compilador de C. Flymake también puede usar herramientas de compilación como make
para comprobar proyectos complicados.
Para activar el modo Flymake, escriba Alt-x flymake-mode
(M-x flymake-mode
). Puede saltar a los errores que encuentre usando M-x flymake-goto-next-error
y M-x flymake-goto-prev-error
. Para mostrar una vista detallada de los diagnósticos del búfer actual, use el comando M-x flymake-show-buffer-diagnostics
; para mostrar una vista similar de los diagnósticos de todo el proyecto (vea 28.2 Modo Compilación), use M-x flymake-show-project-diagnostics
.
Para más detalles sobre cómo usar Flymake, vea Flymake en The Flymake Manual.
28.6. Ejecutar Depuradores en Emacs
La biblioteca GUD (Grand Unified Debugger, Gran Depurador Unificado) proporciona una interfaz de Emacs para una amplia variedad de depuradores simbólicos. Puede ejecutar el depurador de GNU (GDB), así como DBX, SDB, XDB, los comandos de depuración de Guile REPL, el modo de depuración de Perl, el depurador de Python PDB, y el depurador de Java JDB.
Emacs proporciona una interfaz especial para GDB, que usa ventanas extra de Emacs para mostrar el estado del programa depurado. Ver 28.6.5. Interfaz Gráfica de GDB.
Emacs también tiene un depurador incorporado para programas Emacs Lisp. Ver El depurador Lisp en el Manual de Referencia de Emacs Lisp.
28.6.1 Iniciar GUD
Existen varios comandos para iniciar un subproceso depurador, cada uno correspondiente a un programa depurador en particular.
Alt-x gdb
(M-x gdb
)
Ejecuta GDB como un subproceso, e interactúa con él a través de una interfaz Emacs tipo IDE. Consulte 28.6.5. Interfaz Gráfica de GDB, para obtener más información sobre este comando.
Alt-x gud-gdb
(M-x gud-gdb
)
Ejecuta GDB, usando un búfer de interacción GUD para entrada y salida al subproceso GDB (ver 28.6.2. Funcionamiento del Depurador). Si tal búfer ya existe, cambia a él; de lo contrario, crea el búfer y luego cambia a él.
Los otros comandos de esta lista hacen lo mismo, para otros programas depuradores.
Alt-x perldb
(M-x perldb
)
Ejecuta el intérprete Perl en modo depuración.
Alt-x jdb
(M-x jdb
)
Ejecuta el depurador de Java.
Alt-x pdb
(M-x pdb
)
Ejecuta el depurador de Python.
Alt-x guiler
(M-x guiler
)
Ejecuta Guile REPL para depurar programas Guile Scheme.
Alt-x dbx
(M-x dbx
)
Ejecuta el depurador DBX.
Alt-x xdb
(M-x xdb
)
Ejecuta el depurador XDB.
Alt-x sdb
(M-x sdb
)
Ejecuta el depurador SDB.
Cada uno de estos comandos lee una línea de comandos para invocar el depurador, usando el minibúfer. El contenido inicial del minibúfer contiene el nombre del ejecutable estándar y las opciones para el depurador, y a veces también una suposición del nombre del archivo ejecutable que se desea depurar. Los comodines y variables de shell no están permitidos en esta línea de comandos. Emacs asume que el primer argumento del comando que no comienza con un -
es el nombre del archivo ejecutable.
Tramp permite la depuración remota, en la que tanto el depurador como el programa que se está depurando se encuentran en el mismo host remoto. Ver Ejecutar un Depurador en un Host Remoto en el Manual de Tramp, para más detalles. Esto es independiente de la característica de depuración remota de GDB, donde el programa y el depurador se ejecutan en máquinas diferentes (ver Depurando Programas Remotos en El depurador GNU).
28.6.2. Funcionamiento del Depurador
El búfer de interacción de GUD es un búfer de Emacs que se usa para enviar comandos de texto a un subproceso del depurador, y grabar su salida. Esta es la interfaz básica para interactuar con un depurador, usada por M-x gud-gdb
y otros comandos listados en 28.6.1 Iniciar GUD Comenzando GUD. El comando M-x gdb
extiende esta interfaz con búferes especializados adicionales para controlar puntos de interrupción, marcos de pila y otros aspectos del estado del depurador (vea 28.6.5. Interfaz Gráfica de GDB).
El búfer de interacción GUD usa una variante del modo Shell, por lo que los comandos de Emacs definidos por el modo Shell están disponibles (ver 39.3 Modo Shell). El completado está disponible para la mayoría de los comandos del depurador (vea 9.4 Completado), y puede usar los comandos habituales del historial del modo Shell para repetirlos. Vea 28.6.3 Comandos del GUD, para comandos especiales que pueden usarse en el búfer de interacción del GUD.
Mientras depura un programa, Emacs muestra los archivos fuente relevantes visitándolos en los búferes de Emacs, con una flecha en la franja izquierda que indica la línea de ejecución actual. (En un terminal de texto, la flecha aparece como =>
, superpuesta en las dos primeras columnas de texto). Si se mueve el punto en un búfer de este tipo, la flecha no se desplaza. Es libre de editar estos archivos fuente, pero tenga en cuenta que insertar o borrar líneas desviará el posicionamiento de la flecha, ya que Emacs no tiene forma de averiguar qué línea fuente editada corresponde a la línea informada por el subproceso depurador. Para actualizar esta información, normalmente hay que recompilar y reiniciar el programa.
El modo GUD Tooltip es un modo global menor que añade soporte tooltip a GUD. Para activar este modo, escriba M-x gud-tooltip-mode
. Está desactivado por defecto. Si está habilitado, puede mover el puntero del ratón sobre una variable, una función o una macro (colectivamente llamadas identificadores) para mostrar sus valores en tooltips (vea 22.19 Sugerencias sobre Herramientas (Tooltips)). Si con sólo colocar el puntero del ratón sobre una expresión no se muestra el valor de la expresión que tenía en mente, puede decirle a Emacs más explícitamente qué expresión evaluar arrastrando el ratón sobre la expresión, y luego dejando el ratón dentro del área marcada. El modo GUD Tooltip tiene efecto en el búfer de interacción GUD, y en todos los búferes fuente con modos principales listados en la variable gud-tooltip-modes
. Si la variable gud-tooltip-echo-area
no es nula, o si desactivó el modo tooltip, los valores se muestran en el área de eco en lugar de un tooltip.
Cuando se usa el modo GUD Tooltip con M-x gud-gdb
, mostrar el valor de una expresión en GDB a veces puede expandir una macro, causando potenciales efectos secundarios en el programa depurado. Por esta razón, usar tooltips en gud-gdb
está deshabilitado. Si usa la interfaz M-x gdb
, este problema no ocurre, ya que hay código especial para evitar efectos secundarios; además, puede mostrar definiciones de macros asociadas a un identificador cuando el programa no se está ejecutando.
28.6.3 Comandos del GUD
GUD proporciona comandos para establecer y borrar puntos de interrupción, seleccionar marcos de pila y recorrer el programa.
Ctrl-x Ctrl-a Ctrl-b (C-x C-a C-b
)
Establece un punto de interrupción en la línea fuente en la que se encuentra ese punto.
C-x C-a C-b
(gud-break
), cuando se invoca en un búfer fuente, establece un punto de interrupción del depurador en la línea fuente actual. Este comando sólo está disponible después de iniciar GUD. Si lo ejecuta en un búfer que no está asociado a ningún subproceso del depurador, se producirá un error.
Los siguientes comandos están disponibles tanto en el búfer de interacción de GUD como globalmente, pero con diferentes combinaciones de teclas.
Las teclas que empiezan con la combinación Ctrl-c (C-c
) sólo están disponibles en el búfer de interacción GUD, mientras que las que empiezan con las teclas Ctrl-x Ctrl-a (C-x C-a
) están disponibles globalmente. Algunos de estos comandos también están disponibles a través de la barra de herramientas; otros no están soportados por ciertos depuradores.
C-c C-l
)C-x C-a C-l
)Muestra, en otra ventana, la última línea de origen referida en el búfer de interacción GUD (
gud-refresh
).
C-c C-s
)C-x C-a C-s
)Ejecuta la siguiente línea de código (
gud-step
). Si la línea contiene una llamada a función, la ejecución se detiene tras entrar en la función llamada.
C-c C-n
)C-x C-a C-n
)Ejecuta la siguiente línea de código, recorriendo las llamadas a funciones sin detenerse dentro de ellas (
gud-next
).
C-c C-i
)C-x C-a C-i
)Ejecuta una única instrucción de máquina (
gud-stepi
).
C-c C-p
)C-x C-a C-p
)Evalúa la expresión en el punto (
gud-print
). Si Emacs no imprime la expresión exacta que desea, márquela primero como región.
C-c C-r
)C-x C-a C-r
)Continúa la ejecución sin especificar ningún punto de parada. El programa se ejecutará hasta que llegue a un punto de interrupción, termine o reciba una señal que el depurador esté comprobando (
gud-cont
.
C-c C-d
)C-x C-a C-d
)Borra el(los) punto(s) de interrupción en la línea fuente actual, si existe(n) (
gud-remove
). Si usa este comando en el búfer de interacción GUD, se aplica a la línea donde el programa se detuvo por última vez.
C-c C-t
)C-x C-a C-t
)Establece un punto de interrupción temporal en la línea fuente actual, si existe (
gud-tbreak
). Si usa este comando en el búfer de interacción GUD, se aplica a la línea donde el programa se detuvo por última vez.
C-c <
)C-x C-a <
)Selecciona el siguiente marco de pila adyacente (
gud-up
). Esto es equivalente al comandoup
de GDB.
C-c >
)C-x C-a >
)Selecciona el siguiente marco interior de la pila (
gud-down
). Esto equivale al comandodown
de GDB.
C-c C-u
)C-x C-a C-u
)Continúa la ejecución hasta la línea actual (
gud-until
). El programa se ejecutará hasta que llegue a un punto de interrupción, termine, reciba una señal que el depurador esté comprobando o llegue a la línea en la que se encuentra actualmente el cursor.
C-c C-f
)C-x C-a C-f
)Ejecuta el programa hasta que el marco de pila seleccionado regrese o se detenga por alguna otra razón (
gud-finish
).
Si usa GDB, dispone de estos enlaces de teclas adicionales:
Ctrl-x Ctrl-a Ctrl-j (C-x C-a C-j
)
Sólo útil en un búfer fuente,
gud-jump
transfiere el punto de ejecución del programa a la línea actual. En otras palabras, la siguiente línea que ejecute el programa será aquella en la que diste el comando. Si la nueva línea de ejecución está en una función diferente de la anterior, GDB pide confirmación ya que los resultados pueden ser extraños. Consulte la entrada del manual de GDB relativa a jump para más detalles.
TAB (TAB
)
Con GDB, completa un nombre de símbolo (
gud-gdb-complete-command
). Esta tecla sólo está disponible en el búfer de interacción GUD.
Estos comandos interpretan un argumento numérico como un conteo de repeticiones, cuando eso tiene sentido.
Debido a que TAB
sirve como comando de finalización, no puede usarlo para introducir un tabulador como entrada al programa que está depurando con GDB. En su lugar, escriba Ctrl-q TAB (C-q TAB
) para introducir un tabulador.
28.6.4 Personalización de GUD
Al arrancar, GUD ejecuta uno de los siguientes ganchos: gdb-mode-hook
, si está usando GDB; dbx-mode-hook
, si está usando DBX; sdb-mode-hook
, si está usando SDB; xdb-mode-hook
, si está usando XDB; guiler-mode-hook
para depuración Guile REPL; perldb-mode-hook
, para modo de depuración Perl; pdb-mode-hook
, para PDB; jdb-mode-hook
, para JDB. Véase 50.2.2 Ganchos (Hooks).
La macro Lisp gud-def
(ver Definiendo Macros en el Manual de Referencia de Emacs Lisp) proporciona una forma conveniente de definir un comando Emacs que envíe una cadena de comandos particular al depurador, y establecer una unión de teclas para en el búfer de interacción GUD:
(gud-def function cmdstring binding docstring)
Esto define una función con nombre de comando que envía cmdstring al proceso de depuración, y le da la cadena de documentación docstring. Puede usar la función comando en cualquier búfer. Si binding no es nulo, gud-def
también vincula el comando a C-c
binding en el modo del búfer GUD y a C-x C-a
binding en general.
La cadena de comandos cmdstring puede contener ciertas secuencias %
que representan datos que deben rellenarse en el momento en que se llama a la función:
%f
El nombre del archivo fuente actual. Si el búfer actual es el búfer GUD, entonces el archivo fuente actual es el archivo en el que se detuvo el programa.
%l
El número de la línea fuente actual. Si el búfer actual es el búfer GUD, entonces la línea fuente actual es la línea en la que se detuvo el programa.
%e
En el modo
transient-mark
, el texto de la región, si está activa. En caso contrario, el texto del lvalor C o de la expresión de llamada a función en el punto o adyacente a él.%a
El texto de la dirección hexadecimal en o adyacente al punto.
%p
El argumento numérico de la función llamada, como número decimal. Si el comando se usa sin argumento numérico,
%p
representa la cadena vacía.Si no usa
%p
en la cadena de comandos, el comando que defina ignorará cualquier argumento numérico.%d
El nombre del directorio del archivo fuente actual.
%c
Nombre de clase completamente cualificado derivado de la expresión que rodea al punto (sólo jdb).
28.6.5. Interfaz Gráfica de GDB
El comando M-x gdb
inicia GDB en una interfaz tipo IDE, con búferes especializados para controlar puntos de ruptura, marcos de pila y otros aspectos del estado del depurador. También proporciona formas adicionales de controlar la sesión de depuración con el ratón, como hacer clic en el borde de un búfer fuente para establecer allí un punto de interrupción.
Para ejecutar GDB usando sólo la interfaz del búfer de interacción GUD, sin estas características adicionales, use M-x gud-gdb
(vea 28.6.1 Iniciar GUD).
Internamente, M-x gdb
informa a GDB que el tamaño de su pantalla es ilimitado; para un correcto funcionamiento, no debe cambiar los valores de altura y anchura de la pantalla de GDB durante la sesión de depuración.
28.6.5.1. Disposición de la Interfaz de Usuario GDB
Si la variable gdb-many-windows
es nil
(por defecto), M-x gdb
normalmente muestra sólo el búfer de interacción GUD. Sin embargo, si la variable gdb-show-main
tampoco es nula, se inicia con dos ventanas: una mostrando el búfer de interacción GUD, y la otra mostrando el código fuente de la función principal del programa que está depurando.
Si gdb-many-windows es no nil, entonces M-x gdb
muestra el siguiente diseño de marco:
+--------------------------------+---------------------------------------+
| Búfer de interacción | GUD Búfer de registros locales |
|--------------------------------+---------------------------------------+
| Búfer de fuente primaria | Búfer de E/S para pgm depurado |
|--------------------------------+---------------------------------------+
| Búfer de pila | Búfer de puntos de interrupción/hilos |
+--------------------------------+---------------------------------------+
Puede personalizar el diseño de la ventana basado en el anterior y guardar ese diseño en un archivo usando gdb-save-window-configuration
. Luego puede cargar este diseño de nuevo usando gdb-load-window-configuration
. (Internamente, Emacs usa el término configuración de ventana en lugar de disposición de ventana). Puede establecer su diseño personalizado como el predeterminado usado por gdb-many-windows
personalizando gdb-default-window-configuration-file
. Si no es un nombre de archivo absoluto, GDB busca el archivo en gdb-window-configuration-directory
. gdb-window-configuration-directory
por defecto es user-emacs-directory
(vea 50.4.4. Cómo encuentra Emacs su Archivo de Inicio).
Si alguna vez cambia la distribución de ventanas, puede restaurar la distribución por defecto tecleando Alt-x gdb-restore-windows
(M-x gdb-restore-windows
). Para alternar entre la distribución de muchas ventanas y una distribución simple con sólo el búfer de interacción GUD y un archivo fuente, escriba M-x gdb-many-windows
.
Si tiene una configuración de ventanas elaborada, y no quiere que gdb-many-windows
la interrumpa, es mejor invocar M-x gdb
en un marco separado para empezar, entonces la disposición de las ventanas en su marco original no se verá afectada. Un marco separado para las sesiones de GDB puede ser especialmente útil si trabaja en un terminal en modo texto, donde el espacio de pantalla para las ventanas puede ser escaso. Si elige iniciar GDB en el mismo marco, considere establecer gdb-restore-window-configuration-after-quit
a un valor no nulo. Su diseño original será entonces restaurado después de que GDB se cierre. Use t
para restaurar siempre; use if-gdb-many-windows
para restaurar sólo cuando gdb-many-windows
sea distinto de cero; use if-gdb-show-main
para restaurar sólo cuando gdb-show-main
sea distinto de cero.
También puede especificar búferes adicionales relacionados con GDB para mostrar, ya sea en el mismo marco o en uno diferente. Seleccione los búferes que desee escribiendo M-x gdb-display-buffertype-buffer
o M-x gdb-frame-buffertype-buffer
, donde buffertype
es el tipo de búfer relevante, como breakpoints
o io
. Puede hacer lo mismo desde la barra de menús, con los submenús GDB-Windows
y GDB-Frames
del menú GUD
.
Por defecto, GDB usa como máximo una ventana para mostrar el archivo fuente. Puede hacer que use más ventanas personalizando gdb-max-source-window-count
. También puede personalizar gdb-display-source-buffer-action
para controlar como GDB muestra los archivos fuente.
Cuando termine de depurar, elimine el búfer de interacción GUD con C-x k
, que también eliminará todos los búferes asociados con la sesión. Sin embargo, no necesita hacer esto si, después de editar y recompilar su código fuente dentro de Emacs, desea continuar depurando. Cuando reinicie la ejecución, GDB encontrará automáticamente el nuevo ejecutable. Mantener el búfer de interacción GUD tiene la ventaja de mantener el historial del shell así como los puntos de interrupción de GDB. Es necesario comprobar que los puntos de interrupción de los archivos fuente editados recientemente siguen estando en los lugares correctos.
28.6.5.2 Búferes Fuente
ratón-1
(en el margen)Establece o borra un punto de interrupción en esa línea (
gdb-mouse-set-clear-breakpoint
).
Ctrl-ratón-1
(C-ratón-1
en el margen)
Activa o desactiva un «punto de interrupción» (
breakpoint
) en esa línea (gdb-mouse-toggle-breakpoint-margin
).
ratón-3
(en el margen)Continúa la ejecución hasta esa línea (
gdb-mouse-until
).
Ctrl-ratón-3
(C-ratón-3
en el margen)
Salta a esa línea (
gdb-mouse-jump
).
En una pantalla gráfica, puede hacer clic con el ratón-1
en el margen de un búfer fuente, para establecer un punto de interrupción en esa línea (ver 15.15 Bordes de ventana). Aparecerá un punto rojo en la franja donde haya hecho clic. Si ya existe un punto de interrupción allí, el clic lo elimina. Un clic con C-ratón-1
activa o desactiva un punto de interrupción existente; un punto de interrupción desactivado, pero no desactivado, se indica con un punto gris.
En un terminal de texto, o cuando los márgenes están desactivados, los puntos de interrupción activados se indican con un carácter B
en el margen izquierdo de la ventana. Los puntos de interrupción desactivados se indican con una b
. (El margen sólo se muestra si hay un punto de interrupción presente).
Una flecha sólida en la franja izquierda de un búfer fuente indica la línea del marco más interno donde se ha detenido el programa depurado. Una flecha hueca indica la línea de ejecución actual de un marco superior. Si arrastra la flecha de la franja con ratón-1
, la ejecución avanzará hasta la línea en la que suelte el botón. Alternativamente, puede hacer clic con el ratón-3
en la franja para avanzar a esa línea. Puede pulsar C-ratón-3
en la franja para saltar a esa línea sin ejecutar las líneas intermedias. Este comando le permite ir hacia atrás, lo que puede ser útil para recorrer código que ya se ha ejecutado, con el fin de examinar su ejecución con más detalle.
Por defecto, los nombres de archivos fuente y las cadenas no ASCII del programa que se está depurando se decodifican usando el sistema de codificación por defecto. Si prefiere una decodificación diferente, quizás porque el programa que está siendo depurado usa una codificación de caracteres diferente, establezca la variable gdb-mi-decode-strings
al sistema de codificación apropiado, o a nil
para dejar los caracteres no ASCII como escapes octales sin decodificar.
28.6.5.3. Búfer de puntos de interrupción
El búfer de puntos de interrupción del GDB muestra los puntos de interrupción, los puntos de control y los puntos de captura en la sesión del depurador. Ver Puntos de Interrupción en El depurador GNU. Proporciona los siguientes comandos, que en su mayoría se aplican al punto de interrupción actual (el punto de interrupción en el que se encuentra el punto):
SPACE (SPC
)
Activa/desactiva el punto de interrupción actual (
gdb-toggle-breakpoint
). En una visualización gráfica, esto cambia el color del punto en la franja del búfer fuente en esa línea. El punto es rojo cuando el punto de interrupción está activado, y gris cuando está desactivado.
D (D
)
Elimina el punto de interrupción actual (
gdb-delete-breakpoint
).
RETURN (RET
)
Visita la línea fuente del punto de interrupción actual (
gdb-goto-breakpoint
).
ratón-2
Visita la línea fuente del punto de interrupción sobre el que ha hecho clic (
gdb-goto-breakpoint
).
Cuando gdb-many-windows
es distinto de nil
, el búfer GDB Breakpoints comparte su ventana con el búfer GDB Threads. Para cambiar de una a otra pulse con ratón-1
sobre el botón correspondiente en la línea de cabecera. Si gdb-show-threads-by-default
es distinto de nil
, el búfer GDB Threads es el que se muestra por defecto.
28.6.5.4. Búfer de Hilos (Threads)
El búfer de hilos del GDB muestra un resumen de los hilos en el programa depurado. Ver Depurando Programas con Múltiples Hilos en El depurador GNU. Para seleccionar un hilo, mueva el punto allí y pulse RETURN (RET`, ``gdb-select-thread
), o haga clic sobre él con ratón-2
. Esto también muestra el búfer fuente asociado, y actualiza el contenido de los otros búferes GDB.
Puede personalizar las variables del grupo gdb-buffers
para seleccionar los campos incluidos en el búfer GDB Threads.
gdb-thread-buffer-verbose-names
Muestra nombres de hilos largos como
Thread 0x4e2ab70 (LWP 1983)
.gdb-thread-buffer-arguments
Muestra los argumentos de los marcos superiores de hilo.
gdb-thread-buffer-locations
Muestra la información de los archivos o los nombres de las bibliotecas.
gdb-thread-buffer-addresses
Muestra las direcciones de los marcos de los hilos en el búfer de hilos.
Para ver información de varios hilos simultáneamente, use los siguientes comandos desde el búfer de hilos GDB.
d
Muestra el búfer de desensamblado para el hilo en la línea actual (
gdb-display-disassembly-for-thread
).f
Muestra el búfer de pila GDB para el subproceso en la línea actual (
gdb-display-stack-for-thread
).l
Muestra el búfer de GDB Locals para el subproceso en la línea actual (
gdb-display-locals-for-thread
).r
Muestra el búfer de registros GDB para el subproceso en la línea actual (
gdb-display-registers-for-thread
).
Sus homólogos en mayúsculas, D
, F
, L
y R
, muestran el búfer correspondiente en un nuevo marco.
Cuando se puede crear un búfer que muestre información sobre un subproceso específico, se vincula a ese subproceso y sigue mostrando la información real mientras se depura el programa. El indicador de modo de cada búfer GDB muestra el número de la hebra cuya información muestra ese búfer. El número de subproceso también se incluye en el nombre de cada búfer vinculado.
Hay más comandos disponibles en el búfer de hilos GDB que dependen del modo de GDB que se usa para controlar la ejecución de su programa. Ver 28.6.5.8. Depuración Multihilo.
28.6.5.5. Búfer de pila
El búfer de pila del GDB muestra una pila de llamadas, con una línea para cada una de las llamadas a subrutinas anidadas (marcos de pila) en la sesión del depurador. Ver Trazas Anteriores (Backtraces) en El depurador GNU.
En pantallas gráficas, el marco de pila seleccionado se indica con una flecha en el borde. En terminales de texto, o cuando las franjas están desactivados, el marco de pila seleccionado se muestra en contraste inverso. Para seleccionar un marco de pila, mueva el punto en su línea y escriba RETURN (RET
, gdb-frames-select
), o haga clic con ratón-2
sobre él. Al hacerlo, también se actualiza el búfer Locals (véase 28.6.5.6. Otros Búferes GDB).
Si desea que la dirección del marco se muestre en cada marco de pila, personalice la variable gdb-stack-buffer-addresses
a un valor no nulo.
28.6.5.6. Otros Búferes GDB
Otros búferes proporcionados por M-x gdb cuya visualización puede solicitar opcionalmente incluyen:
- Búfer de variables locales
Este búfer muestra los valores de las variables locales del marco de pila actual para tipos de datos simples (ver Información Sobre un Marco) en El depurador GNU. Pulse RETURN (
RET
) o haga clic conratón-2
sobre el valor si quiere editarlo.Las matrices y estructuras sólo muestran su tipo. Con GDB 6.4 o posterior, puede examinar el valor de la variable local en el punto tecleando RETURN (
RET
), o con un clic deratón-2
. Con versiones anteriores de GDB, useRET
oratón-2
en la descripción del tipo ([struct/union]
o[array]--
). Ver 28.6.5.7 Observa las Expresiones.Para mostrar el búfer Locals, escriba
M-x gdb-display-locals-buffer
.- Búfer de E/S
Si el programa que está depurando usa flujos de entrada y salida estándar para interactuar con el Usuario, o emite una cantidad significativa de salida a su salida estándar, puede que desee separar su E/S de la interacción con GDB. Usa el comando
M-x gdb-display-io-buffer
para mostrar una ventana con un búfer al que Emacs redirige la entrada y salida del programa que está depurando.- Búfer de Registros
Este búfer muestra los valores contenidos en los registros (ver Registros en El depurador GNU). Solicite la visualización de este búfer con el comando
M-x gdb-display-registers-buffer
. Pulse RETURN (RET
) o haga clic conratón-2
en un registro si desea editar su valor. Con GDB 6.4 o posterior, los valores de registro recientemente cambiados se muestran confont-lock-warning-face
.- Búfer de ensamblador
El búfer de ensamblador muestra el marco actual como código máquina. Una flecha señala la instrucción actual, y puede establecer y eliminar puntos de interrupción como en un búfer fuente. También aparecen iconos de puntos de interrupción en la franja o margen. Para solicitar la visualización de este búfer, use
M-x gdb-display-disassembly-buffer
.- Búfer de Memoria
El búfer de memoria le permite examinar secciones de la memoria del programa (vea Examinar la memoria en El depurador GNU). Haga clic con
ratón-1
en la parte apropiada de la línea de cabecera para cambiar la dirección de inicio o el número de elementos de datos que muestra el búfer. Alternativamente, useS
oN
respectivamente. Haga clic conratón-3
en la línea de encabezado para seleccionar el formato de visualización o el tamaño de la unidad para estos elementos de datos. UsarM-x gdb-display-memory-buffer
para solicitar la visualización de este búfer.
Cuando gdb-many-windows
es distinto de cero, el búfer local comparte su ventana con el búfer de registros, al igual que los puntos de interrupción y los búferes de hilos. Para cambiar de uno a otro, haga clic con ratón-1
en el botón correspondiente de la línea de cabecera.
28.6.5.7 Observa las Expresiones
Si desea ver cómo cambia una variable cada vez que su programa se detiene, mueva el punto en el nombre de la variable y haga clic en el icono watch de la barra de herramientas (gud-watch
) o escriba Ctrl-x Ctrl-a Ctrl-w (C-x C-a C-w
). Si especifica un argumento prefijo, puede introducir el nombre de la variable en el minibúfer.
Cada expresión del reloj se muestra en la barra de velocidad (véase 22.9 Marcos con Speedbar (con barra de control o barra rápida)). Los tipos de datos complejos, como matrices, estructuras y uniones, se representan en formato de árbol. Las hojas y los tipos de datos simples muestran el nombre de la expresión y su valor y, cuando se selecciona el marco de la barra speedbar, muestran el tipo como información sobre herramientas. Los niveles superiores muestran el nombre, el tipo y el valor de la dirección para los punteros y sólo el nombre y el tipo en caso contrario. Las expresiones raíz también muestran la dirección del marco como información sobre herramientas para ayudar a identificar el marco en el que se definieron.
Para expandir o contraer un tipo de dato complejo, haga clic con ratón-2
o pulse SPACE (SPC
) en la etiqueta a la izquierda de la expresión. Emacs pide confirmación antes de expandir la expresión si su número de hijos inmediatos excede el valor de la variable gdb-max-children
.
Para borrar una expresión de reloj compleja, mueva el punto a la expresión raíz en la barra de velocidad y teclee D
(gdb-var-delete
).
Para editar una variable con un tipo de datos simple, o un elemento simple de un tipo de datos complejo, mueva el punto allí en la barra speedbar y escriba RETURN (RET
, gdb-edit-value
). O puede hacer clic con ratón-2
en un valor para editarlo. De cualquier manera, esto lee el nuevo valor usando el minibúfer.
Si establece la variable gdb-show-changed-values
a no-nil
(el valor por defecto), Emacs usa font-lock-warning-face
para resaltar los valores que han cambiado recientemente y shadow face
para hacer que las variables que han salido del ámbito sean menos perceptibles. Cuando una variable sale del ámbito no se puede editar su valor.
Si la variable gdb-delete-out-of-scope
es distinta de nil
(el valor por defecto), Emacs borra automáticamente las expresiones watch que salen de ámbito. A veces, cuando su programa vuelve a entrar en la misma función muchas veces, puede ser útil establecer este valor a nil para no tener que volver a crear la expresión de observación.
Si la variable gdb-use-colon-colon-notation
no es nula, Emacs usa el formato function::variable
. Esto permite al Usuario mostrar expresiones de reloj que comparten el mismo nombre de variable. El valor por defecto es nil
.
Para subir automáticamente el acelerador cada vez que se actualiza la visualización de las expresiones de control, establezca gdb-speedbar-auto-raise
a no-nil
. Esto puede ser útil si está depurando con un marco Emacs a pantalla completa.
28.6.5.8. Depuración Multihilo
En el modo all-stop de GDB, cuando su programa se detiene, son detenidos todos los hilos de ejecución. Del mismo modo, cuando reinicia el programa, todos los hilos comienzan a ejecutarse. Vea Modo de Parada Completa (All-Stop Mode) en El depurador GNU (The GNU debugger). Para algunos objetivos multihilo, GDB soporta un modo adicional de operación, llamado modo sin parada, en el cual puede examinar hilos de programa detenidos en el depurador mientras otros hilos continúan ejecutándose libremente. Vea Modo Sin Parada en El depurador GNU. Las versiones de GDB anteriores a la 7.0 no soportan el modo non-stop, y no funciona en todos los sistemas.
La variable gdb-non-stop-setting
determina si Emacs ejecuta GDB en modo all-stop o en modo non-stop. El valor por defecto es t
, lo que significa que intenta usar el modo non-stop si está disponible. Si cambia el valor a nil
, o si el modo non-stop no está disponible, Emacs ejecuta GDB en modo all-stop. La variable tiene efecto cuando Emacs comienza una sesión de depuración; si cambias su valor, debes reiniciar cualquier sesión de depuración activa.
Cuando un hilo se detiene en modo non-stop, Emacs normalmente cambia a ese hilo. Si no desea que Emacs haga este cambio si otro hilo detenido ya está seleccionado, cambie la variable gdb-switch-when-another-stopped
a nil
.
Emacs puede decidir si cambiar o no al hilo detenido dependiendo de la razón que causó la parada. Personalice la variable gdb-switch-reasons
para seleccionar las razones de parada que causarán un cambio de hilo.
La variable gdb-stopped
-functions le permite ejecutar sus funciones siempre que algún hilo se detenga.
En modo non-stop, puede cambiar entre diferentes modos para los comandos de control de ejecución de GUD
- Non-stop/A
Cuando
gdb-gud-control-all-threads
est
(el valor por defecto), los comandos de interrupción y continuación se aplican a todos los hilos, por lo que puede detener o continuar todos sus hilos con un solo comando usandogud-stop-subjob
ygud-cont
, respectivamente. El botón Go (Ir) se muestra en la barra de herramientas cuando al menos un hilo está detenido, mientras que el botón “Stop” (Detener) se muestra cuando al menos un hilo está en ejecución.- Non-stop/T
Cuando
gdb-gud-control-all-threads
esnil
, sólo se detiene/continúa el hilo actual. Los botones Go y Stop de la barra de herramientas de GUD se muestran dependiendo del estado del hilo actual.
Puede cambiar el valor actual de gdb-gud-control-all-threads
desde la barra de herramientas o desde el menú GUD->GDB-MI
.
Los comandos de paso siempre se aplican al hilo actual.
En modo non-stop, puede interrumpir/continuar los hilos sin seleccionarlos. Pulsando i (i
) en el búfer de hilos se interrumpe el hilo en cuestión, c
lo continúa, s
lo atraviesa. Es posible que en el futuro se añadan más comandos de este tipo.
Tenga en cuenta que cuando interrumpe un hilo, se detiene con la razón signal received
(señal recibida). Si esa razón está incluida en su gdb-switch-reasons
(lo está por defecto), Emacs cambiará a ese hilo.
28.7. Ejecución de Expresiones Lisp
Emacs tiene modos principales para varias variantes de Lisp. Usan los mismos comandos de edición que otros modos de lenguajes de programación (véase 27 Edición de Programas). Además, proporcionan comandos especiales para ejecutar expresiones Lisp.
- Emacs Lisp Mode (modo Emacs Lisp)
El modo para editar archivos fuente Emacs Lisp. Define
C-M-x
para evaluar la expresión Lisp de nivel superior actual. Véase 28.9. Evaluación de Expresiones Emacs Lisp Evaluación de Expresiones Emacs Lisp.- Lisp Interaction mode (modo de Interacción Lisp)
El modo para una sesión interactiva de Emacs Lisp. Define
C-j
para evaluar la expresión antes de punto e insertar su valor en el búfer. Véase 28.10. Búferes de Interacción Lisp.- Lisp mode (modo Lisp)
El modo para editar archivos fuente de programas que se ejecutan en Lisps distintos de Emacs Lisp. Define
C-M-x
para evaluar la expresión de nivel superior actual en un Lisp externo. Véase 28.11. Ejecutar un Lisp externo.- Inferior Lisp Mode (modo inferior Lisp)
El modo para una sesión interactiva con un Lisp externo que está siendo ejecutado como un subproceso (o proceso inferior) de Emacs. Ver 28.11. Ejecutar un Lisp externo.
- Scheme mode
Como el modo Lisp, pero para programas Scheme.
- Inferior Scheme mode
Como el modo Inferior de Lisp, pero para Scheme.
28.8 Bibliotecas de Código Lisp para Emacs
El código Lisp de Emacs se almacena en archivos cuyos nombres terminan convencionalmente en .el
. Tales archivos se visitan automáticamente en el modo Emacs Lisp.
El código Emacs Lisp puede compilarse en código byte, que se carga más rápido, ocupa menos espacio y se ejecuta más rápido. Por convención, el código Emacs Lisp compilado va en un archivo separado cuyo nombre termina en .elc``. Por ejemplo, el código compilado para foo.el
va en foo.elc
. Ver Compilación de Bytes en el Manual de Referencia de Emacs Lisp.
El código Emacs Lisp también puede compilarse en código nativo: código máquina no muy diferente del producido por un compilador C o Fortran. El código nativo se ejecuta incluso más rápido que el código byte. El código Emacs Lisp compilado nativamente se almacena en archivos cuyos nombres terminan en .eln
. Véase Compilación nativa en el Manual de referencia de Emacs Lisp.
Para cargar un archivo Emacs Lisp, escriba Alt-x (M-x load-file
). Este comando lee un nombre de archivo usando el minibúfer, y ejecuta el contenido de ese archivo como código Emacs Lisp. No es necesario visitar el archivo primero; este comando lee el archivo directamente del disco, no de un búfer Emacs existente.
Si un archivo Emacs Lisp está instalado en la ruta de carga de Emacs Lisp (definida más abajo), puede cargarlo tecleando Alt-x load-library
(M-x load-library
), en lugar de usar M-x load-file
. La orden M-x load-library
pide un nombre de biblioteca en lugar de un nombre de fichero; busca en cada directorio de la ruta de carga de Emacs Lisp, intentando encontrar un archivo que coincida con ese nombre de biblioteca. Si el nombre de la biblioteca es foo
, intenta buscar archivos llamados foo.elc
, foo.el
, y foo
. (Si Emacs fue construido con la compilación nativa activada, load-library
busca un archivo .eln
que corresponda a foo.el
y lo carga en lugar de foo.elc
). El comportamiento por defecto es cargar el primer archivo encontrado. Este comando prefiere los archivos .eln
a los archivos .elc
, y prefiere los archivos .elc
a los archivos .el
, porque los archivos compilados se cargan y ejecutan más rápido. Si encuentra que lib.el
es más reciente que lib.elc
, emite una advertencia, en caso de que alguien haya hecho cambios en el archivo .el
y haya olvidado recompilarlo, pero carga el archivo .elc
de todos modos. (Debido a este comportamiento, puede guardar ediciones inacabadas en los archivos fuente de Emacs Lisp, y no recompilar hasta que sus cambios estén listos para usar). Sin embargo, si establece la opción load-prefer-newer
a un valor no nulo, entonces en lugar del procedimiento descrito anteriormente, Emacs carga cualquier versión del archivo que sea más reciente. Si Emacs fue construido con compilación nativa, y no puede encontrar el archivo .eln
correspondiente a lib.el
, cargará un lib.elc
e iniciará la compilación nativa de lib.el
en segundo plano, luego cargará el archivo .eln
cuando termine la compilación.
Los programas Emacs Lisp suelen cargar archivos Emacs Lisp usando la función load
. Es similar a load-library
, pero es de nivel inferior y acepta argumentos adicionales. Vea Cómo Cargan los Programas en el Manual de Referencia de Emacs Lisp.
La ruta de carga de Emacs Lisp se especifica mediante la variable load-path
. Su valor debe ser una lista de directorios (cadenas). Estos directorios son buscados, en el orden especificado, por la orden M-x load-library
, la función load
de nivel inferior, y otras funciones de Emacs que encuentran bibliotecas Emacs Lisp. Una entrada en load-path
también puede tener el valor especial nil
, que representa el directorio actual por defecto, pero casi siempre es una mala idea usarlo, porque su significado dependerá del búfer que esté activo cuando load-path
sea usado por el Editor. (Si se encuentra con que desearía que nil
estuviera en la lista, lo más probable es que lo que realmente quiera sea usar M-x load-file
).
El valor por defecto de load-path
es una lista de directorios donde se almacena el código Lisp del propio Emacs. Si tiene bibliotecas propias en otro directorio, puede añadir ese directorio a la ruta de carga. A diferencia de la mayoría de las otras variables descritas en este manual, load-path
no puede cambiarse a través de la interfaz Customize (ver 50.1 Interfaz de Personalización Fácil), pero puede añadirle un directorio poniendo una línea como esta en su archivo init (ver 50.4. El Archivo de Inicialización de Emacs):
(add-to-list 'load-path "/ruta/a/mi/lisp/librería")
Es habitual colocar las bibliotecas instaladas localmente en el directorio site-lisp
que ya está en el valor por defecto de load-path
, o en algún subdirectorio de site-lisp
. De esta forma, no es necesario modificar el valor por defecto de load-path
.
De forma similar a load-path
, la lista de directorios donde Emacs busca archivos *.eln
con código Lisp compilado nativamente se especifica mediante la variable native-comp-eln-load-path
.
Algunos comandos se cargan automáticamente; cuando los ejecuta, Emacs carga primero la biblioteca asociada. Por ejemplo, el comando de compilación M-x
(ver 28.1 Ejecutar Compiladores en Emacs) es autocargado; si lo invoca, Emacs carga automáticamente la biblioteca de compilación primero. Por el contrario, el comando M-x recompile
no está autocargado, por lo que no está disponible hasta que cargue la biblioteca de compilación.
La carga automática también puede ocurrir cuando busca la documentación de un comando autocargado (vea 11.3 Ayuda por Comando o Nombre de Variable), si la documentación se refiere a otras funciones y variables en su biblioteca (cargar la biblioteca permite a Emacs configurar correctamente los hipervínculos en el búfer *Help*
). Para desactivar esta función, cambie la variable help-enable-autoload
a nil
.
La carga automática también ocurre cuando se completan los nombres para describe-variable
y describe-función
, basándose en el prefijo que se está completando. Para desactivar esta función, cambie la variable help-enable-completion-autoload
a nil
.
Una vez que haya puesto su biblioteca en un directorio donde Emacs pueda encontrarla y cargarla, puede que desee hacerla disponible al inicio. Esto es útil cuando la biblioteca define características que deberían estar disponibles automáticamente bajo demanda, y cargar manualmente la biblioteca es por tanto inconveniente. En estos casos, asegúrese de que la biblioteca se cargará añadiendo las formas adecuadas a su archivo init: load
o require
(si siempre necesita cargar la biblioteca al inicio), o autoload si necesita que Emacs cargue la biblioteca cuando se invoque algún comando o función. Por ejemplo:
;; Carga my-shining-package.elc incondicionalmente.
(require 'mi-paquete-brillante)
;; Cargará mi-paquete-brillante.elc cuando se invoque a mi-func.
(autoload 'mi-func "mi-paquete-brillante")
Tenga en cuenta que instalar un paquete usando package-install
(ver 49.3 Instalación de Paquetes) se encarga de colocar los archivos Lisp del paquete en un directorio donde Emacs los encuentre, y también escribe el código de inicialización necesario en sus archivos init, haciendo innecesarias las personalizaciones manuales anteriores.
28.9. Evaluación de Expresiones Emacs Lisp
El modo Emacs Lisp es el modo principal para editar Emacs Lisp. Su comando de modo es M-x emacs-lisp-mode
.
Emacs proporciona varios comandos para evaluar expresiones Emacs Lisp. Puedes usar estos comandos en modo Emacs Lisp, para probar su código Emacs Lisp mientras se escribe. Por ejemplo, después de reescribir una función, puede evaluar la definición de la función para que tenga efecto en las siguientes llamadas a la función. Estos comandos también están disponibles globalmente, y pueden usarse fuera del modo Emacs Lisp.
Alt-x (M-:
)
Lee una única expresión Emacs Lisp en el minibúfer, la evalúa e imprime el valor en el área de eco (
eval-expression
).
Ctrl-x e (C-x C-e
)
Evalúa la expresión Emacs Lisp anterior a punto, e imprime el valor en el área de eco (
eval-last-sexp
).
C-M-x
, en Emacs Lisp mode)eval-defun
(M-x eval-defun
)Evalúa el defun que contiene o después del punto, e imprime el valor en el área de eco (
eval-defun
).
Alt-x eval-region
(M-x eval-region
)
Evalúa todas las expresiones Emacs Lisp de la región.
Alt-x (M-x eval-buffer
)
Evalúa todas las expresiones Emacs Lisp del búfer.
M-:
(eval-expression
) lee una expresión usando el minibúfer, y la evalúa. (Antes de evaluar la expresión, el búfer actual vuelve al búfer que había cuando tecleó Alt-: (M-:
), no al minibúfer en el que tecleó la expresión).
El comando C-x C-e
(eval-last-sexp
) evalúa la expresión Emacs Lisp que precede al punto en el búfer, y muestra el valor en el área de eco. Cuando el resultado de una evaluación es un entero, se muestra junto con el valor en otros formatos (octal, hexadecimal y carácter si eval-expression-print-maximum-character, descrito más adelante, lo permite).
Si M-:
o C-x C-e
recibe un argumento prefijo, inserta el valor en el búfer actual en el punto, en lugar de mostrarlo en el área de eco. Si el argumento prefijo es cero, cualquier salida entera se inserta junto con su valor en otros formatos (octal, hexadecimal y carácter). Un argumento prefijo de este tipo también evita la abreviación de la salida según las variables eval-expression-print-level
y eval-expression-print-length
(véase más adelante). Del mismo modo, un argumento de prefijo -1
anula el efecto de eval-expression-print-length
.
C-x C-e
(eval-last-sexp
) trata las expresiones defvar de forma especial. Normalmente, evaluar una expresión defvar no hace nada si la variable que define ya tiene un valor. Pero este comando reinicia incondicionalmente la variable al valor inicial especificado por defvar; esto es conveniente para depurar programas Emacs Lisp. Las expresiones defcustom y defface se tratan de forma similar. Tenga en cuenta que los otros comandos documentados en esta sección, excepto eval-defun, no tienen esta característica especial.
El comando eval-defun
está vinculado a C-M-x
en modo Emacs Lisp. Evalúa la expresión Lisp de nivel superior que contiene o sigue al punto, e imprime el valor en el área de eco. En este contexto, una expresión de nivel superior se denomina «defun», pero no tiene por qué ser un defun
real (definición de función).
Este comando maneja las formas defvar/defcustom/defface
del mismo modo que eval-last-sexp
.
Con un argumento prefijo, C-M-x
instrumenta la definición de función para Edebug, el depurador de Emacs Lisp. Ver Instrumentación para Edebug en el Manual de Referencia de Emacs Lisp.
El comando M-x eval-region
analiza el texto de la región como una o más expresiones Lisp, evaluándolas una a una. M-x eval-buffer
es similar pero evalúa todo el búfer.
Las opciones eval-expression-print-level
y eval-expression-print-length
controlan la profundidad y longitud máximas de las listas que se imprimirán en el resultado de los comandos de evaluación antes de abreviarlos. Si se proporciona un argumento de prefijo cero a eval-expression
o eval-last-sexp
, las listas se imprimen completas. eval-expression-debug-on-error
controla si los errores de evaluación invocan al depurador cuando se usan estos comandos; su valor por defecto es t
. eval-expression-print-maximum-character
evita que los enteros que sean mayores que él se muestren como caracteres.
28.10. Búferes de Interacción Lisp
Cuando Emacs arranca, contiene un búfer llamado *scratch*
, que se proporciona para evaluar expresiones Emacs Lisp interactivamente. Su modo principal es el modo de Interacción Lisp. También puede activar el modo de interacción de Lisp escribiendo M-x lisp-interaction-mode
.
Si elimina el búfer *scratch*
, puede volver a crearlo con la orden M-x scratch-buffer
.
En el búfer *scratch*
y en otros búferes del modo de interacción de Lisp, C-j
(eval-print-last-sexp
) evalúa la expresión Lisp anterior al punto e inserta el valor en el punto. Así, al escribir expresiones en el búfer seguidas de C-j
después de cada expresión, el búfer registra una transcripción de las expresiones evaluadas y sus valores. Todos los demás comandos en el modo Lisp Interaction son los mismos que en el modo Emacs Lisp.
Al iniciarse, el búfer *scratch*
contiene un breve mensaje, en forma de comentario Lisp, que explica para qué sirve. Este mensaje está controlado por la variable initial-scratch-message
, que debe ser una cadena de documentación, o nil
(que significa suprimir el mensaje).
Una forma alternativa de evaluar expresiones Emacs Lisp interactivamente es usar el modo Emacs Lisp Inferior, que proporciona una interfaz parecida al modo Shell (ver 39.3 Modo Shell) para evaluar expresiones Emacs Lisp. Escriba Alt-x ielm
(M-x ielm
) para crear un búfer *ielm*
que use este modo. Para más información, consulte la documentación de este comando.
28.11. Ejecutar un Lisp externo
El modo Lisp es el modo principal para editar programas escritos en dialectos Lisp de propósito general, como Common Lisp. Su comando de modo es M-x lisp-mode
. Emacs usa el modo Lisp automáticamente para archivos cuyos nombres terminan en .l
, .lsp
, o .lisp
.
Puede ejecutar una sesión Lisp externa como un subproceso o proceso inferior de Emacs, y pasarle expresiones para que sean evaluadas. Para iniciar una sesión Lisp externa, escriba Alt-x run-lisp
(M-x run-lisp
). Esto ejecuta el programa llamado lisp
, y lo configura para que tanto la entrada como la salida pasen por un búfer de Emacs llamado *inferior-lisp*
. Para cambiar el nombre del programa Lisp ejecutado por M-x run-lisp
, cambie la variable inferior-lisp-program
.
El modo principal del búfer *lisp*
es el modo Lisp inferior, que combina las características del modo Lisp y del modo Shell (véase 39.3 Modo Shell). Para enviar una entrada a la sesión Lisp, vaya al final del búfer *lisp*
y escriba la entrada, seguida de RET
. La salida del terminal de la sesión Lisp se inserta automáticamente en el búfer.
Cuando edite un programa Lisp en modo Lisp, puede escribir Ctrl-Alt-x (C-M-x
, lisp-eval-defun
) para enviar una expresión desde el búfer del modo Lisp a una sesión Lisp que haya iniciado con M-x run-lisp
. La expresión enviada es la expresión Lisp de nivel superior en o siguiente punto. El valor resultante va como de costumbre al búfer *inferior-lisp*
. Observe que el efecto de C-M-x
en modo Lisp es, por tanto, muy similar a su efecto en modo Emacs Lisp (véase Evaluación de Expresiones Emacs Lisp), salvo que la expresión se envía a un entorno Lisp diferente en lugar de evaluarse en Emacs.
Las facilidades para editar código Scheme, y para enviar expresiones a un subproceso Scheme, son muy similares. Los archivos fuente de Scheme se editan en modo Scheme, que puede activarse explícitamente con M-x scheme-mode
. Puede iniciar una sesión de Scheme tecleando Alt-x run-scheme
(M-x run-scheme
) (el búfer para interactuar con Scheme se llama *scheme*
), y enviarle expresiones tecleando Ctrl-Alt-x (C-M-x
).