Subject: Re: bug#59147: 29.0.50; dispnew.c:1456: Emacs fatal error: assertion failed: row >= 0 && row < matrix->nrows

From: Gregor Zattler <[email-masked]>
Date: Wed, 09 Nov 2022 15:35:01 +0100

Hi Eli,
* Eli Zaretskii <[email-masked]> [2022-11-09; 16:06 +02]:
>> From: Gregor Zattler <[email-masked]>
>> Cc: [email-masked], [email-masked]
>> Date: Wed, 09 Nov 2022 14:49:15 +0100
>>
>> > What does the below produce:
>> >
>> >   (gdb) frame 2
>> >   (gdb) p matrix->nrows
>>
>> (gdb) frame 2
>> #2  0x000055555559d310 in matrix_row (matrix=0x55555d44d470, row=8) at dispnew.c:1456
>> 1456      eassert (row >= 0 && row < matrix->nrows);
>> (gdb) p matrix->nrows
>> $1 = 7
>> (gdb)
>
> Can you describe what does notmuch-jump do and maybe show its code?

notmuch-emacs is a xapian based mail client.  It's possible
to configure saved searches accompanied with keys to select
them froma menu notmuch-jump presents in the minibuffer.
This is it's code:

(defun notmuch-jump (action-map prompt)
  "Interactively prompt for one of the keys in ACTION-MAP.

Displays a summary of all bindings in ACTION-MAP in the
minibuffer, reads a key from the minibuffer, and performs the
corresponding action.  The prompt can be canceled with C-g or
RET.  PROMPT must be a string to use for the prompt.  PROMPT
should include a space at the end.

ACTION-MAP must be a list of triples of the form
  (KEY LABEL ACTION)
where KEY is a key binding, LABEL is a string label to display in
the buffer, and ACTION is a nullary function to call.  LABEL may
be null, in which case the action will still be bound, but will
not appear in the pop-up buffer."
  (let* ((items (notmuch-jump--format-actions action-map))
	 ;; Format the table of bindings and the full prompt
	 (table
	  (with-temp-buffer
	    (notmuch-jump--insert-items (window-body-width) items)
	    (buffer-string)))
	 (full-prompt
	  (concat table "\n\n"
		  (propertize prompt 'face 'minibuffer-prompt)))
	 ;; By default, the minibuffer applies the minibuffer face to
	 ;; the entire prompt.  However, we want to clearly
	 ;; distinguish bindings (which we put in the prompt face
	 ;; ourselves) from their labels, so disable the minibuffer's
	 ;; own re-face-ing.
	 (minibuffer-prompt-properties
	  (notmuch-plist-delete
	   (copy-sequence minibuffer-prompt-properties)
	   'face))
	 ;; Build the keymap with our bindings
	 (minibuffer-map (notmuch-jump--make-keymap action-map prompt))
	 ;; The bindings save the the action in notmuch-jump--action
	 (notmuch-jump--action nil))
    ;; Read the action
    (read-from-minibuffer full-prompt nil minibuffer-map)
    ;; If we got an action, do it
    (when notmuch-jump--action
      (funcall notmuch-jump--action))))

> The backtrace seems to indicate that it reads from the minibuffer, but
> in that case, does it mean the mini-window was 7-lines high in this
> case?

quite possible, I have quite a few saved searches which are
presented to me.  The hight of the minibuffer also depends
on the frames width.  If the frame is half of the width of
my monitor the choices are listed in 6 lines, then there is
a blan line and a final line with a prompt.  In fullscreen
it's 3 lines of choices, the blank line and the prompt.

> Also, can you describe what you do to trigger this assertion
> violation?

I can do so only on the level of user interaction: I call
notmuch-jump-search via it's key binding which is key chord
prefixed.  Then I enter one or more chars to select the
specific saved search I want to perform.  It might be
possible that I'm typing faster than Emacs performs this
commands.  Emacs hits the assertion with the choices still
visible.  I cannot say if it does so after my last key
stroke or in the middel of them.

Thanks for looking into this, Gregor