mirror of
https://github.com/masscollaborationlabs/emacs.git
synced 2025-07-04 03:13:24 +00:00
; * etc/DEBUG: Improve the redisplay section.
This commit is contained in:
parent
e110312ad9
commit
ba924be452
1 changed files with 55 additions and 36 deletions
91
etc/DEBUG
91
etc/DEBUG
|
@ -472,6 +472,16 @@ and, assuming that "xtype" says that args[0] is a symbol:
|
||||||
|
|
||||||
** Debugging Emacs redisplay problems
|
** Debugging Emacs redisplay problems
|
||||||
|
|
||||||
|
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. Redisplay problems that cause
|
||||||
|
aborts or segfaults in production builds of Emacs will many times be caught by
|
||||||
|
these assertions before they cause a crash.
|
||||||
|
|
||||||
If you configured Emacs with --enable-checking='glyphs', you can use redisplay
|
If you configured Emacs with --enable-checking='glyphs', you can use redisplay
|
||||||
tracing facilities from a running Emacs session.
|
tracing facilities from a running Emacs session.
|
||||||
|
|
||||||
|
@ -481,21 +491,18 @@ code paths taken by the display engine under various conditions, especially if
|
||||||
some redisplay optimizations produce wrong results. (You know that redisplay
|
some redisplay optimizations produce wrong results. (You know that redisplay
|
||||||
optimizations might be involved if "M-x redraw-display RET", or even just
|
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
|
typing "M-x", causes Emacs to correct the bad display.) Since the cursor
|
||||||
blinking feature triggers periodic redisplay cycles, we recommend disabling
|
blinking feature and ElDoc trigger periodic redisplay cycles, we recommend
|
||||||
'blink-cursor-mode' before invoking 'trace-redisplay', so that you have less
|
disabling 'blink-cursor-mode' and 'global-eldoc-mode' before invoking
|
||||||
clutter in the trace. You can also have up to 30 last trace messages dumped to
|
'trace-redisplay', so that you have less clutter in the trace. You can also
|
||||||
standard error by invoking the 'dump-redisplay-history' command.
|
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
|
To find the code paths which were taken by the display engine, search xdisp.c
|
||||||
for the trace messages you see.
|
for the trace messages you see.
|
||||||
|
|
||||||
The command 'dump-glyph-matrix' is useful for producing on standard error
|
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
|
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
|
doc string for more details.
|
||||||
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
|
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
|
just calling that function with the matrix as its argument. For example, the
|
||||||
|
@ -507,13 +514,11 @@ whose pointer is in 'w':
|
||||||
(The second argument 2 tells dump_glyph_matrix to print the glyphs in
|
(The second argument 2 tells dump_glyph_matrix to print the glyphs in
|
||||||
a long form.)
|
a long form.)
|
||||||
|
|
||||||
The Emacs display code includes special debugging code, but it is normally
|
If you are debugging redisplay issues in text-mode frames, you may find the
|
||||||
disabled. Configuring Emacs with --enable-checking='yes,glyphs' enables it.
|
command 'dump-frame-glyph-matrix' useful.
|
||||||
|
|
||||||
Building Emacs like that activates many assertions which scrutinize
|
Other commands useful for debugging redisplay are 'dump-glyph-row' and
|
||||||
display code operation more than Emacs does normally. (To see the
|
'dump-tool-bar-row'.
|
||||||
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
|
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 'ff' command to flush all pending display updates to the screen.
|
||||||
|
@ -535,36 +540,40 @@ object of the relevant type as argument. For example, 'pgrowx' dumps all
|
||||||
glyphs in its argument, which must be of type 'struct glyph_row'.
|
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
|
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
|
breakpoints cleverly to avoid hitting them all the time, when the issue you
|
||||||
debugging did not (yet) happen. Here are some useful techniques for that:
|
are debugging did not (yet) happen. Here are some useful techniques for that:
|
||||||
|
|
||||||
. Put a breakpoint at 'Fredraw_display' before running Emacs. Then do
|
. Put a breakpoint at 'Frecenter' or 'Fredraw_display' before running Emacs.
|
||||||
whatever is required to reproduce the bad display, and invoke "M-x
|
Then do whatever is required to reproduce the bad display, and type C-l or
|
||||||
redraw-display". The debugger will kick in, and you can set or enable
|
"M-x redraw-display" just before invoking the last action that reproduces
|
||||||
breakpoints in strategic places, knowing that the bad display will be
|
the bug. The debugger will kick in, and you can set or enable breakpoints
|
||||||
|
in strategic places, knowing that the bad display will happen soon. With a
|
||||||
|
breakpoint at 'Fredraw_display', you can even reproduce the bug and invoke
|
||||||
|
"M-x redraw-display" afterwards, knowing that the bad display will be
|
||||||
redrawn from scratch.
|
redrawn from scratch.
|
||||||
|
|
||||||
. For debugging incorrect cursor position, a good place to put a breakpoint is
|
. For debugging incorrect cursor position, a good place to put a breakpoint
|
||||||
in 'set_cursor_from_row'. The first time this function is called as part of
|
is in 'set_cursor_from_row'. The first time this function is called as
|
||||||
'redraw-display', Emacs is redrawing the minibuffer window, which is usually
|
part of 'redraw-display', Emacs is redrawing the minibuffer window, which
|
||||||
not what you want; type "continue" to get to the call you want. In general,
|
is usually not what you want; type "continue" to get to the call you want.
|
||||||
always make sure 'set_cursor_from_row' is called for the right window and
|
In general, always make sure 'set_cursor_from_row' is called for the right
|
||||||
buffer by examining the value of w->contents: it should be the buffer whose
|
window and buffer by examining the value of w->contents: it should be the
|
||||||
display you are debugging.
|
buffer whose display you are debugging.
|
||||||
|
|
||||||
. 'set_cursor_from_row' is also a good place to look at the contents of a
|
. '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
|
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
|
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',
|
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'.
|
or 'Frecenter', as advised above, move cursor to that line before invoking
|
||||||
|
these commands.
|
||||||
|
|
||||||
. If the problem happens only at some specific buffer position or for some
|
. If the problem happens only at some specific buffer position or for some
|
||||||
specific rarely-used character, you can make your breakpoints conditional on
|
specific rarely-used character, you can make your breakpoints conditional
|
||||||
those values. The display engine maintains the buffer and string position
|
on those values. The display engine maintains the buffer and string
|
||||||
it is processing in the it->current member; for example, the buffer
|
position it is processing in the it->current member; for example, the
|
||||||
character position is in it->current.pos.charpos. Most redisplay functions
|
buffer character position is in it->current.pos.charpos. Most redisplay
|
||||||
accept a pointer to a 'struct it' object as their argument, so you can make
|
functions accept a pointer to a 'struct it' object as their argument, so
|
||||||
conditional breakpoints in those functions, like this:
|
you can make conditional breakpoints in those functions, like this:
|
||||||
|
|
||||||
(gdb) break x_produce_glyphs if it->current.pos.charpos == 1234
|
(gdb) break x_produce_glyphs if it->current.pos.charpos == 1234
|
||||||
|
|
||||||
|
@ -578,6 +587,16 @@ debugging did not (yet) happen. Here are some useful techniques for that:
|
||||||
GET_FROM_IMAGE for displaying an image, etc. See 'enum it_method' in
|
GET_FROM_IMAGE for displaying an image, etc. See 'enum it_method' in
|
||||||
dispextern.h for the full list of values.
|
dispextern.h for the full list of values.
|
||||||
|
|
||||||
|
. When the display engine is processing a 'display' text property or an
|
||||||
|
overlay string, it pushes on the iterator stack the state variables
|
||||||
|
describing its iteration of buffer text, then reinitializes the iterator
|
||||||
|
object for processing the property or overlay. The it->sp ("stack
|
||||||
|
pointer") member, if it is greater than zero, means the iterators stack was
|
||||||
|
pushed at least once. You can therefore condition your breakpoints on the
|
||||||
|
value of it->sp being positive or being of a certain positive value, to
|
||||||
|
debug display problems that happen only with display properties or
|
||||||
|
overlays.
|
||||||
|
|
||||||
** Debugging problems with native-compiled Lisp.
|
** Debugging problems with native-compiled Lisp.
|
||||||
|
|
||||||
When you encounter problems specific to native-compilation of Lisp, we
|
When you encounter problems specific to native-compilation of Lisp, we
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue