Subject: Re: bug#21394: 25.0.50; Segfault when displaying unprintable character in echo area while frames are being created

From: Pip Cet <[email-masked]>
Date: Wed, 2 Sep 2015 16:08:08 +0000

On Wed, Sep 2, 2015 at 3:16 PM, Eli Zaretskii <[email-masked]> wrote:

> > This patch appears, so far, to run without a segfault
>

No segfault overnight.

> Can you please verify that when the (unmodified) code does segfault,
> the offending face ID is indeed stored in
> last_escape_glyph_merged_face_id?  I'd like to be sure we have really
> found the source of that face ID.
>

It is, indeed, and last_escape_glyph_frame also equals it->f.

Revised patch attached.
From a245722563c5b904313f2f0fe9ca187f6daacae2 Mon Sep 17 00:00:00 2001
From: Philip <[email-masked]>
Date: Wed, 2 Sep 2015 15:58:16 +0000
Subject: [PATCH] Forget cached face ids when displaying echo area messages
 (Bug#21394)

	* xdisp.c (uncache_faces): New function.
	(display_echo_area_1): Call `uncache_faces'.
	(redisplay_internal): Call `uncache_faces'.
---
 src/xdisp.c | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/src/xdisp.c b/src/xdisp.c
index 9ff9f6c..c68c7e1 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -6787,6 +6787,15 @@ merge_glyphless_glyph_face (struct it *it)
   return face_id;
 }
 
+static void
+uncache_faces (void)
+{
+  last_escape_glyph_frame = NULL;
+  last_escape_glyph_face_id = (1 << FACE_ID_BITS);
+  last_glyphless_glyph_frame = NULL;
+  last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
+}
+
 /* Load IT's display element fields with information about the next
    display element from the current position of IT.  Value is false if
    end of buffer (or C string) is reached.  */
@@ -10676,7 +10685,11 @@ display_echo_area_1 (ptrdiff_t a1, Lisp_Object a2)
   /* Do this before displaying, so that we have a large enough glyph
      matrix for the display.  If we can't get enough space for the
      whole text, display the last N lines.  That works by setting w->start.  */
-  bool window_height_changed_p = resize_mini_window (w, false);
+  bool window_height_changed_p;
+
+  uncache_faces ();
+
+  window_height_changed_p = resize_mini_window (w, false);
 
   /* Use the starting position chosen by resize_mini_window.  */
   SET_TEXT_POS_FROM_MARKER (start, w->start);
@@ -13326,10 +13339,7 @@ redisplay_internal (void)
   sw = w;
 
   pending = false;
-  last_escape_glyph_frame = NULL;
-  last_escape_glyph_face_id = (1 << FACE_ID_BITS);
-  last_glyphless_glyph_frame = NULL;
-  last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
+  uncache_faces ();
 
   /* If face_change, init_iterator will free all realized faces, which
      includes the faces referenced from current matrices.  So, we
-- 
2.5.1