Subject: bug#50571: 28.0.50; Redisplay segfaults with empty face cache

From: "Basil L. Contovounesios" <[email-masked]>
Date: Sun, 19 Sep 2021 14:57:02 +0100

reopen 50571
quit

Basil L. Contovounesios [2021-09-14 20:45 +0100] wrote:

> Eli Zaretskii [2021-09-14 16:33 +0300] wrote:
>
>>> Date: Tue, 14 Sep 2021 16:03:02 +0300
>>> From: Eli Zaretskii <[email-masked]>
>>> Cc: [email-masked]
>>> 
>>> Thanks, I see the reason now.  It's because we allow to have arbitrary
>>> Lisp to be registered in jit-lock-functions, and then that arbitrary
>>> Lisp is called in the middle of redisplay, and in this case creates a
>>> whole new frame with faces.  As luck would have it, we decide right
>>> there and then perform routine maintenance and release all the faces
>>> on all the frames...
>>> 
>>> I'm thinking about the best solution for this.
>>
>> Does the patch below give good results?
>
> Yes, applying it makes the issue go away, and reverting it reintroduces
> the segfault.  I didn't notice any other issues.  Thanks!

Unfortunately I found another hole that needs plugging, but fortunately
I can reliably reproduce it with the following site-specific steps:

0. emacs
1. C-x p p (project-switch-project)
2. Select a checkout of https://github.com/abo-abo/swiper,
   using Ivy completion.
3. f (project-find-file)
4. ivy.el RET
5. C-s (isearch-forward)
6. C-g
7. M-s s (counsel-grep-or-swiper)
8. #[[:digit:]]

This brings a bug-reference-bug-regexp match onto screen, which again
triggers a frame creation via bug-reference's call to display-warning.

The attached GDB log shows where the relevant frame's face cache is
cleared right before the crash (search for 'New value = 0'), at which
point f->inhibit_clear_image_cache is false.

-- 
Basil