Comment déboguer un plantage emacs?

16

Je débogue pourquoi emacs se bloque lors de l'utilisation d'une fonction à partir d'un package 1 . Le but de ce processus de débogage est d'obtenir des données utiles à soumettre en utilisant M-x report-emacs-bug.

Pour obtenir de l'aide sur la façon de déboguer les plantages d'emacs, j'ai déjà regardé Emacs Manual - Crashing et Emacs Manual - After a Crash , mais ils n'ont pas aidé.

Le manuel After A Crash fait référence emacs-buffer.gdbmais je ne sais pas comment l'utiliser. En demandant de l'aide à Google, je suis tombé sur cette question emacs.SE et j'ai recompilé emacs en utilisant les -ggdb3drapeaux.

Je n'ai aucune expérience préalable de l'utilisation gdbet j'ai donc tenté quelques tentatives infructueuses d'utilisation du emacs-buffer.gbdfichier.

Voici ce que j'ai essayé:

  • gdb -x /path/to/emacs-buffer.gdb
  • gdb -> file /path/to/emacs-buffer.gdb
  • gdb -> source /path/to/emacs-buffer.gdb
  • source /path/to/emacs-buffer.gdb

Sur une note latérale, emacs compilé avec le -ggdb3drapeau prend environ 10 secondes de plus à charger; plus tôt, c'était 5-6 secondes, maintenant environ 16-17 secondes. Je connais les secondes exactes à cause d'un code qui calcule cela dans mon init. Cette augmentation du temps de démarrage est-elle attendue?


Note de bas de page 1: emacs se bloque systématiquement lors d'une undo-treetentative de restauration de l'historique d'annulation d'un fichier .org particulier (que je ne peux pas partager publiquement). Je l'ai (setq undo-tree-auto-save-history t). Ce plantage ne se produit que sur emacs git master, pas sur emacs 24.5. Sur emacs 24.5, undo-treegénère une erreur indiquant qu'il est impossible de charger l'historique d'annulation (même si le fichier historique d'annulation existe), mais au moins la session emacs ne se bloque pas sur cette version.

Kaushal Modi
la source
2
Cela fait plus de deux ans que j'utilise Emacs et je ne l'ai toujours pas vraiment compris: stackoverflow.com/q/20891431/2112489 Pour être honnête, c'est un peu un mystère et il devrait y avoir un fil faisant autorité qui enseigne comment faire il.
lawlist
D'accord, la question est d'obtenir le nombre de vues, mais pas de votes positifs. Faites-moi savoir si vous avez besoin de moi pour améliorer la question. Si vous pensez que la question peut apporter une bonne réponse et peut être utile à la communauté emacs, veuillez la voter de manière à ce qu'elle retienne l'attention d'un répondeur potentiel.
Kaushal Modi
Je ne veux pas détourner votre fil, mais je ferai une suggestion. Si le thread n'attire pas de réponse appropriée dans un délai raisonnable (c'est-à-dire que vous décidez ce que cela signifie), il peut être utile de rendre ce thread plus général - par exemple, le thread faisant autorité sur la façon d'utiliser gdb pour déboguer Emacs se bloque, créer des backtraces significatives qui aideront les gourous de l'équipe de développement Emacs à diagnostiquer / dépanner les problèmes lors de la réception d'un rapport de bogue contenant lesdites informations. Je comprends que la question est importante en raison de undue-treeproblèmes, mais elle a un potentiel plus large .
lawlist
@lawlist C'est exactement ce que j'attends de ce fil. Je ne m'attendais pas à une undo-treeréponse spécifique car je sais qu'il serait difficile pour quelqu'un d'autre de recréer ce crash exact. Je ne peux pas non plus partager l'intégralité du fichier org, qui est le seul qui semble provoquer ce plantage. J'ai donc appliqué uniquement la gdbbalise à cette question. J'ai donné cette histoire en arrière afin que les réponses puissent me guider sur la façon de déboguer un crash emacs en général afin que je puisse déposer un rapport de bogue emacs utile .
Kaushal Modi
@lawlist J'ai reformulé la question afin qu'il soit clair qu'elle n'est spécifique à aucun paquet.
Kaushal Modi

