Subject: 26.2; Segfault when setting font-backend frame parameter from Xft to X on the initial frame

From: Alex Gramiak <[email-masked]>
Date: Sun, 19 May 2019 15:25:16 -0600

Recipe:

0. Use an Xft build of Emacs.
1. emacs -Q
2. (set-frame-parameter nil 'font-backend '(x))
3. Segfault.

This happens for me on both 26.2 and master.

The crash only occurs on the initial frame; attempting this on other
frames just results in the following error:

  (error "Font ‘-ADBO-Source Code Pro-normal-normal-normal-*-13-*-*-*-m-0-iso10646-1’ is not defined")

It should be noted that the other frames do otherwise switch to the
Xfont backend.

This also occurs with the following fonts:
‘-PfEd-DejaVu Sans Mono-normal-normal-normal-*-15-*-*-*-m-0-iso10646-1’
‘-GOOG-Noto Sans Mono-normal-normal-normal-*-16-*-*-*-*-0-iso10646-1

Here's the xbacktrace:

(gdb) xbacktrace 
"message" (0xffffb6f8)
"debug" (0xffffbe48)
"modify-frame-parameters" (0xffffc588)
"set-frame-parameter" (0xffffc970)
"progn" (0xffffcb68)
"eval" (0xffffce20)
"elisp--eval-last-sexp" (0xffffd2a8)
"eval-last-sexp" (0xffffd850)
"funcall-interactively" (0xffffd848)
"call-interactively" (0xffffdbe0)
"command-execute" (0xffffe0e8)

Below is a bt showing that xftfont_info->xftfont is NULL in
xftfont_text_extents, which seems to be the culprit.

gui_set_font_backend sets the font-backend of the frame to '(x) and
calls gui_set_font, which triggers the error above. For some reason,
only non-initial frames handle the error semi-correctly.

The solution is likely to unwind_protect around gui_set_font in
gui_set_font_backend and reset Qfont_backend if an error occurs. It
might help for the future to figure out the exact issue here, though.

