Subject: bug#42943: 28.0.50; Emacsclient crashes in ftcrfont_glyph_extents

From: Eli Zaretskii <[email-masked]>
Date: Sat, 24 Oct 2020 16:10:31 +0300

> From: Robert Pluim <[email-masked]>
> Cc: [email-masked],  [email-masked],  [email-masked]
> Date: Sat, 24 Oct 2020 14:14:53 +0200
> 
>     Eli> I'm guessing that we close the font, but there's still a face that
>     Eli> references that font, and we try using that face for display.  Can you
>     Eli> see if that is the case?  The 'face' member of 'struct glyph_string'
>     Eli> should point to the face, and face->font should point to the font.
> 
> Yes, weʼre using the face thatʼs cached in the glyph_string:

But glyph_strings are not kept between redisplay cycles, AFAIR, they
are recreated anew each time we need to redisplay something.  This
happens in the write_glyphs method that is called from update_window
and update_frame, which eventually calls gui_write_glyphs, which calls
draw_glyphs, which creates the glyph_strings in BUILD_GLYPH_STRINGS.
So it's unclear to me how can a face be cached in a glyph_string.

> Thread 1 "emacs" received signal SIGSEGV, Segmentation fault.
> ftcrfont_glyph_extents (font=0x555556930478, glyph=1036,
>     metrics=metrics@entry=0x0) at ftcrfont.c:81
> 81        if (METRICS_STATUS (cache) == METRICS_INVALID)
> (gdb) up
> #1  0x00005555558453a1 in ftcrfont_draw (s=0x7fffffffb440,
>     from=<optimized out>, to=<optimized out>, x=17, y=<optimized out>,
>     with_background=<optimized out>) at ftcrfont.c:520
> 520           x += (s->padding_p ? 1 : ftcrfont_glyph_extents (s->font,
> (gdb) l 500
> 495       struct face *face = s->face;
> 496       struct font_info *ftcrfont_info = (struct font_info *) s->font;
> 497       cairo_t *cr;
> 498       cairo_glyph_t *glyphs;
> 499       int len = to - from;
> 500       int i;
> 501
> 502       block_input ();
> 503
> 504       cr = x_begin_cr_clip (f, s->gc);
> (gdb) p s->face
> $1 = (struct face *) 0x555556113290
> (gdb) p s->face->font
> $2 = (struct font *) 0x555556930478
> (gdb) p s->font
> $3 = (struct font *) 0x555556930478

And how do you see from the above that it's a pointer to the same
'struct font' that was used by the now-deleted first client frame?

>     Eli> We call font_clear_cache when a frame is deleted, so it's unclear to
>     Eli> me how come the font is still remembered somewhere.
> 
> font_clear_cache closes all the fonts and sets the frame's font cache
> to Qnil, I donʼt see it doing anything with faces.

Faces are cached in the frame's face cache, see xfaces.c.  When a
frame is deleted, its face cache is freed, so its faces should also go
away.  A new frame starts with an empty face cache, and then faces are
added to that cache as they are "realized", starting from the "basic
faces" that are always needed, see realize_basic_faces.  For a
non-ASCII character, we produce a new face based on the default face,
the first time we need to display a character that needs a font we
don't already have; then that face is also added to the frame's face
cache.

>     Eli> And I lack some background here: what is/are the character(s) we try
>     Eli> displaying here, and how that display is triggered by creating a new
>     Eli> frame due to the second emacsclient invocation?
> 
> Itʼs just emacsclient redisplaying *scratch*, I think.

And *scratch* has an Arabic character?  How did that happen? I thought
the recipe was only to turn on the Arabic input method.  Is the
offending character the IM indicator on the mode-line, per chance?

> Are you saying redisplay should not be called here?

No, of course not.  When a new frame is created, it is immediately
displayed.