Réponses:

15

La façon la plus simple de déboguer un crash Emacs est de démarrer Emacs sous gdb, puis de faire tout ce qui reproduit le crash.

En supposant que vous construisez vos Emacs à partir des sources, vous devez passer CFLAGS="-O0 -g3"au ./configurescript. Cela fait que le compilateur C désactive les optimisations (ce qui peut rendre les choses confuses lors du débogage) et active le maximum d'informations de débogage dans l'exécutable. Courez makepour construire Emacs.

Ensuite, démarrez à gdbpartir du srcrépertoire de votre arborescence Emacs:

$ cd ~/my-emacs-tree/src
$ gdb ./emacs

Sur OSX, vous voudrez passer --with-nsau ./configurescript et démarrer gdb sur Emacs à l'intérieur de l'application créée:

$ cd ~/my-emacs-tree
$ make install
$ cd src
$ gdb nextstep/Emacs.app/Contents/MacOS/Emacs

La raison de commencer à partir du srcrépertoire est qu'il existe un .gdbinitfichier qui définit des définitions de fonction GDB utiles pour le débogage d'Emacs. Si ce fichier a été chargé, vous devriez voir quelque chose comme ça au démarrage gdb:

DISPLAY = /private/tmp/com.apple.launchd.cNjhIdtUNd/org.macosforge.xquartz:0
TERM = xterm-256color
Breakpoint 1 at 0x1000ca444: file ../../src/emacs.c, line 353.
Breakpoint 2 at 0x1000e7e34: file ../../src/sysdep.c, line 926.

Tapez rpour démarrer Emacs. Vous pouvez passer des arguments supplémentaires sur la même ligne, par exemple r --debug-init.

Essayez ensuite de faire planter Emacs. S'il se bloque, vous devriez voir une note à ce sujet gdbet vous serez de nouveau laissé à l' (gdb)invite. Si Emacs ne plante pas, mais se bloque, vous pouvez frapper C-zdans le terminal où vous exécutez gdbpour revenir à l'invite.

Une fois à l'invite, tapez btpour obtenir une trace. En prime, si le .gdbinitfichier Emacs a été correctement chargé, vous verrez une trace Lisp après la trace C. Les deux backtraces sont des éléments très utiles à inclure M-x report-emacs-bug.


Il y a beaucoup plus d'informations, y compris comment examiner l'état des variables, etc., dans le etc/DEBUGfichier de l'arborescence Emacs. Vous pouvez l'ouvrir en tapant C-h C-ddans Emacs, ou vous pouvez le lire en ligne .

legoscia
la source
Merci. Je trouverai le temps aujourd'hui d'essayer votre solution. Je suis toujours curieux de savoir ce qu'il emacs-buffer.gdbfait et comment l'utiliser.
Kaushal Modi
Si je comprends bien, c'est spécifiquement pour récupérer le contenu du fichier que vous éditiez lorsque Emacs s'est écrasé. Comme Emacs enregistre automatiquement toutes les 30 secondes et toutes les 300 touches, je dirais que cela est d'une utilité limitée.
legoscia
1
Mais cela devrait également aider à récupérer les tampons non liés aux fichiers, n'est-ce pas? Mon idée était de l'utiliser pour voir ce que * Messages * et * Backtrace * avaient juste avant le crash.
Kaushal Modi
Ah, c'est un bon point. Je ne l'ai jamais utilisé moi-même, donc je ne sais pas comment le faire.
legoscia
Savez-vous comment exécuter gdb sur emacsclient? Je ne trouve pas ce binaire dans src/. Je l'ai trouvé lib-src/mais cela n'a pas fonctionné gdb ./emacsclient -a '' -c. J'ai donc besoin d'aide pour transmettre ces arguments -aet ces -carguments à emacsclient plutôt qu'à gdb.
Kaushal Modi