(gdb) sel 1
(gdb) p xftfont_info->display 
$1 = (Display *) 0x555555d78c30
(gdb) p xftfont_info->xftfont 
$2 = (XftFont *) 0x0
(gdb) bt
#0  0x00007ffff6b5a160 in XftCharIndex () at /usr/lib/libXft.so.2
#1  0x000055555583cd8d in xftfont_encode_char (font=0x555556019290, c=92) at xftfont.c:532
#2  0x00005555555fdf98 in get_char_glyph_code (c=92, font=0x555556019290, char2b=0x7fffffff8a8e) at xdisp.c:26097
#3  0x0000555555607a29 in gui_produce_glyphs (it=0x7fffffff8c20) at xdisp.c:28475
#4  0x000055555560657e in produce_special_glyphs (it=0x7fffffffa020, what=IT_CONTINUATION) at xdisp.c:28106
#5  0x00005555555ba649 in init_iterator (it=0x7fffffffa020, w=0x555555ff5a20, charpos=1, bytepos=1, row=0x0, base_face_id=DEFAULT_FACE_ID) at xdisp.c:2958
#6  0x00005555555d3865 in resize_mini_window (w=0x555555ff5a20, exact_p=false) at xdisp.c:11323
#7  0x00005555555d330a in display_echo_area_1 (a1=93825003379232, a2=0x0) at xdisp.c:11211
#8  0x00005555555d2a46 in with_echo_area_buffer (w=0x555555ff5a20, which=0, fn=0x5555555d32d4 <display_echo_area_1>, a1=93825003379232, a2=0x0) at xdisp.c:10981
#9  0x00005555555d327d in display_echo_area (w=0x555555ff5a20) at xdisp.c:11177
#10 0x00005555555d44f3 in echo_area_display (update_frame_p=true) at xdisp.c:11664
#11 0x00005555555d1f18 in message3_nolog (m=0x5555565b0e34) at xdisp.c:10683
#12 0x00005555555d1c4e in message3 (m=0x5555565b0e34) at xdisp.c:10612
#13 0x0000555555794de7 in Fmessage (nargs=1, args=0x7fffffffb6f8) at editfns.c:2891
#14 0x00005555557a284d in funcall_subr (subr=0x555555c1aae0 <Smessage>, numargs=1, args=0x7fffffffb6f8) at eval.c:2856
#15 0x00005555557a2509 in Ffuncall (nargs=2, args=0x7fffffffb6f0) at eval.c:2803
#16 0x00005555557ee00a in exec_byte_code (bytestr=0x5555565b0d74, vector=0x5555564c7c25, maxdepth=0xa6, args_template=0x202, nargs=2, args=0x7fffffffbe48) at bytecode.c:633
#17 0x00005555557a2fb3 in funcall_lambda (fun=0x5555565bdb05, nargs=2, arg_vector=0x7fffffffbe48) at eval.c:2998
#18 0x00005555557a254d in Ffuncall (nargs=3, args=0x7fffffffbe40) at eval.c:2805
#19 0x00005555557a177c in Fapply (nargs=2, args=0x7fffffffbef0) at eval.c:2425
#20 0x00005555557a1d2f in apply1 (fn=0x49b0, arg=0x555555d60de3) at eval.c:2641
#21 0x000055555579cba7 in call_debugger (arg=0x555555d60de3) at eval.c:340
#22 0x000055555579fa2a in maybe_call_debugger (conditions=0x7ffff0fc06cb, sig=0x56d0, data=0x555555d60e53) at eval.c:1827
#23 0x000055555579f4fb in signal_or_quit (error_symbol=0x56d0, data=0x555555d60e53, keyboard_quit=false) at eval.c:1663
#24 0x000055555579f199 in Fsignal (error_symbol=0x56d0, data=0x555555d60e53) at eval.c:1565
#25 0x00005555556e397e in xsignal (error_symbol=0x56d0, data=0x555555d60e53) at lisp.h:4083
#26 0x000055555579f684 in xsignal1 (error_symbol=0x56d0, arg=0x55555657f574) at eval.c:1704
#27 0x000055555579fc3d in verror (m=0x555555871dd9 "Font `%s' is not defined", ap=0x7fffffffc0f0) at eval.c:1884
#28 0x000055555579fcee in error (m=0x555555871dd9 "Font `%s' is not defined") at eval.c:1896
#29 0x00005555555abad2 in gui_set_font (f=0x555555ff5570, arg=0x555555ff6854, oldval=0x0) at frame.c:4390
#30 0x00005555555ac0a5 in gui_set_font_backend (f=0x555555ff5570, new_value=0x555555d61033, old_value=0x555556051983) at frame.c:4524
#31 0x00005555555aa497 in gui_set_frame_parameters (f=0x555555ff5570, alist=0x0) at frame.c:4044
#32 0x00005555555a8a25 in Fmodify_frame_parameters (frame=0x555555ff5575, alist=0x555555d61043) at frame.c:3271
#33 0x00005555557a296c in funcall_subr (subr=0x555555c0dde0 <Smodify_frame_parameters>, numargs=2, args=0x7fffffffc588) at eval.c:2878
#34 0x00005555557a2509 in Ffuncall (nargs=3, args=0x7fffffffc580) at eval.c:2803
#35 0x00005555557ee00a in exec_byte_code (bytestr=0x7ffff0f570c4, vector=0x7ffff0f57065, maxdepth=0x1e, args_template=0xc0e, nargs=3, args=0x7fffffffc988) at bytecode.c:633
#36 0x00005555557a2fb3 in funcall_lambda (fun=0x7ffff0f57035, nargs=3, arg_vector=0x7fffffffc970) at eval.c:2998
#37 0x00005555557a2d17 in apply_lambda (fun=0x7ffff0f57035, args=0x555555d61153, count=15) at eval.c:2935
#38 0x00005555557a1088 in eval_sub (form=0x555555d61173) at eval.c:2319
#39 0x000055555579ce96 in Fprogn (body=0x0) at eval.c:463
#40 0x00005555557a0ab5 in eval_sub (form=0x555555d610c3) at eval.c:2227
#41 0x00005555557a04cc in Feval (form=0x555555d610c3, lexical=0xc8d0) at eval.c:2103
#42 0x00005555557a296c in funcall_subr (subr=0x555555c1b520 <Seval>, numargs=2, args=0x7fffffffce20) at eval.c:2878
#43 0x00005555557a2509 in Ffuncall (nargs=3, args=0x7fffffffce18) at eval.c:2803
#44 0x00005555557ee00a in exec_byte_code (bytestr=0x7ffff11034dc, vector=0x7ffff1102c3d, maxdepth=0x42, args_template=0x406, nargs=1, args=0x7fffffffd2b0) at bytecode.c:633
#45 0x00005555557a2fb3 in funcall_lambda (fun=0x7ffff1102c0d, nargs=1, arg_vector=0x7fffffffd2a8) at eval.c:2998
#46 0x00005555557a254d in Ffuncall (nargs=2, args=0x7fffffffd2a0) at eval.c:2805
#47 0x00005555557ee00a in exec_byte_code (bytestr=0x7ffff110362c, vector=0x7ffff1102bb5, maxdepth=0x12, args_template=0x406, nargs=1, args=0x7fffffffd858) at bytecode.c:633
#48 0x00005555557a2fb3 in funcall_lambda (fun=0x7ffff1102b7d, nargs=1, arg_vector=0x7fffffffd850) at eval.c:2998
#49 0x00005555557a254d in Ffuncall (nargs=2, args=0x7fffffffd848) at eval.c:2805
#50 0x0000555555799d44 in Ffuncall_interactively (nargs=2, args=0x7fffffffd848) at callint.c:253
#51 0x00005555557a284d in funcall_subr (subr=0x555555c1ad60 <Sfuncall_interactively>, numargs=2, args=0x7fffffffd848) at eval.c:2856
#52 0x00005555557a2509 in Ffuncall (nargs=3, args=0x7fffffffd840) at eval.c:2803
#53 0x000055555579c24d in Fcall_interactively (function=0x2aaa9b471a08, record_flag=0x0, keys=0x7ffff14c94bd) at callint.c:781
#54 0x00005555557a299e in funcall_subr (subr=0x555555c1ada0 <Scall_interactively>, numargs=3, args=0x7fffffffdbe0) at eval.c:2881
#55 0x00005555557a2509 in Ffuncall (nargs=4, args=0x7fffffffdbd8) at eval.c:2803
#56 0x00005555557ee00a in exec_byte_code (bytestr=0x7ffff105bd84, vector=0x7ffff105b915, maxdepth=0x36, args_template=0x1006, nargs=1, args=0x7fffffffe0f0) at bytecode.c:633
#57 0x00005555557a2fb3 in funcall_lambda (fun=0x7ffff105b8e5, nargs=1, arg_vector=0x7fffffffe0e8) at eval.c:2998
#58 0x00005555557a254d in Ffuncall (nargs=2, args=0x7fffffffe0e0) at eval.c:2805
#59 0x00005555557a1da4 in call1 (fn=0x41a0, arg1=0x2aaa9b471a08) at eval.c:2656
#60 0x00005555556ebd2b in command_loop_1 () at keyboard.c:1461
#61 0x000055555579ec15 in internal_condition_case (bfun=0x5555556eb4ff <command_loop_1>, handlers=0x56d0, hfun=0x5555556eacb4 <cmd_error>) at eval.c:1352