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

From: Eli Zaretskii <[email-masked]>
Date: Mon, 19 Aug 2024 17:35:31 +0300

> Date: Mon, 19 Aug 2024 13:32:42 +0000
> From: Pip Cet <[email-masked]>
> Cc: [email-masked], [email-masked]
> 
> >> * modify the right frame parameter (such as alpha-background) so that
> >>   the basic faces are re-realized ('free_realized_face' is called for
> >>   them), but 'free_realized_faces' is not.
> >
> > Basic faces are routinely freed and re-realized whenever we start the
> > display iteration, see init_iterator.
> 
> > AFAIR, all you need to do for
> > that is to customize some face -- doing so sets the face_change flag,
> > and init_iterator will then normally free all the faces and realize
> > them again.
> 
> ... which won't trigger the bug, because it calls 'free_realized_faces'.

Not necessarily.  I show below a backtrace which called
realize_basic_faces and triggered the same freeing of the fontset of
the ASCII face.  This was obtained by changing the color of the
default face via Customize.

> I specifically explained why 'free_realized_face' must be called
> directly, not via (or after) 'free_realized_faces', to trigger the bug.

Any caller of realize_face (and only those, AFAICT) will go that path.
Which is why I asked for a backtrace in your case (since I cannot
reproduce it exactly myself).  As I explained in my other message,
there's potentially a much more serious problem here, if indeed you
are right.

> I meant why we need at least two non-ASCII faces to trigger the bug.

Which bug?  I can trigger freeing the fontset of an ASCII face while
its non-ASCII variants are not freed without having 2 ASCII faces, see
the backtrace below.

> Here's a reproducer hibiscus.el which uses buffer text:
> 
> (while t
>   (insert (concat (make-string 1 (floor (random 132000)))))
>   (set-frame-parameter nil 'alpha-background 1.0)
>   (sit-for 1.0))

Thanks, but this doesn't help me because AFAIK alpha-background is not
supported on Windows.

Here's the backtrace I promised:

#0  realize_face (cache=0x7c73288, attrs=0xbfb8d8, former_face_id=0)
    at xfaces.c:6097
#1  0x00df6b33 in realize_default_face (f=0x7c6bad8) at xfaces.c:6010
#2  0x00df5d73 in realize_basic_faces (f=0x7c6bad8) at xfaces.c:5862
#3  0x00def95a in update_face_from_frame_parameter (f=0x7c6bad8,
    param=XIL(0x8940), new_value=XIL(0x8000000010805bb8)) at xfaces.c:3813
#4  0x00fe70bc in w32_set_foreground_color (f=0x7c6bad8,
    arg=XIL(0x8000000010805bb8), oldval=XIL(0x8000000007c6f740))
    at w32fns.c:1215
#5  0x00cc486a in gui_set_frame_parameters_1 (f=0x7c6bad8, alist=XIL(0),
    default_parameter=false) at frame.c:4400
#6  0x00cc57a2 in gui_set_frame_parameters (f=0x7c6bad8,
    alist=XIL(0xc000000000bfbec0)) at frame.c:4560
#7  0x00cc21fe in Fmodify_frame_parameters (frame=XIL(0xa000000007c6bad8),
    alist=XIL(0xc000000000bfbec0)) at frame.c:3549
#8  0x00def80d in Finternal_set_lisp_face_attribute (face=XIL(0x6480),
    attr=XIL(0x1050), value=XIL(0x8000000010805bb8),
    frame=XIL(0xa000000007c6bad8)) at xfaces.c:3782
#9  0x00effe0e in funcall_subr (
    subr=0x1553600 <Sinternal_set_lisp_face_attribute>, numargs=4,
    args=0x9fa94e8) at eval.c:3167
#10 0x00f6d4f5 in exec_byte_code (fun=XIL(0xa0000000094e7eb0),
    args_template=642, nargs=34, args=0xbfc6e8) at bytecode.c:812
#11 0x00f00623 in funcall_lambda (fun=XIL(0xa0000000094e7eb0), nargs=34,
    arg_vector=0xbfc6d8) at eval.c:3252
#12 0x00eff6e9 in funcall_general (fun=XIL(0xa0000000094e7eb0), numargs=34,
    args=0xbfc6d8) at eval.c:3044
#13 0x00effa12 in Ffuncall (nargs=35, args=0xbfc6d0) at eval.c:3093
#14 0x00efeb75 in Fapply (nargs=4, args=0x9fa9460) at eval.c:2765
#15 0x00f001bb in funcall_subr (subr=0x155c180 <Sapply>, numargs=4,
    args=0x9fa9460) at eval.c:3184
#16 0x00f6d4f5 in exec_byte_code (fun=XIL(0xa0000000095c89f0),
    args_template=771, nargs=3, args=0x9fa9420) at bytecode.c:812
#17 0x00f00623 in funcall_lambda (fun=XIL(0xa00000001062d700), nargs=1,
    arg_vector=0xbfcff8) at eval.c:3252
