should read the Windows-specific section near the end of this
document.]
-It is a good idea to run Emacs under GDB (or some other suitable
+** When you debug Emacs with GDB, you should start it in the directory
+where you built Emacs. That directory has a .gdbinit file that defines
+various "user-defined" commands for debugging Emacs.
+
+** It is a good idea to run Emacs under GDB (or some other suitable
debugger) *all the time*. Then, when Emacs crashes, you will be able
to debug the live process, not just a core dump. (This is especially
important on systems which don't support core files, and instead print
just the registers and some stack addresses.)
-If Emacs hangs, or seems to be stuck in some infinite loop, typing
+** If Emacs hangs, or seems to be stuck in some infinite loop, typing
"kill -TSTP PID", where PID is the Emacs process ID, will cause GDB to
kick in, provided that you run under GDB.
All Lisp errors go through there.
It is useful, when debugging, to have a guaranteed way to return to
-the debugger at any time. When using X, this is easy: type C-c at the
+the debugger at any time. When using X, this is easy: type C-z at the
window where Emacs is running under GDB, and it will stop Emacs just
as it would stop any ordinary program. When Emacs is running in a
terminal, things are not so easy.
(C-g in Emacs) to be passed to Emacs and not give control back to GDB.
On modern POSIX systems, you can override that with this command:
- handle int stop nopass
+ handle SIGINT stop nopass
After this `handle' command, SIGINT will return control to GDB. If
you want the C-g to cause a QUIT within Emacs as well, omit the
the backtrace when Emacs stops inside that function will show what
code causes the X protocol errors.
+Some bugs related to the X protocol disappear when Emacs runs in a
+synchronous mode. To track down those bugs, we suggest the following
+procedure:
+
+ - Run Emacs under a debugger and put a breakpoint inside the
+ primitive function which, when called from Lisp, triggers the X
+ protocol errors. For example, if the errors happen when you
+ delete a frame, put a breakpoint inside `Fdelete_frame'.
+
+ - When the breakpoint breaks, step through the code, looking for
+ calls to X functions (the ones whose names begin with "X" or
+ "Xt" or "Xm").
+
+ - Insert calls to `XSync' before and after each call to the X
+ functions, like this:
+
+ XSync (f->output_data.x->display_info->display, 0);
+
+ where `f' is the pointer to the `struct frame' of the selected
+ frame, normally available via XFRAME (selected_frame). (Most
+ functions which call X already have some variable that holds the
+ pointer to the frame, perhaps called `f' or `sf', so you shouldn't
+ need to compute it.)
+
+ If your debugger can call functions in the program being debugged,
+ you should be able to issue the calls to `XSync' without recompiling
+ Emacs. For example, with GDB, just type:
+
+ call XSync (f->output_data.x->display_info->display, 0)
+
+ before and immediately after the suspect X calls. If your
+ debugger does not support this, you will need to add these pairs
+ of calls in the source and rebuild Emacs.
+
+ Either way, systematically step through the code and issue these
+ calls until you find the first X function called by Emacs after
+ which a call to `XSync' winds up in the function
+ `x_error_quitter'. The first X function call for which this
+ happens is the one that generated the X protocol error.
+
+ - You should now look around this offending X call and try to figure
+ out what is wrong with it.
+
** If the symptom of the bug is that Emacs fails to respond
Don't assume Emacs is `hung'--it may instead be in an infinite loop.