Subject: Re: bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)

From: [email-masked]
Date: Sun, 18 Aug 2024 20:53:54 +0800

Thanks for the detailed explanation, thank you. :heart:

Eval Exec

On 8/18/24 8:43 PM, Pip Cet <[email-masked]> wrote:
> <[email-masked]> writes:
> 
> > It's
> > ```
> > Redefine command "xbacktrace"? (y or n) [answered Y; input not from terminal]
> > Redefine command "xprintbytestr"? (y or n) [answered Y; input not from terminal]
> > Redefine command "xwhichsymbols"? (y or n) [answered Y; input not from terminal]
> > Redefine command "hookpost-backtrace"? (y or n) [answered Y; input not from terminal]
> > Redefine command "ff"? (y or n) [answered Y; input not from terminal]
> > DISPLAY = :0
> > TERM = tmux-256color
> > Breakpoint 3 at 0x4736d9: file emacs.c, line 431.
> > Breakpoint 4 at 0x562640: file xterm.c, line 27093.
> > (gdb) frame 9
> > #9  0x00000000006dd64d in fontset_font (fontset=fontset@entry=XIL(0), c=c@entry=127802, face=face@entry=0x13fec610, id=-1) at fontset.c:793
> > 793       rfont_def = fontset_find_font (fontset, c, face, id, 0);
> > (gdb) p *face->ascii_face
> > $1 = {
> >    lface = {XIL(0x8220), XIL(0x28bdef4), XIL(0x28bdf34), XIL(0xe340), make_fixnum(90), XIL(0xe340), XIL(0xe340), XIL(0), XIL(0), XIL(0x4417994), XIL(0x233c9c4), XIL(0), XIL(0), XIL(0), XIL(0x7f9ea6b05d63),
> >      XIL(0x765a8285), XIL(0), XIL(0x2aabee4), XIL(0x13500), XIL(0)},
> >    id = 2,
> >    gc = 0x0,
> >    stipple = 0,
> >    foreground = 4288059542,
> >    background = 4278190080,
> >    underline_color = 0,
> >    overline_color = 0,
> >    strike_through_color = 0,
> >    box_color = 4281545523,
> >    font = 0x1e4370d0,
> >    fontset = 5,
> >    box_vertical_line_width = -1,
> >    box_horizontal_line_width = -1,
> >    underline_pixels_above_descent_line = 0,
> >    box = FACE_SIMPLE_BOX,
> >    underline = FACE_NO_UNDERLINE,
> >    use_box_color_for_shadows_p = true,
> >    overline_p = false,
> >    strike_through_p = false,
> >    foreground_defaulted_p = false,
> >    background_defaulted_p = false,
> >    underline_defaulted_p = false,
> >    overline_color_defaulted_p = false,
> >    strike_through_color_defaulted_p = false,
> >    box_color_defaulted_p = true,
> >    underline_at_descent_line_p = false,
> >    tty_bold_p = false,
> >    tty_italic_p = false,
> >    tty_reverse_p = false,
> >    tty_strike_through_p = false,
> >    colors_copied_bitwise_p = false,
> >    overstrike = false,
> >    hash = 322003229,
> >    next = 0x13fec610,
> >    prev = 0x0,
> >    ascii_face = 0x4d7343a0,
> >    extra = 0x0
> > }
> > (gdb)
> > ```
> 
> Thanks. That has a different fontset, so it looks like a fontset was
> prematurely freed while still being referred to by a face.  I think the
> assumption made in xfaces.c, that it's always safe to free a fontset if
> we're freeing the realized ASCII face, is incorrect.
> 
> I can confirm that we're sometimes leaving a frame's fontset field
> invalid by running this code:
> 
> diff --git a/src/xfaces.c b/src/xfaces.c
> index 684b6ccfac7..34bab822022 100644
> --- a/src/xfaces.c
> +++ b/src/xfaces.c
> @@ -4598,7 +4598,23 @@ free_realized_face (struct frame *f, struct face *face)
>   	{
>   	  /* Free fontset of FACE if it is ASCII face.  */
>   	  if (face->fontset >= 0 && face == face->ascii_face)
> -	    free_face_fontset (f, face);
> +	    {
> +	      struct face_cache *cache = FRAME_FACE_CACHE (f);
> +	      if (cache)
> +		{
> +		  for (int i = 0; i < cache->used; i++)
> +		    {
> +		      struct face *face2 = cache->faces_by_id[i];
> +		      if (face2 != 0 && face2 != face && face2->fontset == face->fontset)
> +			{
> +			  message ("Freeing fontset %d that's still in use!", face->fontset);
> +			  goto dont;
> +			}
> +		    }
> +		}
> +	      free_face_fontset (f, face);
> +	    }
> +	dont:
>   
>   #ifdef HAVE_X_WINDOWS
>   	  /* This function might be called with the frame's display
> 
> However, that's not a fix; it would leak fontsets, and it's slow.
> 
> Will investigate further.
> 
> Thanks
> Pip
> 
>