#18 0x00eff6e9 in funcall_general (fun=XIL(0xa00000001062d700), numargs=1,
    args=0xbfcff8) at eval.c:3044
#19 0x00effa12 in Ffuncall (nargs=2, args=0xbfcff0) at eval.c:3093
#20 0x00efe75a in Fapply (nargs=3, args=0xbfcff0) at eval.c:2718
#21 0x00f17ff9 in Fwidget_apply (nargs=2, args=0x9fa92d0) at fns.c:3847
#22 0x00f001bb in funcall_subr (subr=0x155dd00 <Swidget_apply>, numargs=2,
    args=0x9fa92d0) at eval.c:3184
#23 0x00f6d4f5 in exec_byte_code (fun=XIL(0xa00000001069ff18),
    args_template=257, nargs=1, args=0xbfd860) at bytecode.c:812
#24 0x00f00623 in funcall_lambda (fun=XIL(0xa00000001069ff18), nargs=1,
    arg_vector=0xbfd858) at eval.c:3252
#25 0x00eff6e9 in funcall_general (fun=XIL(0xa00000001069ff18), numargs=1,
    args=0xbfd858) at eval.c:3044
#26 0x00effa12 in Ffuncall (nargs=2, args=0xbfd850) at eval.c:3093
#27 0x00f15ac5 in mapcar1 (leni=1, vals=0x0, fn=XIL(0xa00000001069ff18),
    seq=XIL(0xc00000000ef11220)) at fns.c:3346
#28 0x00f16701 in Fmapc (function=XIL(0xa00000001069ff18),
    sequence=XIL(0xc00000000ef11220)) at fns.c:3483
#29 0x00effd5f in funcall_subr (subr=0x155dac0 <Smapc>, numargs=2,
    args=0x9fa9290) at eval.c:3163
#30 0x00f6d4f5 in exec_byte_code (fun=XIL(0xa00000001069feb8),
    args_template=770, nargs=2, args=0x9fa9258) at bytecode.c:812
#31 0x00f00623 in funcall_lambda (fun=XIL(0xa00000001069ff48), nargs=2,
    arg_vector=0xbfe0b8) at eval.c:3252
#32 0x00eff6e9 in funcall_general (fun=XIL(0xa00000001069ff48), numargs=2,
    args=0xbfe0b8) at eval.c:3044
#33 0x00effa12 in Ffuncall (nargs=3, args=0xbfe0b0) at eval.c:3093
#34 0x00efe7a9 in Fapply (nargs=3, args=0xbfe0b0) at eval.c:2722
#35 0x00f17ff9 in Fwidget_apply (nargs=3, args=0x9fa9208) at fns.c:3847
#36 0x00f001bb in funcall_subr (subr=0x155dd00 <Swidget_apply>, numargs=3,
    args=0x9fa9208) at eval.c:3184
#37 0x00f6d4f5 in exec_byte_code (fun=XIL(0xa00000001061b0d0),
    args_template=513, nargs=2, args=0x9fa91c8) at bytecode.c:812
#38 0x00f00623 in funcall_lambda (fun=XIL(0xa0000000106337b0), nargs=1,
    arg_vector=0xbfea50) at eval.c:3252
#39 0x00eff6e9 in funcall_general (fun=XIL(0xa0000000106337b0), numargs=1,
    args=0xbfea50) at eval.c:3044
#40 0x00effa12 in Ffuncall (nargs=2, args=0xbfea48) at eval.c:3093
#41 0x00ef07ca in Ffuncall_interactively (nargs=2, args=0xbfea48)
    at callint.c:250
#42 0x00f001bb in funcall_subr (subr=0x155b840 <Sfuncall_interactively>,
    numargs=2, args=0xbfea48) at eval.c:3184
#43 0x00eff682 in funcall_general (fun=XIL(0xa00000000155b840), numargs=2,
    args=0xbfea48) at eval.c:3040
#44 0x00effa12 in Ffuncall (nargs=3, args=0xbfea40) at eval.c:3093
#45 0x00ef3838 in Fcall_interactively (function=XIL(0x80f0308),
    record_flag=XIL(0), keys=XIL(0xa000000010706cc8)) at callint.c:789
#46 0x00effda7 in funcall_subr (subr=0x155b880 <Scall_interactively>,
    numargs=3, args=0x9fa9078) at eval.c:3165
#47 0x00f6d4f5 in exec_byte_code (fun=XIL(0xa000000009bd6c38),
    args_template=1025, nargs=1, args=0xbff7a0) at bytecode.c:812
#48 0x00f00623 in funcall_lambda (fun=XIL(0xa000000009bd6c38), nargs=1,
    arg_vector=0xbff798) at eval.c:3252
#49 0x00eff6e9 in funcall_general (fun=XIL(0xa000000009bd6c38), numargs=1,
    args=0xbff798) at eval.c:3044
