; etc/DEBUG copedits
* etc/DEBUG: Improve the section on debugging redisplay issues. Also other minor copyedits.
This commit is contained in:
parent
58eeddf56b
commit
34ad02767b
1 changed files with 176 additions and 96 deletions
272
etc/DEBUG
272
etc/DEBUG
|
@ -34,6 +34,13 @@ With GCC and higher optimization levels such as -O2, the
|
|||
essential. The latter prevents GCC from using the same abort call for
|
||||
all assertions in a given function, rendering the stack backtrace
|
||||
useless for identifying the specific failed assertion.
|
||||
Some versions of GCC support recent versions of the DWARF standard for
|
||||
debugging info, but default to older versions; for example, they could
|
||||
support -gdwarf-4 compiler option (for DWARF v4), but default to
|
||||
version 2 of the DWARF standard. For best results in debugging
|
||||
abilities, find out the highest version of DWARF your GCC can support,
|
||||
and use the corresponding -gdwarf-N switch instead of just -g (you
|
||||
will still need -g3, as in "-gdwarf-4 -g3").
|
||||
|
||||
** 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
|
||||
|
@ -76,11 +83,22 @@ use the set command until the inferior process has been started.
|
|||
Put a breakpoint early in `main', or suspend the Emacs,
|
||||
to get an opportunity to do the set command.
|
||||
|
||||
Another technique for get control to the debugger is to put a
|
||||
breakpoint in some rarely used function. One such convenient function
|
||||
is Fredraw_display, which you can invoke at will interactively with
|
||||
"M-x redraw-display RET".
|
||||
|
||||
When Emacs is running in a terminal, it is sometimes useful to use a separate
|
||||
terminal for the debug session. This can be done by starting Emacs as usual,
|
||||
then attaching to it from gdb with the `attach' command which is explained in
|
||||
the node "Attach" of the GDB manual.
|
||||
|
||||
On MS-Windows, you can start Emacs in its own separate terminal by
|
||||
setting the new-console option before running Emacs under GDB:
|
||||
|
||||
(gdb) set new-console 1
|
||||
(gdb) run
|
||||
|
||||
** Examining Lisp object values.
|
||||
|
||||
When you have a live process to debug, and it has not encountered a
|
||||
|
@ -120,6 +138,8 @@ type. Here are these commands:
|
|||
xint xptr xwindow xmarker xoverlay xmiscfree xintfwd xboolfwd xobjfwd
|
||||
xbufobjfwd xkbobjfwd xbuflocal xbuffer xsymbol xstring xvector xframe
|
||||
xwinconfig xcompiled xcons xcar xcdr xsubr xprocess xfloat xscrollbar
|
||||
xchartable xsubchartable xboolvector xhashtable xlist xcoding
|
||||
xcharset xfontset xfont xbytecode
|
||||
|
||||
Each one of them applies to a certain type or class of types.
|
||||
(Some of these types are not visible in Lisp, because they exist only
|
||||
|
@ -138,33 +158,32 @@ Here's an example using concepts explained in the node "Value History"
|
|||
of the GDB manual to print values associated with the variable
|
||||
called frame. First, use these commands:
|
||||
|
||||
cd src
|
||||
gdb emacs
|
||||
b set_frame_buffer_list
|
||||
r -q
|
||||
cd src
|
||||
gdb emacs
|
||||
b set_frame_buffer_list
|
||||
r -q
|
||||
|
||||
Then Emacs hits the breakpoint:
|
||||
|
||||
(gdb) p frame
|
||||
$1 = 139854428
|
||||
(gdb) xpr
|
||||
Lisp_Vectorlike
|
||||
PVEC_FRAME
|
||||
$2 = (struct frame *) 0x8560258
|
||||
"emacs@localhost"
|
||||
(gdb) p *$
|
||||
$3 = {
|
||||
size = 1073742931,
|
||||
next = 0x85dfe58,
|
||||
name = 140615219,
|
||||
[...]
|
||||
}
|
||||
(gdb) p frame
|
||||
$1 = 139854428
|
||||
(gdb) xpr
|
||||
Lisp_Vectorlike
|
||||
PVEC_FRAME
|
||||
$2 = (struct frame *) 0x8560258
|
||||
"emacs@localhost"
|
||||
(gdb) p *$
|
||||
$3 = {
|
||||
size = 1073742931,
|
||||
next = 0x85dfe58,
|
||||
name = 140615219,
|
||||
[...]
|
||||
}
|
||||
|
||||
Now we can use `pr' to print the frame parameters:
|
||||
|
||||
(gdb) pp $->param_alist
|
||||
((background-mode . light) (display-type . color) [...])
|
||||
|
||||
(gdb) pp $->param_alist
|
||||
((background-mode . light) (display-type . color) [...])
|
||||
|
||||
The Emacs C code heavily uses macros defined in lisp.h. So suppose
|
||||
we want the address of the l-value expression near the bottom of
|
||||
|
@ -174,28 +193,28 @@ we want the address of the l-value expression near the bottom of
|
|||
|
||||
XVECTOR is a macro, so GDB only knows about it if Emacs has been compiled with
|
||||
preprocessor macro information. GCC provides this if you specify the options
|
||||
`-gdwarf-2' and `-g3'. In this case, GDB can evaluate expressions like
|
||||
"p XVECTOR (this_command_keys)".
|
||||
`-gdwarf-N' (where N is 2 or higher) and `-g3'. In this case, GDB can
|
||||
evaluate expressions like "p XVECTOR (this_command_keys)".
|
||||
|
||||
When this information isn't available, you can use the xvector command in GDB
|
||||
to get the same result. Here is how:
|
||||
|
||||
(gdb) p this_command_keys
|
||||
$1 = 1078005760
|
||||
(gdb) xvector
|
||||
$2 = (struct Lisp_Vector *) 0x411000
|
||||
0
|
||||
(gdb) p $->contents[this_command_key_count]
|
||||
$3 = 1077872640
|
||||
(gdb) p &$
|
||||
$4 = (int *) 0x411008
|
||||
(gdb) p this_command_keys
|
||||
$1 = 1078005760
|
||||
(gdb) xvector
|
||||
$2 = (struct Lisp_Vector *) 0x411000
|
||||
0
|
||||
(gdb) p $->contents[this_command_key_count]
|
||||
$3 = 1077872640
|
||||
(gdb) p &$
|
||||
$4 = (int *) 0x411008
|
||||
|
||||
Here's a related example of macros and the GDB `define' command.
|
||||
There are many Lisp vectors such as `recent_keys', which contains the
|
||||
last 300 keystrokes. We can print this Lisp vector
|
||||
|
||||
p recent_keys
|
||||
pr
|
||||
p recent_keys
|
||||
pr
|
||||
|
||||
But this may be inconvenient, since `recent_keys' is much more verbose
|
||||
than `C-h l'. We might want to print only the last 10 elements of
|
||||
|
@ -206,24 +225,24 @@ this vector. `recent_keys' is updated in keyboard.c by the command
|
|||
So we define a GDB command `xvector-elts', so the last 10 keystrokes
|
||||
are printed by
|
||||
|
||||
xvector-elts recent_keys recent_keys_index 10
|
||||
xvector-elts recent_keys recent_keys_index 10
|
||||
|
||||
where you can define xvector-elts as follows:
|
||||
|
||||
define xvector-elts
|
||||
set $i = 0
|
||||
p $arg0
|
||||
xvector
|
||||
set $foo = $
|
||||
while $i < $arg2
|
||||
p $foo->contents[$arg1-($i++)]
|
||||
pr
|
||||
end
|
||||
document xvector-elts
|
||||
Prints a range of elements of a Lisp vector.
|
||||
xvector-elts v n i
|
||||
prints `i' elements of the vector `v' ending at the index `n'.
|
||||
end
|
||||
define xvector-elts
|
||||
set $i = 0
|
||||
p $arg0
|
||||
xvector
|
||||
set $foo = $
|
||||
while $i < $arg2
|
||||
p $foo->contents[$arg1-($i++)]
|
||||
pr
|
||||
end
|
||||
document xvector-elts
|
||||
Prints a range of elements of a Lisp vector.
|
||||
xvector-elts v n i
|
||||
prints `i' elements of the vector `v' ending at the index `n'.
|
||||
end
|
||||
|
||||
** Getting Lisp-level backtrace information within GDB
|
||||
|
||||
|
@ -259,7 +278,53 @@ and, assuming that "xtype" says that args[0] is a symbol:
|
|||
|
||||
xsymbol
|
||||
|
||||
** Debugging Emacs Redisplay problems
|
||||
** Debugging Emacs redisplay problems
|
||||
|
||||
If you configured Emacs with --enable-checking='glyphs', you can use redisplay
|
||||
tracing facilities from a running Emacs session.
|
||||
|
||||
The command "M-x trace-redisplay RET" will produce a trace of what redisplay
|
||||
does on the standard error stream. This is very useful for understanding the
|
||||
code paths taken by the display engine under various conditions, especially if
|
||||
some redisplay optimizations produce wrong results. (You know that redisplay
|
||||
optimizations might be involved if "M-x redraw-display RET", or even just
|
||||
typing "M-x", causes Emacs to correct the bad display.) Since the cursor
|
||||
blinking feature triggers periodic redisplay cycles, we recommend disabling
|
||||
`blink-cursor-mode' before invoking `trace-redisplay', so that you have less
|
||||
clutter in the trace. You can also have up to 30 last trace messages dumped to
|
||||
standard error by invoking the `dump-redisplay-history' command.
|
||||
|
||||
To find the code paths which were taken by the display engine, search xdisp.c
|
||||
for the trace messages you see.
|
||||
|
||||
The command `dump-glyph-matrix' is useful for producing on standard error
|
||||
stream a full dump of the selected window's glyph matrix. See the function's
|
||||
doc string for more details. If you are debugging redisplay issues in
|
||||
text-mode frames, you may find the command `dump-frame-glyph-matrix' useful.
|
||||
|
||||
Other commands useful for debugging redisplay are `dump-glyph-row' and
|
||||
`dump-tool-bar-row'.
|
||||
|
||||
If you run Emacs under GDB, you can print the contents of any glyph matrix by
|
||||
just calling that function with the matrix as its argument. For example, the
|
||||
following command will print the contents of the current matrix of the window
|
||||
whose pointer is in `w':
|
||||
|
||||
(gdb) p dump_glyph_matrix (w->current_matrix, 2)
|
||||
|
||||
(The second argument 2 tells dump_glyph_matrix to print the glyphs in
|
||||
a long form.)
|
||||
|
||||
The Emacs display code includes special debugging code, but it is normally
|
||||
disabled. Configuring Emacs with --enable-checking='yes,glyphs' enables it.
|
||||
|
||||
Building Emacs like that activates many assertions which scrutinize
|
||||
display code operation more than Emacs does normally. (To see the
|
||||
code which tests these assertions, look for calls to the `eassert'
|
||||
macros.) Any assertion that is reported to fail should be investigated.
|
||||
|
||||
When you debug display problems running emacs under X, you can use
|
||||
the `ff' command to flush all pending display updates to the screen.
|
||||
|
||||
The src/.gdbinit file defines many useful commands for dumping redisplay
|
||||
related data structures in a terse and user-friendly format:
|
||||
|
@ -273,8 +338,53 @@ related data structures in a terse and user-friendly format:
|
|||
`pgrow' dumps all glyphs in current glyph_row `row'.
|
||||
`pcursor' dumps current output_cursor.
|
||||
|
||||
The above commands also exist in a version with an `x' suffix which
|
||||
takes an object of the relevant type as argument.
|
||||
The above commands also exist in a version with an `x' suffix which takes an
|
||||
object of the relevant type as argument. For example, `pgrowx' dumps all
|
||||
glyphs in its argument, which must be of type `struct glyph_row'.
|
||||
|
||||
Since redisplay is performed by Emacs very frequently, you need to place your
|
||||
breakpoints cleverly to avoid hitting them all the time, when the issue you are
|
||||
debugging did not (yet) happen. Here are some useful techniques for that:
|
||||
|
||||
. Put a breakpoint at `Fredraw_display' before running Emacs. Then do
|
||||
whatever is required to reproduce the bad display, and invoke "M-x
|
||||
redraw-display". The debugger will kick in, and you can set or enable
|
||||
breakpoints in strategic places, knowing that the bad display will be
|
||||
redrawn from scratch.
|
||||
|
||||
. For debugging incorrect cursor position, a good place to put a breakpoint is
|
||||
in `set_cursor_from_row'. The first time this function is called as part of
|
||||
`redraw-display', Emacs is redrawing the minibuffer window, which is usually
|
||||
not what you want; type "continue" to get to the call you want. In general,
|
||||
always make sure `set_cursor_from_row' is called for the right window and
|
||||
buffer by examining the value of w->contents: it should be the buffer whose
|
||||
display you are debugging.
|
||||
|
||||
. `set_cursor_from_row' is also a good place to look at the contents of a
|
||||
screen line (a.k.a. "glyph row"), by means of the `pgrow' GDB command. Of
|
||||
course, you need first to make sure the cursor is on the screen line which
|
||||
you want to investigate. If you have set a breakpoint in `Fredraw_display',
|
||||
as advised above, move cursor to that line before invoking `redraw-display'.
|
||||
|
||||
. If the problem happens only at some specific buffer position or for some
|
||||
specific rarely-used character, you can make your breakpoints conditional on
|
||||
those values. The display engine maintains the buffer and string position
|
||||
it is processing in the it->current member; for example, the buffer
|
||||
character position is in it->current.pos.charpos. Most redisplay functions
|
||||
accept a pointer to a 'struct it' object as their argument, so you can make
|
||||
conditional breakpoints in those functions, like this:
|
||||
|
||||
(gdb) break x_produce_glyphs if it->current.pos.charpos == 1234
|
||||
|
||||
For conditioning on the character being displayed, use it->c or
|
||||
it->char_to_display.
|
||||
|
||||
. You can also make the breakpoints conditional on what object is being used
|
||||
for producing glyphs for display. The it->method member has the value
|
||||
GET_FROM_BUFFER for displaying buffer contents, GET_FROM_STRING for
|
||||
displaying a Lisp string (e.g., a `display' property or an overlay string),
|
||||
GET_FROM_IMAGE for displaying an image, etc. See `enum it_method' in
|
||||
dispextern.h for the full list of values.
|
||||
|
||||
** Following longjmp call.
|
||||
|
||||
|
@ -304,18 +414,18 @@ features available just for debugging Emacs:
|
|||
|
||||
** Debugging what happens while preloading and dumping Emacs
|
||||
|
||||
Type `gdb temacs' and start it with `r -batch -l loadup dump'.
|
||||
Debugging `temacs' is useful when you want to establish whether a
|
||||
problem happens in an undumped Emacs. To run `temacs' under a
|
||||
debugger, type "gdb temacs", then start it with `r -batch -l loadup'.
|
||||
|
||||
If you need to debug what happens during dumping, start it with `r -batch -l
|
||||
loadup dump' instead. For debugging the bootstrap dumping, use "loadup
|
||||
bootstrap" instead of "loadup dump".
|
||||
|
||||
If temacs actually succeeds when running under GDB in this way, do not
|
||||
try to run the dumped Emacs, because it was dumped with the GDB
|
||||
breakpoints in it.
|
||||
|
||||
** Debugging `temacs'
|
||||
|
||||
Debugging `temacs' is useful when you want to establish whether a
|
||||
problem happens in an undumped Emacs. To run `temacs' under a
|
||||
debugger, type "gdb temacs", then start it with `r -batch -l loadup'.
|
||||
|
||||
** If you encounter X protocol errors
|
||||
|
||||
The X server normally reports protocol errors asynchronously,
|
||||
|
@ -469,8 +579,7 @@ Then, if Emacs becomes hopelessly wedged, you can create another
|
|||
window to do kill -9 in. kill -ILL is often useful too, since that
|
||||
may make Emacs dump core or return to adb.
|
||||
|
||||
|
||||
** Debugging incorrect screen updating.
|
||||
** Debugging incorrect screen updating on a text terminal.
|
||||
|
||||
To debug Emacs problems that update the screen wrong, it is useful
|
||||
to have a record of what input you typed and what Emacs sent to the
|
||||
|
@ -494,40 +603,6 @@ evaluate `(setq inverse-video t)' before you try the operation you think
|
|||
will cause too much redrawing. This doesn't refresh the screen, so only
|
||||
newly drawn text is in inverse video.
|
||||
|
||||
The Emacs display code includes special debugging code, but it is
|
||||
normally disabled. You can enable it by building Emacs with the
|
||||
pre-processing symbol GLYPH_DEBUG defined. Here's one easy way,
|
||||
suitable for Unix and GNU systems, to build such a debugging version:
|
||||
|
||||
MYCPPFLAGS='-DGLYPH_DEBUG=1' make
|
||||
|
||||
Building Emacs like that activates many assertions which scrutinize
|
||||
display code operation more than Emacs does normally. (To see the
|
||||
code which tests these assertions, look for calls to the `xassert'
|
||||
macros.) Any assertion that is reported to fail should be investigated.
|
||||
|
||||
Building with GLYPH_DEBUG defined also defines several helper
|
||||
functions which can help debugging display code. One such function is
|
||||
`dump_glyph_matrix'. If you run Emacs under GDB, you can print the
|
||||
contents of any glyph matrix by just calling that function with the
|
||||
matrix as its argument. For example, the following command will print
|
||||
the contents of the current matrix of the window whose pointer is in `w':
|
||||
|
||||
(gdb) p dump_glyph_matrix (w->current_matrix, 2)
|
||||
|
||||
(The second argument 2 tells dump_glyph_matrix to print the glyphs in
|
||||
a long form.) You can dump the selected window's current glyph matrix
|
||||
interactively with "M-x dump-glyph-matrix RET"; see the documentation
|
||||
of this function for more details.
|
||||
|
||||
Several more functions for debugging display code are available in
|
||||
Emacs compiled with GLYPH_DEBUG defined; type "C-h f dump- TAB" and
|
||||
"C-h f trace- TAB" to see the full list.
|
||||
|
||||
When you debug display problems running emacs under X, you can use
|
||||
the `ff' command to flush all pending display updates to the screen.
|
||||
|
||||
|
||||
** Debugging LessTif
|
||||
|
||||
If you encounter bugs whereby Emacs built with LessTif grabs all mouse
|
||||
|
@ -550,7 +625,6 @@ You can arrange for GDB to run on one machine, with the Emacs display
|
|||
appearing on another. Then, when the bug happens, you can go back to
|
||||
the machine where you started GDB and use the debugger from there.
|
||||
|
||||
|
||||
** Debugging problems which happen in GC
|
||||
|
||||
The array `last_marked' (defined on alloc.c) can be used to display up
|
||||
|
@ -629,6 +703,12 @@ directed to the xterm window you opened above.
|
|||
Similar arrangement is possible on a character terminal by using the
|
||||
`screen' package.
|
||||
|
||||
On MS-Windows, you can start Emacs in its own separate terminal by
|
||||
setting the new-console option before running Emacs under GDB:
|
||||
|
||||
(gdb) set new-console 1
|
||||
(gdb) run
|
||||
|
||||
** Running Emacs built with malloc debugging packages
|
||||
|
||||
If Emacs exhibits bugs that seem to be related to use of memory
|
||||
|
|
Loading…
Add table
Reference in a new issue