18

I am debugging why emacs crashes when using a function from a package1. The aim of this debug process is to get useful data to submit using M-x report-emacs-bug.

To get help on how to debug emacs crashes, I have already looked at Emacs Manual - Crashing and Emacs Manual - After a Crash, but they did not help.

The After A Crash manual refers to emacs-buffer.gdb but I have no idea how to use it. While asking google for help, I came across this emacs.SE question, and I recompiled emacs using the -ggdb3 flags.

I have no prior experience using gdb and so I tried few failed attempts to use the emacs-buffer.gbd file.

Here's what I tried:

  • 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

On a side note, emacs compiled with the -ggdb3 flag takes about 10 seconds longer to load; earlier it was 5-6 seconds, now about 16-17 seconds. I know the exact seconds because of a code that calculates that in my init. Is this increase in startup time expected?


Footnote 1: emacs crashes consistently when undo-tree tries to restore the undo history for a particular .org file (which I cannot share publicly). I have (setq undo-tree-auto-save-history t). This crash happens only on the emacs git master, not on emacs 24.5. On emacs 24.5, undo-tree throws an error stating that it's unable to load the undo history (even through the undo history file exists), but at least the emacs session does not crash on that version.

Drew
  • 75,699
  • 9
  • 109
  • 225
Kaushal Modi
  • 25,203
  • 3
  • 74
  • 179
  • 2
    I'm more than two years into using Emacs and still haven't really figured it out: http://stackoverflow.com/q/20891431/2112489 To be honest, it's somewhat of a mystery and there should be an authoritative thread that teaches how to do it. – lawlist Jul 30 '15 at 13:19
  • Alright, the question is getting view counts, but no upvotes. Let me know if you need me to improve the question. If you think that the question can yield a good answer and can be helpful to the emacs community, please upvote it so that it gets attention of a prospective answerer. – Kaushal Modi Jul 30 '15 at 14:29
  • I don't want to hijack your thread, but I'll make a suggestion. If the thread does not attract a suitable answer within a reasonable period of time (i.e., you decide what that means), it may be worthwhile to make this thread more general -- e.g., the authoritative thread on how to use gdb to debug Emacs crashes, create meaningful backtraces that will assist the gurus on the Emacs development team to diagnose/troubleshoot the issues when receiving a bug-report that contains said information. I understand the issue is important because of `undue-tree` problems, but it has broader *potential*. – lawlist Jul 31 '15 at 05:22
  • @lawlist That's exactly what I expect this thread to be. I didn't expect an `undo-tree`-specific answer because I know it would be difficult for anyone else to recreate that exact crash. Also I cannot share the whole org file which is the only one that seems to cause this crash. So I applied only the `gdb` tag to this question. I gave that back story so that the answers can guide me **how to debug an emacs crash in general so that I can file a useful emacs bug report**. – Kaushal Modi Jul 31 '15 at 10:26
  • @lawlist I have rephrased the question so that it is clear that it is not specific to any package. – Kaushal Modi Jul 31 '15 at 13:50
  • Hi @KaushalModi thank you for your post, especially mentioning `undo-tree` in the footnote. It saved me a lot of time! – kyanny Oct 11 '21 at 14:31

1 Answers1

15

The easiest way to debug an Emacs crash is to start Emacs under gdb, and then do whatever thing it is that reproduces the crash.

Assuming you're building your Emacs from source, you should pass CFLAGS="-O0 -g3" to the ./configure script. This makes the C compiler turn off optimisations (which can make things confusing while debugging) and activates maximum debug information in the executable. Run make to build Emacs.

Then, start gdb from within the src directory of your Emacs tree:

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

On OSX, you'll want to pass --with-ns to the ./configure script and start gdb on the Emacs inside the created application:

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

The reason to start from the src directory is that there is a .gdbinit file that sets up useful GDB function definitions for debugging Emacs. If that file was loaded, you should see something like this when starting 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.

Type r to start Emacs. You can pass extra arguments on the same line, e.g. r --debug-init.

Then try to make Emacs crash. If it crashes, you should see a note about it in gdb, and you'll be left at the (gdb) prompt again. If Emacs doesn't crash, but freezes, you can hit C-z in the terminal where you're running gdb to get back to the prompt.

Once at the prompt, type bt to get a backtrace. As a bonus, if the Emacs .gdbinit file was correctly loaded, you'll see a Lisp backtrace after the C backtrace. Both backtraces are very useful things to include in M-x report-emacs-bug.


There is much more information, including how to examine the state of variables etc, in the etc/DEBUG file in the Emacs tree. You can open it by typing C-h C-d inside Emacs, or you can read it online.

legoscia
  • 6,012
  • 29
  • 54
  • Thanks. I will find time today to try out your solution. I am still curious what `emacs-buffer.gdb` does and how to use it. – Kaushal Modi Jul 31 '15 at 13:51
  • As I understand it, that's specifically to recover the contents of the file you were editing when Emacs crashed. As Emacs autosaves every 30 seconds and every 300 key presses, I'd say that's of limited use. – legoscia Jul 31 '15 at 13:53
  • 1
    But that should also help recover non-file buffers, is that correct? My idea was to use that to see what \*Messages\* and \*Backtrace\* had just before the crash. – Kaushal Modi Jul 31 '15 at 13:56
  • Ah, that's a good point. I've never used it myself, so I'm not sure how to do it. – legoscia Jul 31 '15 at 15:11
  • Do you know how to run gdb on emacsclient? I cannot find that binary in `src/`. I found it in `lib-src/` though but this did not work `gdb ./emacsclient -a '' -c`. So I need help on how to pass those `-a` and `-c` args to emacsclient instead of to gdb. – Kaushal Modi Sep 01 '15 at 13:34
  • Most likely the problem would be in emacs itself, not in emacsclient. So start your Emacs instance inside gdb, as above, and then run emacsclient as usual. If there's a problem in Emacs, you'll be able to debug it in gdb. – legoscia Sep 01 '15 at 14:26
  • And to answer your question, in order to pass command line arguments to a program you're running under gdb, you can't pass them on the command line itself (as far as I know); you need to pass them to the `r` command inside gdb, e.g. `r -a '' -c`. – legoscia Sep 01 '15 at 14:28
  • These gdb instructions were very helpful for me. Would you like to contribute these to the emacs truck in its manual perhaps? – Kaushal Modi Oct 23 '15 at 11:33
  • Do you mean in addition to the instructions in the `DEBUG` file (linked at the end of the answer)? I have a feeling you would be better suited to write this up, as this is already second nature to me, but you still remember what you had to learn :) I'd be happy to review anything you come up with if you'd like. – legoscia Oct 23 '15 at 11:52