52 Tratando con Problemas de Emacs
Esta sección describe cómo reconocer y tratar situaciones en las que Emacs no funciona como esperaba, como confusiones de código de teclado, pantallas incomprensibles, quedarse sin memoria y cuelgues.
Ver 53 Informar de Fallos, para saber qué hacer cuando cree que ha encontrado un fallo en Emacs.
52.1 Niveles de Edición Recursivos
Los niveles de edición recursivos son características importantes y útiles de Emacs, pero pueden parecer fallos de funcionamiento si no los entiende.
Si la línea de modo tiene corchetes [...]
alrededor de los paréntesis que contienen los nombres de los modos mayor y menor, ha entrado en un nivel de edición recursivo. Si no lo ha hecho a propósito, o si no entiende lo que significa, debería salir del nivel de edición recursivo. Para ello, escriba Alt-x top-level
(M-x top-level
). Véase 46 Niveles de Edición Recursiva.
52.2 Basura en la pantalla
Si el texto en un terminal de texto parece incorrecto, lo primero que hay que hacer es ver si está mal en el búfer. Escriba Ctrl-l (C-l
, recenter-top-bottom
) para volver a mostrar toda la pantalla. Si la pantalla se muestra correctamente después de esto, el problema estaba enteramente en la actualización anterior de la misma. (En caso contrario, consulte la siguiente sección).
Los problemas de actualización de pantalla a menudo son el resultado de una entrada terminfo incorrecta para el terminal que está utilizando. El fichero etc/TERMS
en la distribución de Emacs da las soluciones para problemas conocidos de este tipo. INSTALL
contiene consejos generales para estos problemas en una de sus secciones. Si le parece que está usando la entrada terminfo correcta, es posible que haya un error en la entrada terminfo, o un error en Emacs que aparece para ciertos tipos de terminal.
52.3 Basura en el Texto
Si C-l
muestra que el texto es incorrecto, primero teclee Ctrl-h l (C-h l
, view-lossage
) para ver qué comandos tecleó para producir los resultados observados. A continuación, intente deshacer los cambios paso a paso utilizando C-x u
(undo
, deshacer), hasta que vuelva a un estado que considere correcto.
Si parece que falta una gran parte del texto al principio o al final del búfer, compruebe si aparece la palabra Narrow
(Estrecho) en la línea de modo. Si aparece, es probable que el texto que no ve aún esté presente, pero temporalmente fuera de los límites. Para que vuelva a ser accesible, escriba Ctrl-x nw (C-x n w
, widen
, ampliar). Véase 15.5 Estrechamiento.
52.4 Si se queda sin Memoria
Si recibe el mensaje de error Virtual memory exceeded
(Memoria virtual excedida), guarde sus búferes modificados con C-x s
(save-some-buffers
). Este método de guardarlos es el que menos memoria adicional necesita. Emacs mantiene una reserva de memoria que hace disponible cuando ocurre este error; eso debería ser suficiente para permitir a C-x s
completar su trabajo. Cuando se ha usado la reserva, aparece !MEM FULL!
al principio de la línea de modo, indicando que no hay más reserva.
Una vez que haya guardado sus búferes modificados, puede salir de esta sesión de Emacs y empezar otra, o puede usar M-x kill-some-buffers
para liberar espacio en el trabajo actual de Emacs. Si esto libera suficiente espacio, Emacs rellenará su reserva de memoria, y !MEM FULL!
desaparecerá de la línea de modo. Esto significa que puede seguir editando con seguridad en la misma sesión de Emacs.
No use M-x buffer-menu
para guardar o matar búferes cuando se quedes sin memoria, porque Buffer Menu necesita una buena cantidad de memoria por sí mismo, y la cantidad disponible puede no ser suficiente.
En los sistemas GNU/Linux, Emacs normalmente no recibe notificaciones sobre situaciones de falta de memoria; en su lugar, el sistema operativo puede matar el proceso Emacs cuando se queda sin memoria. Esta característica se conoce como out-of-memory killer (destructor de memoria insuficiente), u OOM killer. Cuando este comportamiento está en efecto, Emacs es incapaz de detectar la situación de falta de memoria a tiempo, y no podrá permitirte guardar tu búfer como se ha descrito anteriormente. Sin embargo, es posible desactivar este comportamiento del SO, y así permitir a Emacs una oportunidad de manejar la situación de falta de memoria de una manera más útil, antes de que se mate. Para ello, conviértase en superusuario, edite el archivo /etc/sysctl.conf
para que contenga las líneas que se muestran a continuación, luego invoque el comando sysctl -p
desde el prompt del shell:
vm.overcommit_memory=2
vm.overcommit_ratio=0
Tenga en cuenta que la configuración anterior afecta a todos los procesos del sistema y, en general, al comportamiento del sistema bajo condiciones de sobrecarga de memoria, no sólo al proceso Emacs.
52.5 Cuando Emacs se Bloquea
Se supone que Emacs no se cuelga, pero si lo hace, produce un informe de fallo antes de salir. Dicho informe se imprime en la salida de error estándar. Si el Editor se inició desde un escritorio gráfico en un sistema GNU o Unix, el flujo de error estándar se redirige normalmente a un archivo como ~/.xsession-errors
, por lo que puede buscar el informe de fallo allí. En MS-Windows, el informe de fallo se escribe en un fichero llamado emacs_backtrace.txt
en el directorio actual del proceso Emacs, además de la salida de error estándar.
El formato del informe de error depende de la plataforma. En algunas, como las que usan la librería GNU C, el informe de fallo incluye un seguimiento (backtrace) que describe el estado de ejecución previo al fallo, que puede usarse para ayudar a depurar el fallo. He aquí un ejemplo para un sistema GNU:
Fatal error 11: Segmentation fault
Backtrace:
emacs[0x5094e4]
emacs[0x4ed3e6]
emacs[0x4ed504]
/lib64/libpthread.so.0[0x375220efe0]
/lib64/libpthread.so.0(read+0xe)[0x375220e08e]
emacs[0x509af6]
emacs[0x5acc26]
…
El número 11
es el número de señal del sistema correspondiente al fallo, en este caso un fallo de segmentación. Los números hexadecimales son direcciones de programa, que pueden asociarse a líneas de código fuente utilizando una herramienta de depuración. Por ejemplo, el comando de GDB list *0x509af6
imprime las líneas de código fuente correspondientes a la entrada emacs[0x509af6]
. Si su sistema tiene la utilidad addr2line
, el siguiente comando de shell muestra un trazado (backtrace) con los números de línea del código fuente:
sed -n 's/.*\[\(.*\)]$/\1/p' backtrace |
addr2line -C -f -i -p -e bindir/emacs-binary
En MS-Windows, el backtrace tiene un aspecto algo diferente, por ejemplo:
Backtrace:
00007ff61166a12e
00007ff611538be1
00007ff611559601
00007ff6116ce84a
00007ff9b7977ff0
…
Por lo tanto, el filtrado mediante sed
no es necesario, y el comando para mostrar el número de línea del código fuente es
addr2line -C -f -i -p -e direct-informe/binario-emacs < rastreo
Aquí, rastreo es el nombre de un archivo de texto que contiene una copia del backtrace (en MS-Windows, emacs_backtrace.txt
en el directorio donde se inició Emacs), direct-informe es el nombre del directorio que contiene el ejecutable de Emacs, y binario-emacs es el nombre del archivo ejecutable de Emacs, normalmente emacs
en sistemas GNU y Unix y emacs.exe
en MS-Windows y MS-DOS. Omita la opción -p
si su versión de addr2line
es demasiado antigua para tenerla.
Opcionalmente, Emacs puede generar un volcado del núcleo cuando se bloquea, en sistemas que soporten archivos de núcleo. Un volcado del núcleo es un archivo que contiene datos voluminosos sobre el estado del programa antes del fallo, normalmente examinado cargándolo en un depurador como GDB. En muchas plataformas, los volcados de memoria están deshabilitados por defecto, y debe habilitarlos explícitamente ejecutando el comando de shell ulimit -c unlimited
(por ejemplo, en su script de inicio de shell).
52.6 Recuperación tras un fallo
Si Emacs o el ordenador se bloquean, puede recuperar los archivos que estaba editando en el momento del bloqueo desde sus archivos de autoguardado. Para ello, inicie Emacs de nuevo y escriba el comando M-x recover-session
.
Este comando muestra inicialmente un buffer que lista los archivos de sesión interrumpidos, cada uno con su fecha. Debe elegir de qué sesión quiere recuperarse. Normalmente la que quiere es la más reciente. Mueva el punto a la que elija y teclee Ctrl-c Ctrl-c (C-c C-c
).
A continuación, recover-session
tiene en cuenta cada uno de los archivos que ha editado durante la sesión y le pregunta si desea recuperarlo. Si la respuesta es y
(sí) para un archivo, se muestran las fechas de ese archivo y de su fichero de autoguardado, y se vuelve a preguntar si se quiere recuperar ese fichero. Para la segunda pregunta, debe confirmar con yes
(sí). Si lo hace, Emacs visita el archivo pero obtiene el texto del fichero de autoguardado.
Cuando recover-session
termina, los archivos que ha elegido recuperar están presentes en los buffers de Emacs. A continuación, debe guardarlos. Sólo esto -guardarlos- actualiza los propios archivos.
Como último recurso, si tiene búferes con contenido que no está asociado a ningún archivos, o si el autoguardado no es lo suficientemente reciente como para haber registrado cambios importantes, puede usar el script etc/emacs-buffer.gdb
con GDB (el depurador de GNU) para recuperarlos de un volcado del núcleo, siempre que se haya guardado uno, y que el ejecutable de Emacs no haya sido despojado de sus símbolos de depuración.
Tan pronto como obtenga el volcado del núcleo, renómbrelo con otra asignación como core.emacs
, para que otro fallo no lo sobrescriba.
Para utilizar este script, ejecute gdb
con el nombre de archivo de su ejecutable Emacs y el nombre de archivo del volcado del núcleo, por ejemplo, gdb /usr/bin/emacs core.emacs
. En el prompt (gdb)
, carga el script de recuperación: source /usr/src/emacs/etc/emacs-buffer.gdb
. A continuación, escriba el comando ybuffer-list
para ver qué búferes están disponibles. Para cada búfer, lista un número de búfer. Para guardar un búfer, utilice ysave-buffer
; especifique el número de búfer y el nombre de archivo en el que escribirlo. Debe utilizar un nombre de fichero que no exista ya; si el fichero existe, el script no hace una copia de seguridad de su contenido antiguo.
52.7 Escape de Emergencia
En terminales de texto, la característica escape de emergencia suspende Emacs inmediatamente si teclea Ctrl-g (C-g
) una segunda vez antes de que Emacs pueda responder a la primera saliendo. Esto es para que siempre pueda salir de GNU Emacs sin importar lo mal que pueda estar colgado. Cuando las cosas funcionan correctamente, Emacs reconoce y maneja el primer comando C-g
tan rápido que la segunda no disparará la salida de emergencia. Sin embargo, si algún problema impide que Emacs maneje la primera C-g
correctamente, entonces la segunda le devolverá al shell.
Cuando reanuda Emacs después de una suspensión causada por un escape de emergencia, informa de la recuperación y hace una pregunta o dos antes de volver a lo que había estado haciendo:
Emacs is resuming after an emergency escape.
Auto-save? (y or n)
Abort (and dump core)? (y or n)
Traducción:
Emacs se reanuda después de un escape de emergencia.
¿Autoguardar? (y o n)
¿Abortar (y volcar núcleo)? (y o n)
Responda a cada pregunta con y
(yes
, si) o n
(no
) seguido de RETURN (RET
).
Si se responde y
a ¿Auto-save?
, se guardarán inmediatamente todos los búferes modificados en los que esté activado el autoguardado. La respuesta n
omite esta opción. Esta pregunta se omite si Emacs está en un estado en el que el auto-save
(el auto guardado) no puede hacerse de forma segura.
Decir y
a ¿Abort (and dump core)? (y or n)?
hace que Emacs se bloquee, volcando el núcleo. Esto es para permitir a un asistente averiguar por qué Emacs estaba fallando al salir en primer lugar. La ejecución no continúa después de un volcado del núcleo.
Si responde a esta pregunta n
, la ejecución de Emacs se reanuda. Con suerte, Emacs finalmente hará el abandono solicitado. Si no, cada C-g
subsiguiente invoca de nuevo el escape de emergencia.
Si Emacs no está realmente colgado, sólo lento, puede invocar la doble función C-g
sin quererlo realmente. Entonces reanude y responda n
a ambas preguntas, y volverá al estado anterior. La salida solicitada se producirá de forma inmediata.
La salida de emergencia sólo está activa en los terminales de texto. En pantallas gráficas, puede usar el ratón para matar Emacs o cambiar a otro programa.
En MS-DOS, debe teclear C-Break
(dos veces) para provocar el escape de emergencia, pero hay casos en los que no funcionará, cuando se cuelgue una llamada al sistema o cuando Emacs se quede atascado en un bucle cerrado en código C.
52.8 Si DEL no Borra
Todos los teclados tienen una tecla grande, normalmente etiquetada como BACKSPACE (backspace
, RETROCESO), que se usa normalmente para borrar el último carácter que ha escrito. En Emacs, esta tecla se supone que es equivalente a DEL (DEL
).
Cuando Emacs arranca en una pantalla gráfica, determina automáticamente qué tecla debe ser DEL
. En algunos casos inusuales, Emacs recibe la información incorrecta del sistema, y BACKSPACE
acaba borrando hacia delante en lugar de hacia atrás.
Algunos teclados también tienen una tecla Supr (Supr
), que normalmente se usa para borrar hacia delante. Si esta tecla borra hacia atrás en Emacs, eso también sugiere que el Editor obtuvo la información equivocada, pero en el sentido opuesto.
En un terminal de texto, si encuentra que BACKSPACE
le pide un comando de ayuda, como Control-h
, en lugar de borrar un carácter, significa que esa tecla está enviando el carácter BS
. Emacs debería tratar BS
como DEL
, pero no lo hace.
En todos esos casos, la solución inmediata es la misma: usar el comando M-x normal-erase-is-backspace-mode
. Esto alterna entre los dos modos que Emacs soporta para manejar DEL
, así que si Emacs se inicia en el modo equivocado, esto debería cambiar al modo correcto. En un terminal de texto, si quiere pedir ayuda cuando BS
es tratado como DEL
, use F1
en lugar de C-h
; C-?
también puede funcionar, si envía el código de carácter 127.
Para solucionar el problema en cada sesión de Emacs, pon una de las siguientes líneas en su fichero de inicialización (ver 50.4. El Archivo de Inicialización de Emacs). Para el primer caso anterior, donde BACKSPACE
borra hacia delante en lugar de hacia atrás, usa esta línea para hacer que BACKSPACE
actúe como DEL
:
(normal-erase-is-backspace-mode 0)
Para los otros dos casos use la línea:
(normal-erase-is-backspace-mode 1)
Otra forma de arreglar el problema para cada sesión de Emacs es personalizar la variable normal-erase-is-backspace
: el valor t
especifica el modo donde BS
o BACKSPACE
es DEL
, y nil
especifica el otro modo. Ver 50.1 Interfaz de Personalización Fácil.