#50 0x00effa12 in Ffuncall (nargs=2, args=0xbff790) at eval.c:3093
#51 0x00e05691 in command_loop_1 () at keyboard.c:1550
#52 0x00efa701 in internal_condition_case (bfun=0xe04aa1 <command_loop_1>,
    handlers=XIL(0x90), hfun=0xe03afa <cmd_error>) at eval.c:1613
#53 0x00e04506 in command_loop_2 (handlers=XIL(0x90)) at keyboard.c:1168
#54 0x00ef9786 in internal_catch (tag=XIL(0x12720),
    func=0xe044cf <command_loop_2>, arg=XIL(0x90)) at eval.c:1292
#55 0x00e04471 in command_loop () at keyboard.c:1146
#56 0x00e0355a in recursive_edit_1 () at keyboard.c:754
#57 0x00e037f8 in Frecursive_edit () at keyboard.c:837
#58 0x00dfe919 in main (argc=2, argv=0x7ce2570) at emacs.c:2635

Lisp Backtrace:
"internal-set-lisp-face-attribute" (0x9fa94e8)
"set-face-attribute" (0xbfc6d8)
"apply" (0x9fa9460)
"face-spec-set-2" (0x9fa9408)
"face-spec-recalc" (0x9fa9398)
"face-spec-set" (0x9fa9328)
"custom-face-set" (0xbfcff8)
"widget-apply" (0x9fa92d0)
0x1069ff18 PVEC_CLOSURE
"mapc" (0x9fa9290)
"custom-command-apply" (0x9fa9248)
"Custom-set" (0xbfe0b8)
"widget-apply" (0x9fa9208)
"widget-apply-action" (0x9fa91b8)
"widget-button--check-and-call-button" (0x9fa9120)
"widget-button-click" (0xbfea50)
"funcall-interactively" (0xbfea48)
"call-interactively" (0x9fa9078)
"command-execute" (0xbff798)

And I wrote a simple GDB script that loops over the cached faces when
free_realized_face is called under conditions that will cause it to
call free_face_fontset, and got this:

  face 0xbcad118(N), fontset 3, ascii 0x10643628
  face 0x1025a7f0(N), fontset 3, ascii 0x10643628
  face 0x101a0f50(N), fontset 3, ascii 0x10643628
  face 0x1016a328(N), fontset 3, ascii 0x10643628
  face 0xc02ed68(N), fontset 3, ascii 0x10643628
  face 0xb9fb020(N), fontset 3, ascii 0x10643628
  face 0xb98fc38(N), fontset 3, ascii 0x10643628
  face 0xb9b1498(N), fontset 3, ascii 0x10643628
  face 0x7c4cd48(N), fontset 3, ascii 0x10643628
  face 0xbcbb350(N), fontset 3, ascii 0x10643628
  face 0x107e5410(N), fontset 3, ascii 0x10643628
  face 0x105ff8e8(N), fontset 3, ascii 0x10643628
  face 0xbcab9f8(N), fontset 3, ascii 0x10643628
  face 0xb9c8cd0(N), fontset 3, ascii 0x10643628
  face 0xb99e470(N), fontset 3, ascii 0x10643628
  face 0xb998d38(N), fontset 3, ascii 0x10643628
  face 0xb97cbd0(N), fontset 3, ascii 0x10643628
  face 0x104ac2b8(N), fontset 3, ascii 0x10643628
  face 0x10167af0(N), fontset 3, ascii 0x10643628
  face 0x10643d30(N), fontset 3, ascii 0x10643628
  face 0x104d0c48(N), fontset 3, ascii 0x10643628
  face 0x107e31b0(N), fontset 3, ascii 0x10643628
  face 0xb949650(N), fontset 3, ascii 0x10643628
  face 0xb949758(N), fontset 3, ascii 0x10643628
  face 0x105403f0(N), fontset 3, ascii 0x10643628
  face 0x105404f8(N), fontset 3, ascii 0x10643628
  face 0x10540600(N), fontset 3, ascii 0x10643628
  face 0x10540708(N), fontset 3, ascii 0x10643628
  face 0x10540810(N), fontset 3, ascii 0x10643628
  face 0x10540918(N), fontset 3, ascii 0x10643628
  face 0x10540a20(N), fontset 3, ascii 0x10643628
  face 0x10540b28(N), fontset 3, ascii 0x10643628
  face 0x104a4fe8(N), fontset 3, ascii 0x10643628
  face 0x104a50f0(N), fontset 3, ascii 0x10643628
  face 0x104a51f8(N), fontset 3, ascii 0x10643628
  face 0x104a5300(N), fontset 3, ascii 0x10643628

The "(N)" part means that this face is not ASCII face (its ASCII
parent is shown by "ascii 0xNNNNN").

Except that in this case the caller sets the frame's 'face_change'
flag, which then frees and all the non-ASCII faces the first time we
call init_iterator.