* bug#42943: 28.0.50; Emacsclient crashes in ftcrfont_glyph_extents
@ 2020-08-20 0:47 Basil L. Contovounesios
2020-08-20 14:28 ` Eli Zaretskii
2020-08-21 14:05 ` Lars Ingebrigtsen
0 siblings, 2 replies; 19+ messages in thread
From: Basil L. Contovounesios @ 2020-08-20 0:47 UTC (permalink / raw)
To: 42943
[-- Attachment #1: Type: text/plain, Size: 352 bytes --]
From the project-root:
0. cd src
1. gdb ./emacs
2. set logging on
3. r -Q --fg-daemon
From the project-root in another shell:
4. ./lib-src/emacsclient -c
5. C-\ arabic RET
6. s ~ A
7. C-x 5 0
8. ./lib-src/emacsclient -c
Back to GDB:
9. bt full
I attach the resulting backtrace.
I then recompiled ftcrfont.c with the following printf sprinkles:
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: printf-debug.diff --]
[-- Type: text/x-diff, Size: 1991 bytes --]
diff --git a/src/ftcrfont.c b/src/ftcrfont.c
index 29813c8d7d..7832d4f5ce 100644
--- b/src/ftcrfont.c
+++ a/src/ftcrfont.c
@@ -52,11 +52,19 @@
row = glyph / METRICS_NCOLS_PER_ROW;
col = glyph % METRICS_NCOLS_PER_ROW;
+ fprintf (stderr, "\nglyph %u row %d col %d nrows %d",
+ glyph, row, col, ftcrfont_info->metrics_nrows);
if (row >= ftcrfont_info->metrics_nrows)
{
+ fprintf (stderr, " realloc %p %zu", ftcrfont_info->metrics,
+ sizeof (struct font_metrics *) * (row + 1));
ftcrfont_info->metrics =
xrealloc (ftcrfont_info->metrics,
sizeof (struct font_metrics *) * (row + 1));
+ fprintf (stderr, " memset %p %zu",
+ ftcrfont_info->metrics + ftcrfont_info->metrics_nrows,
+ (sizeof (struct font_metrics *)
+ * (row + 1 - ftcrfont_info->metrics_nrows)));
memset (ftcrfont_info->metrics + ftcrfont_info->metrics_nrows, 0,
(sizeof (struct font_metrics *)
* (row + 1 - ftcrfont_info->metrics_nrows)));
@@ -68,10 +76,15 @@
int i;
new = xmalloc (sizeof (struct font_metrics) * METRICS_NCOLS_PER_ROW);
+ fprintf (stderr, " malloc %p %zu", new,
+ sizeof (struct font_metrics) * METRICS_NCOLS_PER_ROW);
for (i = 0; i < METRICS_NCOLS_PER_ROW; i++)
METRICS_SET_STATUS (new + i, METRICS_INVALID);
ftcrfont_info->metrics[row] = new;
}
+ fprintf (stderr, " m %p r %p c %p\n", ftcrfont_info->metrics,
+ ftcrfont_info->metrics[row],
+ ftcrfont_info->metrics[row] + col);
cache = ftcrfont_info->metrics[row] + col;
if (METRICS_STATUS (cache) == METRICS_INVALID)
@@ -503,8 +516,10 @@
}
glyphs = alloca (sizeof (cairo_glyph_t) * len);
+ fprintf (stderr, "sz %zu len %d", sizeof (cairo_glyph_t), len);
for (i = 0; i < len; i++)
{
+ fprintf (stderr, " from %d i %d", from, i);
glyphs[i].index = s->char2b[from + i];
glyphs[i].x = x;
glyphs[i].y = y;
[-- Attachment #3: Type: text/plain, Size: 2015 bytes --]
and repeated the recipe. IIRC the segfault didn't happen in step 8 the
first time; I had to repeat steps 7-8 a few times before it did, and
this generated a lot of output. Here are the last few lines:
--8<---------------cut here---------------start------------->8---
glyph 7 row 0 col 7 nrows 1 m 0x5555561a7660 r 0x555556495210 c 0x555556495256
glyph 7 row 0 col 7 nrows 1 m 0x5555561a7660 r 0x555556495210 c 0x555556495256
glyph 63 row 0 col 63 nrows 1 m 0x5555561a7660 r 0x555556495210 c 0x555556495486
sz 24 len 1 from 0 i 0
glyph 3 row 0 col 3 nrows 1 m 0x5555561a7660 r 0x555556495210 c 0x55555649522e
sz 24 len 1 from 0 i 0
glyph 1135 row 8 col 111 nrows 10 m 0x5555562304d0 r 0x2073756c50656d55 c 0x2073756c506571ab
--8<---------------cut here---------------end--------------->8---
IIRC step 8 segfaulted every time after I removed some of the printfs.
Either way, the pattern is always the same: 'glyph' goes from being a
small number to 1135 or 1153, and the address of ftcrfont_info->metrics
changes.
Any ideas?
Thanks,
--
Basil
In GNU Emacs 28.0.50 (build 9, x86_64-pc-linux-gnu, X toolkit, cairo version 1.16.0, Xaw3d scroll bars)
of 2020-08-20 built on tabos
Repository revision: f8d3d18168a742691d095a3f0c83512f19621725
Repository branch: master
Windowing system distributor 'The X.Org Foundation', version 11.0.12008000
System Description: Debian GNU/Linux bullseye/sid
Configured using:
'configure 'CC=ccache gcc' 'CFLAGS=-O0 -g3 -ggdb -gdwarf-4'
--config-cache --prefix=/home/blc/.local --program-suffix=-dbg
--enable-checking=yes,glyphs --enable-check-lisp-object-type
--with-x-toolkit=lucid --with-file-notification=yes --with-x'
Configured features:
XAW3D XPM JPEG TIFF GIF PNG RSVG CAIRO SOUND GPM DBUS GSETTINGS GLIB
NOTIFY INOTIFY ACL LIBSELINUX GNUTLS LIBXML2 FREETYPE HARFBUZZ M17N_FLT
LIBOTF ZLIB TOOLKIT_SCROLL_BARS LUCID X11 XDBE XIM MODULES THREADS
LIBSYSTEMD JSON PDUMPER LCMS2
Important settings:
value of $LANG: en_IE.UTF-8
locale-coding-system: utf-8-unix
[-- Attachment #4: gdb.txt --]
[-- Type: text/plain, Size: 10498 bytes --]
Starting program: /home/blc/.local/src/emacs-dbg/src/emacs -Q --fg-daemon
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7ffff18bf700 (LWP 151164)]
[New Thread 0x7ffff10ad700 (LWP 151217)]
[New Thread 0x7ffff08ac700 (LWP 151218)]
Thread 1 "emacs" received signal SIGSEGV, Segmentation fault.
0x00005555558c001e in ftcrfont_glyph_extents (font=0x5555560ee8d8, glyph=1135, metrics=0x0) at ftcrfont.c:77
77 if (METRICS_STATUS (cache) == METRICS_INVALID)
#0 0x00005555558c001e in ftcrfont_glyph_extents (font=0x5555560ee8d8, glyph=1135, metrics=0x0) at ftcrfont.c:77
ftcrfont_info = 0x5555560ee8d8
row = 8
col = 111
cache = 0x3720a1c
#1 0x00005555558c16d6 in ftcrfont_draw (s=0x7fffffffb400, from=0, to=1, x=11, y=1006, with_background=false)
at ftcrfont.c:511
f = 0x5555560d8570
face = 0x5555561a6860
ftcrfont_info = 0x5555560ee8d8
cr = 0x5555561b5810
glyphs = 0x7fffffffaa20
len = 1
i = 0
#2 0x00005555556dcd4a in x_draw_composite_glyph_string_foreground (s=0x7fffffffb400) at xterm.c:1969
gstring = XIL(0x5555560eea1d)
glyph = XIL(0x555556482de5)
y = 1006
width = 9
i = 1
j = 0
x = 11
font = 0x5555560ee8d8
#3 0x00005555556e08df in x_draw_glyph_string (s=0x7fffffffb400) at xterm.c:3780
relief_drawn_p = true
#4 0x0000555555625aeb in draw_glyphs
(w=0x55555656e2d8, x=956, row=0x5555563112a0, area=TEXT_AREA, start=0, end=106, hl=DRAW_NORMAL_TEXT, overlaps=0)
at xdisp.c:28732
head = 0x7fffffffb6a0
tail = 0x7fffffffade0
s = 0x7fffffffb400
clip_head = 0x0
clip_tail = 0x0
i = 106
j = -1
x_reached = 956
last_x = 955
area_left = 1
f = 0x5555560d8570
sa_avail = 14820
sa_count = 9
#5 0x000055555562cdd0 in gui_write_glyphs
(w=0x55555656e2d8, updated_row=0x5555563112a0, start=0x55555636f700, updated_area=TEXT_AREA, len=106)
at xdisp.c:30750
x = 61
hpos = 0
chpos = 0
#6 0x000055555559dd23 in update_text_area (w=0x55555656e2d8, updated_row=0x5555563112a0, vpos=61) at dispnew.c:3842
current_row = 0x5555563761a0
desired_row = 0x5555563112a0
rif = 0x555555a03200 <x_redisplay_interface>
changed_p = false
#7 0x000055555559e852 in update_window_line (w=0x55555656e2d8, vpos=61, mouse_face_overwritten_p=0x7fffffffbbe7)
at dispnew.c:4085
current_row = 0x5555563761a0
desired_row = 0x5555563112a0
rif = 0x555555a03200 <x_redisplay_interface>
changed_p = false
#8 0x000055555559d0ed in update_window (w=0x55555656e2d8, force_p=true) at dispnew.c:3566
end = 0x5555563112a0
mode_line_row = 0x5555563112a0
header_line_row = 0x0
changed_p = false
mouse_face_overwritten_p = false
row = 0x55555630d5a0
tab_line_row = 0x0
yb = 955
n_updated = 0
desired_matrix = 0x55555656daf0
paused_p = false
preempt_count = 9
rif = 0x555555a03200 <x_redisplay_interface>
#9 0x000055555559c6d6 in update_window_tree (w=0x55555656e2d8, force_p=true) at dispnew.c:3337
paused_p = false
#10 0x000055555559c2bd in update_frame (f=0x5555560d8570, force_p=true, inhibit_hairy_id_p=false) at dispnew.c:3226
paused_p = false
root_window = 0x55555656e2d8
#11 0x00005555555f5564 in redisplay_internal () at xdisp.c:15868
gcscrollbars = true
f_redisplay_flag = true
f = 0x5555560d8570
w = 0x55555656e2d8
sw = 0x55555656e2d8
fr = 0x5555560d8570
pending = false
must_finish = true
match_p = true
tlbufpos = {
charpos = 146,
bytepos = 146
}
tlendpos = {
charpos = 0,
bytepos = 0
}
number_of_visible_frames = 2
count = 6
sf = 0x5555560d8570
polling_stopped_here = true
tail = XIL(0x555555f13a33)
frame = XIL(0x5555560d8575)
hscroll_retries = 0
garbaged_frame_retries = 0
consider_all_windows_p = true
update_miniwindow_p = true
#12 0x00005555555f6056 in redisplay_preserve_echo_area (from_where=12) at xdisp.c:16137
count = 5
#13 0x0000555555870357 in wait_reading_process_output
(time_limit=30, nsecs=0, read_kbd=-1, do_display=true, wait_for_cell=XIL(0), wait_proc=0x0, just_wait_proc=0)
at process.c:5812
nread = 3375
process_skipped = false
channel = 7
nfds = 1
Available = {
fds_bits = {0 <repeats 16 times>}
}
Writeok = {
fds_bits = {0 <repeats 16 times>}
}
check_write = true
check_delay = 0
no_avail = false
xerrno = 11
proc = XIL(0x55555656e51d)
timeout = {
tv_sec = 30,
tv_nsec = 0
}
end_time = {
tv_sec = 1597883621,
tv_nsec = 52427752
}
timer_delay = {
tv_sec = 0,
tv_nsec = -1
}
got_output_end_time = {
tv_sec = 0,
tv_nsec = -1
}
wait = TIMEOUT
got_some_output = 3375
prev_wait_proc_nbytes_read = 0
retry_for_async = false
count = 4
now = {
tv_sec = 0,
tv_nsec = -1
}
#14 0x00005555555a4ac8 in sit_for (timeout=make_fixnum(30), reading=true, display_option=1) at dispnew.c:6049
sec = 30
nsec = 0
do_display = true
#15 0x000055555572c886 in read_char
(commandflag=1, map=XIL(0x555556572ac3), prev_event=XIL(0), used_mouse_menu=0x7fffffffd9ef, end_time=0x0)
at keyboard.c:2738
tem0 = XIL(0x7fffffffd6a0)
timeout = 30
count1 = 3
delay_level = 4
buffer_size = 1
c = XIL(0)
jmpcount = 3
local_getcjmp = {{
__jmpbuf = {0, -4276096293224735316, 93824992491632, 0, 0, 0, -4276096293535113812, -7927157738208125524},
__mask_was_saved = 0,
__saved_mask = {
__val = {93824995017460, 140737488345088, 0, 140737488345168, 93824995064878, 93825009134259, 3, 93825009134243, 93825001707712, 0, 0, 140737488345168, 0, 93825009134259, 0, 140737488345344}
}
}}
save_jump = {{
__jmpbuf = {0, 0, 0, 0, 0, 0, 0, 0},
__mask_was_saved = 0,
__saved_mask = {
__val = {0 <repeats 16 times>}
}
}}
tem = XIL(0x2ffffd6d8)
save = XIL(0x7ffff1c186f8)
previous_echo_area_message = XIL(0)
also_record = XIL(0)
reread = false
recorded = false
polling_stopped_here = false
orig_kboard = 0x555555fa53c0
#16 0x000055555573ed3b in read_key_sequence
(keybuf=0x7fffffffdb80, prompt=XIL(0), dont_downcase_last=false, can_return_switch_frame=true, fix_current_buffer=true, prevent_redisplay=false) at keyboard.c:9547
interrupted_kboard = 0x555555fa53c0
interrupted_frame = 0x555555efeea8
key = XIL(0x7ffff1c186fd)
used_mouse_menu = false
echo_local_start = 0
last_real_key_start = 0
keys_local_start = 0
new_binding = XIL(0x55555589484d)
count = 3
t = 0
echo_start = 0
keys_start = 0
current_binding = XIL(0x555556572ac3)
first_unbound = 31
mock_input = 0
used_mouse_menu_history = {false <repeats 30 times>}
fkey = {
parent = XIL(0x555555f708b3),
map = XIL(0x555555f708b3),
start = 0,
end = 0
}
keytran = {
parent = XIL(0x7ffff22acc43),
map = XIL(0x7ffff22acc43),
start = 0,
end = 0
}
indec = {
parent = XIL(0x555555f708c3),
map = XIL(0x555555f708c3),
start = 0,
end = 0
}
shift_translated = false
delayed_switch_frame = XIL(0)
original_uppercase = XIL(0)
original_uppercase_position = -1
dummyflag = false
starting_buffer = 0x7ffff1c186f8
fake_prefixed_keys = XIL(0)
first_event = XIL(0)
second_event = XIL(0)
#17 0x00005555557282e5 in command_loop_1 () at keyboard.c:1350
cmd = XIL(0x4e60)
keybuf =
{make_fixnum(24), make_fixnum(53), make_fixnum(48), XIL(0x5555557df79c), XIL(0x1f22c1f30), XIL(0x7ffff22c1f30), XIL(0), XIL(0x8250), XIL(0x7fffffffdbf0), XIL(0), XIL(0x555555e5d8c0), XIL(0), XIL(0x7fffffffdc10), XIL(0x5555557fc2a0), make_fixnum(34910567923712), XIL(0), XIL(0x555555e5d8c0), XIL(0), XIL(0x7fffffffdc40), XIL(0x5555557fc2a0), XIL(0), XIL(0x555555e5d8c0), XIL(0), XIL(0), XIL(0x7fffffffdc60), XIL(0x5555557fc2f4), XIL(0x8), XIL(0x8250), XIL(0x7fffffffdca0), make_fixnum(23456248759793)}
i = 3
prev_modiff = 38
prev_buffer = 0x7ffff1c186f8
already_adjusted = false
#18 0x0000555555801286 in internal_condition_case
(bfun=0x555555727e69 <command_loop_1>, handlers=XIL(0x90), hfun=0x555555727480 <cmd_error>) at eval.c:1356
val = XIL(0x5555557245c8)
c = 0x555555f268e0
#19 0x0000555555727a52 in command_loop_2 (ignore=XIL(0)) at keyboard.c:1091
val = XIL(0xd5f0)
#20 0x000055555580073a in internal_catch (tag=XIL(0xd5f0), func=0x555555727a25 <command_loop_2>, arg=XIL(0))
at eval.c:1117
val = XIL(0)
c = 0x555555f10c00
#21 0x00005555557279f1 in command_loop () at keyboard.c:1070
#22 0x0000555555726f69 in recursive_edit_1 () at keyboard.c:714
count = 1
val = XIL(0x7fffffffde10)
#23 0x0000555555727160 in Frecursive_edit () at keyboard.c:786
count = 0
buffer = XIL(0)
#24 0x0000555555723120 in main (argc=3, argv=0x7fffffffe078) at emacs.c:2047
stack_bottom_variable = 0x7ffff5acd720
no_loadup = false
junk = 0x0
dname_arg = 0x0
ch_to_dir = 0x0
original_pwd = 0x0
dump_mode = 0x0
skip_args = 1
temacs = 0x0
attempt_load_pdump = true
rlim = {
rlim_cur = 10022912,
rlim_max = 18446744073709551615
}
lc_all = 0x0
sockfd = -1
module_assertions = false
Lisp Backtrace:
"redisplay_internal (C function)" (0x0)
^ permalink raw reply related [flat|nested] 19+ messages in thread
* bug#42943: 28.0.50; Emacsclient crashes in ftcrfont_glyph_extents
2020-08-20 0:47 bug#42943: 28.0.50; Emacsclient crashes in ftcrfont_glyph_extents Basil L. Contovounesios
@ 2020-08-20 14:28 ` Eli Zaretskii
2020-08-21 14:05 ` Lars Ingebrigtsen
1 sibling, 0 replies; 19+ messages in thread
From: Eli Zaretskii @ 2020-08-20 14:28 UTC (permalink / raw)
To: Basil L. Contovounesios; +Cc: 42943
> From: "Basil L. Contovounesios" <contovob@tcd.ie>
> Date: Thu, 20 Aug 2020 01:47:32 +0100
>
> --8<---------------cut here---------------start------------->8---
> glyph 7 row 0 col 7 nrows 1 m 0x5555561a7660 r 0x555556495210 c 0x555556495256
>
> glyph 7 row 0 col 7 nrows 1 m 0x5555561a7660 r 0x555556495210 c 0x555556495256
>
> glyph 63 row 0 col 63 nrows 1 m 0x5555561a7660 r 0x555556495210 c 0x555556495486
> sz 24 len 1 from 0 i 0
> glyph 3 row 0 col 3 nrows 1 m 0x5555561a7660 r 0x555556495210 c 0x55555649522e
> sz 24 len 1 from 0 i 0
> glyph 1135 row 8 col 111 nrows 10 m 0x5555562304d0 r 0x2073756c50656d55 c 0x2073756c506571ab
> --8<---------------cut here---------------end--------------->8---
Is 0x2073756c506571ab a bogus pointer, i.e. it cannot be dereferenced?
If so, you need to figure out where did it come from. It could have
come from the xmalloc call, but then why the trace around that call
are not shown in your printfs?
And what is sizeof(struct font_metrics) there? I see no printfs which
show that, so I can only guess.
^ permalink raw reply [flat|nested] 19+ messages in thread
* bug#42943: 28.0.50; Emacsclient crashes in ftcrfont_glyph_extents
2020-08-20 0:47 bug#42943: 28.0.50; Emacsclient crashes in ftcrfont_glyph_extents Basil L. Contovounesios
2020-08-20 14:28 ` Eli Zaretskii
@ 2020-08-21 14:05 ` Lars Ingebrigtsen
2020-10-22 12:41 ` Lars Ingebrigtsen
1 sibling, 1 reply; 19+ messages in thread
From: Lars Ingebrigtsen @ 2020-08-21 14:05 UTC (permalink / raw)
To: Basil L. Contovounesios; +Cc: 42943
I wonder if this is somehow related to bug#42897. Probably not, but two
ftcrfont-related crashes are reported within a few days, so perhaps
there's a connection...
--
(domestic pets only, the antidote for overdose, milk.)
bloggy blog: http://lars.ingebrigtsen.no
^ permalink raw reply [flat|nested] 19+ messages in thread
* bug#42943: 28.0.50; Emacsclient crashes in ftcrfont_glyph_extents
2020-08-21 14:05 ` Lars Ingebrigtsen
@ 2020-10-22 12:41 ` Lars Ingebrigtsen
2020-10-22 22:11 ` Basil L. Contovounesios
0 siblings, 1 reply; 19+ messages in thread
From: Lars Ingebrigtsen @ 2020-10-22 12:41 UTC (permalink / raw)
To: Basil L. Contovounesios; +Cc: 42943
Lars Ingebrigtsen <larsi@gnus.org> writes:
> I wonder if this is somehow related to bug#42897. Probably not, but two
> ftcrfont-related crashes are reported within a few days, so perhaps
> there's a connection...
Are you still seeing this problem? Pip's fix for bug#41627 may or may
not have fixed this problem.
--
(domestic pets only, the antidote for overdose, milk.)
bloggy blog: http://lars.ingebrigtsen.no
^ permalink raw reply [flat|nested] 19+ messages in thread
* bug#42943: 28.0.50; Emacsclient crashes in ftcrfont_glyph_extents
2020-10-22 12:41 ` Lars Ingebrigtsen
@ 2020-10-22 22:11 ` Basil L. Contovounesios
2020-10-24 11:24 ` Robert Pluim
0 siblings, 1 reply; 19+ messages in thread
From: Basil L. Contovounesios @ 2020-10-22 22:11 UTC (permalink / raw)
To: Lars Ingebrigtsen; +Cc: 42943
Lars Ingebrigtsen <larsi@gnus.org> writes:
> Lars Ingebrigtsen <larsi@gnus.org> writes:
>
>> I wonder if this is somehow related to bug#42897. Probably not, but two
>> ftcrfont-related crashes are reported within a few days, so perhaps
>> there's a connection...
>
> Are you still seeing this problem? Pip's fix for bug#41627 may or may
> not have fixed this problem.
Sadly, it doesn't seem to have - I still get a segfault, at least in my
optimised build of master. Hopefully I'll find some time over the
weekend to look into it.
Thanks,
--
Basil
^ permalink raw reply [flat|nested] 19+ messages in thread
* bug#42943: 28.0.50; Emacsclient crashes in ftcrfont_glyph_extents
2020-10-22 22:11 ` Basil L. Contovounesios
@ 2020-10-24 11:24 ` Robert Pluim
2020-10-24 11:46 ` Eli Zaretskii
0 siblings, 1 reply; 19+ messages in thread
From: Robert Pluim @ 2020-10-24 11:24 UTC (permalink / raw)
To: Basil L. Contovounesios; +Cc: Lars Ingebrigtsen, 42943
>>>>> On Thu, 22 Oct 2020 23:11:30 +0100, "Basil L. Contovounesios" <contovob@tcd.ie> said:
Basil> Sadly, it doesn't seem to have - I still get a segfault, at least in my
Basil> optimised build of master. Hopefully I'll find some time over the
Basil> weekend to look into it.
I can reproduce this with a GTK3 + cairo build. Your recipe is very
helpful, in fact just doing 'C-\ arabic RET' is enough to cause the
second emacsclient invocation to crash.
Running emacs under valgrind shows what's going on, but I donʼt know
how to fix it:
==9766== Invalid read of size 2
==9766== at 0x3F8FED: ftcrfont_glyph_extents (ftcrfont.c:81)
==9766== by 0x3F93A0: ftcrfont_draw (ftcrfont.c:522)
==9766== by 0x25C67F: x_draw_composite_glyph_string_foreground (xterm.c:1969)
==9766== by 0x25F9A4: x_draw_glyph_string (xterm.c:3780)
==9766== by 0x1BFC4D: draw_glyphs (xdisp.c:28915)
==9766== by 0x1C65EA: gui_write_glyphs (xdisp.c:30933)
==9766== by 0x15227D: update_text_area (dispnew.c:3849)
==9766== by 0x152C38: update_window_line (dispnew.c:4092)
==9766== by 0x151858: update_window (dispnew.c:3573)
==9766== by 0x151015: update_window_tree (dispnew.c:3344)
==9766== by 0x150C48: update_frame (dispnew.c:3226)
==9766== by 0x19766E: redisplay_internal (xdisp.c:16023)
==9766== Address 0xf36a92e is 126 bytes inside a block of size 1,280 free'd
==9766== at 0x48369AB: free (vg_replace_malloc.c:530)
==9766== by 0x327438: xfree (alloc.c:820)
==9766== by 0x3F9EF4: ftcrfont_close (ftcrfont.c:307)
==9766== by 0x3F9EF4: ftcrfont_close (ftcrfont.c:282)
==9766== by 0x37B285: font_clear_cache (font.c:2648)
==9766== by 0x37B096: font_finish_cache (font.c:2593)
==9766== by 0x37E258: font_update_drivers (font.c:3588)
==9766== by 0x15F56E: delete_frame (frame.c:2093)
==9766== by 0x15FD21: Fdelete_frame (frame.c:2325)
==9766== by 0x35F1FD: funcall_subr (eval.c:2884)
==9766== by 0x35EDE9: Ffuncall (eval.c:2809)
==9766== by 0x356002: Ffuncall_interactively (callint.c:253)
==9766== by 0x35F0FC: funcall_subr (eval.c:2862)
==9766== Block was alloc'd at
==9766== at 0x483577F: malloc (vg_replace_malloc.c:299)
==9766== by 0x327BEB: lmalloc (alloc.c:1359)
==9766== by 0x3272FA: xmalloc (alloc.c:761)
==9766== by 0x3F9093: ftcrfont_glyph_extents (ftcrfont.c:73)
==9766== by 0x3F94B2: ftcrfont_text_extents (ftcrfont.c:371)
==9766== by 0x3803DA: font_fill_lglyph_metrics (font.c:4430)
==9766== by 0x3E1736: fill_gstring_body (composite.c:843)
==9766== by 0x3E42C4: Fcomposition_get_gstring (composite.c:1792)
==9766== by 0x3E1BC3: autocmp_chars (composite.c:912)
==9766== by 0x3E2BCE: composition_reseat_it (composite.c:1269)
==9766== by 0x1858B9: next_element_from_string (xdisp.c:8578)
==9766== by 0x1854C6: next_element_from_string (xdisp.c:8504)
The call to ftcrfont_glyph_extents is from here:
static int
ftcrfont_draw (struct glyph_string *s,
int from, int to, int x, int y, bool with_background)
{
struct frame *f = s->f;
struct face *face = s->face;
struct font_info *ftcrfont_info = (struct font_info *) s->font;
So this means that the struct glyph_string here still refers to the
font from the previous frame, which has been closed. Iʼm not sure how
to get it to refer to the right font on the new frame.
Robert
--
^ permalink raw reply [flat|nested] 19+ messages in thread
* bug#42943: 28.0.50; Emacsclient crashes in ftcrfont_glyph_extents
2020-10-24 11:24 ` Robert Pluim
@ 2020-10-24 11:46 ` Eli Zaretskii
2020-10-24 12:14 ` Robert Pluim
0 siblings, 1 reply; 19+ messages in thread
From: Eli Zaretskii @ 2020-10-24 11:46 UTC (permalink / raw)
To: Robert Pluim; +Cc: contovob, larsi, 42943
> From: Robert Pluim <rpluim@gmail.com>
> Cc: Lars Ingebrigtsen <larsi@gnus.org>, 42943@debbugs.gnu.org, eliz@gnu.org
> Date: Sat, 24 Oct 2020 13:24:42 +0200
>
> The call to ftcrfont_glyph_extents is from here:
>
> static int
> ftcrfont_draw (struct glyph_string *s,
> int from, int to, int x, int y, bool with_background)
> {
> struct frame *f = s->f;
> struct face *face = s->face;
> struct font_info *ftcrfont_info = (struct font_info *) s->font;
>
> So this means that the struct glyph_string here still refers to the
> font from the previous frame, which has been closed. Iʼm not sure how
> to get it to refer to the right font on the new frame.
I'm guessing that we close the font, but there's still a face that
references that font, and we try using that face for display. Can you
see if that is the case? The 'face' member of 'struct glyph_string'
should point to the face, and face->font should point to the font.
We call font_clear_cache when a frame is deleted, so it's unclear to
me how come the font is still remembered somewhere.
And I lack some background here: what is/are the character(s) we try
displaying here, and how that display is triggered by creating a new
frame due to the second emacsclient invocation?
^ permalink raw reply [flat|nested] 19+ messages in thread
* bug#42943: 28.0.50; Emacsclient crashes in ftcrfont_glyph_extents
2020-10-24 11:46 ` Eli Zaretskii
@ 2020-10-24 12:14 ` Robert Pluim
2020-10-24 13:10 ` Eli Zaretskii
2020-10-24 13:27 ` Robert Pluim
0 siblings, 2 replies; 19+ messages in thread
From: Robert Pluim @ 2020-10-24 12:14 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: contovob, larsi, 42943
>>>>> On Sat, 24 Oct 2020 14:46:29 +0300, Eli Zaretskii <eliz@gnu.org> said:
>> From: Robert Pluim <rpluim@gmail.com>
>> Cc: Lars Ingebrigtsen <larsi@gnus.org>, 42943@debbugs.gnu.org, eliz@gnu.org
>> Date: Sat, 24 Oct 2020 13:24:42 +0200
>>
>> The call to ftcrfont_glyph_extents is from here:
>>
>> static int
>> ftcrfont_draw (struct glyph_string *s,
>> int from, int to, int x, int y, bool with_background)
>> {
>> struct frame *f = s->f;
>> struct face *face = s->face;
>> struct font_info *ftcrfont_info = (struct font_info *) s->font;
>>
>> So this means that the struct glyph_string here still refers to the
>> font from the previous frame, which has been closed. Iʼm not sure how
>> to get it to refer to the right font on the new frame.
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:
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
(this is from a separate run from the valgrind one)
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.
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. Are you saying redisplay
should not be called here?
Robert
--
^ permalink raw reply [flat|nested] 19+ messages in thread
* bug#42943: 28.0.50; Emacsclient crashes in ftcrfont_glyph_extents
2020-10-24 12:14 ` Robert Pluim
@ 2020-10-24 13:10 ` Eli Zaretskii
2020-10-24 13:35 ` Robert Pluim
2020-10-24 13:27 ` Robert Pluim
1 sibling, 1 reply; 19+ messages in thread
From: Eli Zaretskii @ 2020-10-24 13:10 UTC (permalink / raw)
To: Robert Pluim; +Cc: contovob, larsi, 42943
> From: Robert Pluim <rpluim@gmail.com>
> Cc: contovob@tcd.ie, larsi@gnus.org, 42943@debbugs.gnu.org
> 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.
^ permalink raw reply [flat|nested] 19+ messages in thread
* bug#42943: 28.0.50; Emacsclient crashes in ftcrfont_glyph_extents
2020-10-24 12:14 ` Robert Pluim
2020-10-24 13:10 ` Eli Zaretskii
@ 2020-10-24 13:27 ` Robert Pluim
2020-10-24 14:12 ` Eli Zaretskii
1 sibling, 1 reply; 19+ messages in thread
From: Robert Pluim @ 2020-10-24 13:27 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: contovob, larsi, 42943
>>>>> On Sat, 24 Oct 2020 14:14:53 +0200, Robert Pluim <rpluim@gmail.com> said:
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.
Robert> Yes, weʼre using the face thatʼs cached in the glyph_string:
Robert> Thread 1 "emacs" received signal SIGSEGV, Segmentation fault.
Robert> ftcrfont_glyph_extents (font=0x555556930478, glyph=1036,
Robert> metrics=metrics@entry=0x0) at ftcrfont.c:81
Robert> 81 if (METRICS_STATUS (cache) == METRICS_INVALID)
Robert> (gdb) up
Robert> #1 0x00005555558453a1 in ftcrfont_draw (s=0x7fffffffb440,
Robert> from=<optimized out>, to=<optimized out>, x=17, y=<optimized out>,
Robert> with_background=<optimized out>) at ftcrfont.c:520
Robert> 520 x += (s->padding_p ? 1 : ftcrfont_glyph_extents (s->font,
Robert> (gdb) l 500
Robert> 495 struct face *face = s->face;
Robert> 496 struct font_info *ftcrfont_info = (struct font_info *) s->font;
Robert> 497 cairo_t *cr;
Robert> 498 cairo_glyph_t *glyphs;
Robert> 499 int len = to - from;
Robert> 500 int i;
Robert> 501
Robert> 502 block_input ();
Robert> 503
Robert> 504 cr = x_begin_cr_clip (f, s->gc);
Robert> (gdb) p s->face
Robert> $1 = (struct face *) 0x555556113290
Robert> (gdb) p s->face->font
Robert> $2 = (struct font *) 0x555556930478
Robert> (gdb) p s->font
Robert> $3 = (struct font *) 0x555556930478
And that font comes from here:
static int
fill_gstring_glyph_string (struct glyph_string *s, int face_id,
int start, int end, int overlaps)
{
struct glyph *glyph, *last;
Lisp_Object lgstring;
int i;
bool glyph_not_available_p;
s->for_overlaps = overlaps;
glyph = s->row->glyphs[s->area] + start;
last = s->row->glyphs[s->area] + end;
glyph_not_available_p = glyph->glyph_not_available_p;
s->cmp_id = glyph->u.cmp.id;
s->cmp_from = glyph->slice.cmp.from;
s->cmp_to = glyph->slice.cmp.to + 1;
s->face = FACE_FROM_ID (s->f, face_id);
lgstring = composition_gstring_from_id (s->cmp_id);
s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring)); <----
so itʼs the caching in the Lisp_Object for the composition thatʼs
causing the problem.
I can also get it to crash by entering 'a' followed by U+306 (COMBINING
BREVE), but the initial code path is different, as then the
initial caching of the font is here:
Lisp_Object
hbfont_shape (Lisp_Object lgstring, Lisp_Object direction)
{
struct font *font = CHECK_FONT_GET_OBJECT (LGSTRING_FONT (lgstring));
(but the final crash is at the same place).
Robert
--
^ permalink raw reply [flat|nested] 19+ messages in thread
* bug#42943: 28.0.50; Emacsclient crashes in ftcrfont_glyph_extents
2020-10-24 13:10 ` Eli Zaretskii
@ 2020-10-24 13:35 ` Robert Pluim
0 siblings, 0 replies; 19+ messages in thread
From: Robert Pluim @ 2020-10-24 13:35 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: contovob, larsi, 42943
>>>>> On Sat, 24 Oct 2020 16:10:31 +0300, Eli Zaretskii <eliz@gnu.org> said:
>> From: Robert Pluim <rpluim@gmail.com>
>> Cc: contovob@tcd.ie, larsi@gnus.org, 42943@debbugs.gnu.org
>> 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:
Eli> But glyph_strings are not kept between redisplay cycles, AFAIR, they
Eli> are recreated anew each time we need to redisplay something. This
Eli> happens in the write_glyphs method that is called from update_window
Eli> and update_frame, which eventually calls gui_write_glyphs, which calls
Eli> draw_glyphs, which creates the glyph_strings in BUILD_GLYPH_STRINGS.
Eli> So it's unclear to me how can a face be cached in a glyph_string.
Youʼre right, itʼs not cached in the glyph_string, itʼs cached in the
composition_gstring thatʼs used to create the glyph_string (see my
other message).
Eli> And how do you see from the above that it's a pointer to the same
Eli> 'struct font' that was used by the now-deleted first client frame?
thatʼs what the valgrind trace earlier said.
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.
Eli> Faces are cached in the frame's face cache, see xfaces.c. When a
Eli> frame is deleted, its face cache is freed, so its faces should also go
Eli> away. A new frame starts with an empty face cache, and then faces are
Eli> added to that cache as they are "realized", starting from the "basic
Eli> faces" that are always needed, see realize_basic_faces. For a
Eli> non-ASCII character, we produce a new face based on the default face,
Eli> the first time we need to display a character that needs a font we
Eli> don't already have; then that face is also added to the frame's face
Eli> 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.
Eli> And *scratch* has an Arabic character? How did that happen? I thought
Eli> the recipe was only to turn on the Arabic input method. Is the
Eli> offending character the IM indicator on the mode-line, per chance?
Yes, I suspect so, since there are no Arabic characters in *scratch*
Robert
--
^ permalink raw reply [flat|nested] 19+ messages in thread
* bug#42943: 28.0.50; Emacsclient crashes in ftcrfont_glyph_extents
2020-10-24 13:27 ` Robert Pluim
@ 2020-10-24 14:12 ` Eli Zaretskii
2020-10-24 14:48 ` Eli Zaretskii
2020-10-24 15:34 ` Robert Pluim
0 siblings, 2 replies; 19+ messages in thread
From: Eli Zaretskii @ 2020-10-24 14:12 UTC (permalink / raw)
To: Robert Pluim; +Cc: contovob, larsi, 42943
> From: Robert Pluim <rpluim@gmail.com>
> Cc: contovob@tcd.ie, larsi@gnus.org, 42943@debbugs.gnu.org
> Date: Sat, 24 Oct 2020 15:27:39 +0200
>
> static int
> fill_gstring_glyph_string (struct glyph_string *s, int face_id,
> int start, int end, int overlaps)
> {
> struct glyph *glyph, *last;
> Lisp_Object lgstring;
> int i;
> bool glyph_not_available_p;
>
> s->for_overlaps = overlaps;
> glyph = s->row->glyphs[s->area] + start;
> last = s->row->glyphs[s->area] + end;
> glyph_not_available_p = glyph->glyph_not_available_p;
> s->cmp_id = glyph->u.cmp.id;
> s->cmp_from = glyph->slice.cmp.from;
> s->cmp_to = glyph->slice.cmp.to + 1;
> s->face = FACE_FROM_ID (s->f, face_id);
> lgstring = composition_gstring_from_id (s->cmp_id);
> s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring)); <----
>
> so itʼs the caching in the Lisp_Object for the composition thatʼs
> causing the problem.
OK, so when we are about to release a font, we need to go over all the
LGSTRING objects in gstring_hash_table, and remove from that cache
every LGSTRING whose LGSTRING_FONT object holds the font we are about
to release.
^ permalink raw reply [flat|nested] 19+ messages in thread
* bug#42943: 28.0.50; Emacsclient crashes in ftcrfont_glyph_extents
2020-10-24 14:12 ` Eli Zaretskii
@ 2020-10-24 14:48 ` Eli Zaretskii
2020-10-24 15:41 ` Robert Pluim
2020-10-24 15:34 ` Robert Pluim
1 sibling, 1 reply; 19+ messages in thread
From: Eli Zaretskii @ 2020-10-24 14:48 UTC (permalink / raw)
To: rpluim; +Cc: contovob, larsi, 42943
> Date: Sat, 24 Oct 2020 17:12:04 +0300
> From: Eli Zaretskii <eliz@gnu.org>
> Cc: contovob@tcd.ie, larsi@gnus.org, 42943@debbugs.gnu.org
>
> > s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring)); <----
> >
> > so itʼs the caching in the Lisp_Object for the composition thatʼs
> > causing the problem.
>
> OK, so when we are about to release a font, we need to go over all the
> LGSTRING objects in gstring_hash_table, and remove from that cache
> every LGSTRING whose LGSTRING_FONT object holds the font we are about
> to release.
Here, does the below give good results?
diff --git a/src/composite.c b/src/composite.c
index 984e0d9..f1b4b97 100644
--- a/src/composite.c
+++ b/src/composite.c
@@ -679,6 +679,27 @@ composition_gstring_from_id (ptrdiff_t id)
return HASH_VALUE (h, id);
}
+/* Remove from the composition hash table every lgstring that
+ references the given FONT_OBJECT. */
+void
+composition_gstring_cache_clear_font (Lisp_Object font_object)
+{
+ struct Lisp_Hash_Table *h = XHASH_TABLE (gstring_hash_table);
+
+ for (ptrdiff_t i = 0; i < HASH_TABLE_SIZE (h); ++i)
+ {
+ Lisp_Object k = HASH_KEY (h, i);
+
+ if (!EQ (k, Qunbound))
+ {
+ Lisp_Object gstring = HASH_VALUE (h, i);
+
+ if (EQ (LGSTRING_FONT (gstring), font_object))
+ hash_remove_from_table (h, k);
+ }
+ }
+}
+
DEFUN ("clear-composition-cache", Fclear_composition_cache,
Sclear_composition_cache, 0, 0, 0,
doc: /* Internal use only.
diff --git a/src/composite.h b/src/composite.h
index 239f1e5..0d7d1c7 100644
--- a/src/composite.h
+++ b/src/composite.h
@@ -331,6 +331,8 @@ #define LGLYPH_WADJUST(g) (VECTORP (LGLYPH_ADJUSTMENT (g)) \
extern ptrdiff_t composition_adjust_point (ptrdiff_t, ptrdiff_t);
+extern void composition_gstring_cache_clear_font (Lisp_Object);
+
INLINE_HEADER_END
#endif /* not EMACS_COMPOSITE_H */
diff --git a/src/font.c b/src/font.c
index fe257f4..d74938e 100644
--- a/src/font.c
+++ b/src/font.c
@@ -2645,6 +2645,11 @@ font_clear_cache (struct frame *f, Lisp_Object cache,
if (! NILP (AREF (val, FONT_TYPE_INDEX)))
{
eassert (font && driver == font->driver);
+ /* We are going to close the font, so make
+ sure we don't have any lgstrings lying
+ around in lgstring cache that reference
+ the font. */
+ composition_gstring_cache_clear_font (val);
driver->close_font (font);
}
}
^ permalink raw reply related [flat|nested] 19+ messages in thread
* bug#42943: 28.0.50; Emacsclient crashes in ftcrfont_glyph_extents
2020-10-24 14:12 ` Eli Zaretskii
2020-10-24 14:48 ` Eli Zaretskii
@ 2020-10-24 15:34 ` Robert Pluim
1 sibling, 0 replies; 19+ messages in thread
From: Robert Pluim @ 2020-10-24 15:34 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: contovob, larsi, 42943
>>>>> On Sat, 24 Oct 2020 17:12:04 +0300, Eli Zaretskii <eliz@gnu.org> said:
>> From: Robert Pluim <rpluim@gmail.com>
>> Cc: contovob@tcd.ie, larsi@gnus.org, 42943@debbugs.gnu.org
>> Date: Sat, 24 Oct 2020 15:27:39 +0200
>>
>> static int
>> fill_gstring_glyph_string (struct glyph_string *s, int face_id,
>> int start, int end, int overlaps)
>> {
>> struct glyph *glyph, *last;
>> Lisp_Object lgstring;
>> int i;
>> bool glyph_not_available_p;
>>
s-> for_overlaps = overlaps;
>> glyph = s->row->glyphs[s->area] + start;
>> last = s->row->glyphs[s->area] + end;
>> glyph_not_available_p = glyph->glyph_not_available_p;
s-> cmp_id = glyph->u.cmp.id;
s-> cmp_from = glyph->slice.cmp.from;
s-> cmp_to = glyph->slice.cmp.to + 1;
s-> face = FACE_FROM_ID (s->f, face_id);
>> lgstring = composition_gstring_from_id (s->cmp_id);
s-> font = XFONT_OBJECT (LGSTRING_FONT (lgstring)); <----
>>
>> so itʼs the caching in the Lisp_Object for the composition thatʼs
>> causing the problem.
Eli> OK, so when we are about to release a font, we need to go over all the
Eli> LGSTRING objects in gstring_hash_table, and remove from that cache
Eli> every LGSTRING whose LGSTRING_FONT object holds the font we are about
Eli> to release.
I stuck an Fclrhash (gstring_hash_table) in ftcrfont_close, and it no
longer crashes (and valgrind is happy). The following also doesnʼt
crash, but I worry about the quadratic behaviour when removing the
entries from the hash_table. Do we need a
hash_remove_from_table_by_index? Am I being overly paranoid?
Iʼve not checked with other font backends, so the same treatment might
be needed there.
diff --git i/src/composite.c w/src/composite.c
index 984e0d9cda..93a700897f 100644
--- i/src/composite.c
+++ w/src/composite.c
@@ -639,6 +639,18 @@ compose_text (ptrdiff_t start, ptrdiff_t end, Lisp_Object components,
static Lisp_Object gstring_lookup_cache (Lisp_Object);
+void
+gstring_remove_from_cache_by_font (struct font * font)
+{
+ struct Lisp_Hash_Table *h = XHASH_TABLE (gstring_hash_table);
+ for (ptrdiff_t i = 0; i < HASH_TABLE_SIZE (h); ++i)
+ {
+ Lisp_Object k = HASH_KEY (h, i);
+ if (!EQ (k, Qunbound) && font == XFONT_OBJECT (LGSTRING_FONT (HASH_VALUE (h, i))))
+ hash_remove_from_table (h, k);
+ }
+}
+
static Lisp_Object
gstring_lookup_cache (Lisp_Object header)
{
diff --git i/src/composite.h w/src/composite.h
index 239f1e531e..2c30ee1933 100644
--- i/src/composite.h
+++ w/src/composite.h
@@ -331,6 +331,8 @@ #define LGLYPH_WADJUST(g) (VECTORP (LGLYPH_ADJUSTMENT (g)) \
extern ptrdiff_t composition_adjust_point (ptrdiff_t, ptrdiff_t);
+extern void gstring_remove_from_cache_by_font (struct font *);
+
INLINE_HEADER_END
#endif /* not EMACS_COMPOSITE_H */
diff --git i/src/ftcrfont.c w/src/ftcrfont.c
index 4892a34a3a..61a2b1290f 100644
--- i/src/ftcrfont.c
+++ w/src/ftcrfont.c
@@ -283,6 +283,7 @@ ftcrfont_close (struct font *font)
struct font_info *ftcrfont_info = (struct font_info *) font;
block_input ();
+ gstring_remove_from_cache_by_font (font);
#ifdef HAVE_LIBOTF
if (ftcrfont_info->otf)
{
Robert
--
^ permalink raw reply related [flat|nested] 19+ messages in thread
* bug#42943: 28.0.50; Emacsclient crashes in ftcrfont_glyph_extents
2020-10-24 14:48 ` Eli Zaretskii
@ 2020-10-24 15:41 ` Robert Pluim
2020-10-24 15:52 ` Eli Zaretskii
0 siblings, 1 reply; 19+ messages in thread
From: Robert Pluim @ 2020-10-24 15:41 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: contovob, larsi, 42943
>>>>> On Sat, 24 Oct 2020 17:48:26 +0300, Eli Zaretskii <eliz@gnu.org> said:
>> Date: Sat, 24 Oct 2020 17:12:04 +0300
>> From: Eli Zaretskii <eliz@gnu.org>
>> Cc: contovob@tcd.ie, larsi@gnus.org, 42943@debbugs.gnu.org
>>
>> > s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring)); <----
>> >
>> > so itʼs the caching in the Lisp_Object for the composition thatʼs
>> > causing the problem.
>>
>> OK, so when we are about to release a font, we need to go over all the
>> LGSTRING objects in gstring_hash_table, and remove from that cache
>> every LGSTRING whose LGSTRING_FONT object holds the font we are about
>> to release.
Eli> Here, does the below give good results?
I should really hit 'g' in Gnus before writing patches :-)
That fixes it as well.
Robert
--
^ permalink raw reply [flat|nested] 19+ messages in thread
* bug#42943: 28.0.50; Emacsclient crashes in ftcrfont_glyph_extents
2020-10-24 15:41 ` Robert Pluim
@ 2020-10-24 15:52 ` Eli Zaretskii
2020-10-26 12:33 ` Robert Pluim
0 siblings, 1 reply; 19+ messages in thread
From: Eli Zaretskii @ 2020-10-24 15:52 UTC (permalink / raw)
To: Robert Pluim; +Cc: contovob, larsi, 42943
> From: Robert Pluim <rpluim@gmail.com>
> Cc: contovob@tcd.ie, larsi@gnus.org, 42943@debbugs.gnu.org
> Date: Sat, 24 Oct 2020 17:41:36 +0200
>
> >> OK, so when we are about to release a font, we need to go over all the
> >> LGSTRING objects in gstring_hash_table, and remove from that cache
> >> every LGSTRING whose LGSTRING_FONT object holds the font we are about
> >> to release.
>
> Eli> Here, does the below give good results?
>
> I should really hit 'g' in Gnus before writing patches :-)
>
> That fixes it as well.
OK, thanks. (I think clearing the entire cache of gstrings is too
radical: we don't necessarily remove all the fonts from all the
frames.)
Now the important question: should we install this on master or on the
release branch? I believe the problem is not limited to 28.0.50, is
it? OTOH, is this safe enough to install on emacs-27?
^ permalink raw reply [flat|nested] 19+ messages in thread
* bug#42943: 28.0.50; Emacsclient crashes in ftcrfont_glyph_extents
2020-10-24 15:52 ` Eli Zaretskii
@ 2020-10-26 12:33 ` Robert Pluim
2020-10-26 16:16 ` Eli Zaretskii
0 siblings, 1 reply; 19+ messages in thread
From: Robert Pluim @ 2020-10-26 12:33 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: contovob, larsi, 42943
Eli Zaretskii <eliz@gnu.org> writes:
>> From: Robert Pluim <rpluim@gmail.com>
>> Cc: contovob@tcd.ie, larsi@gnus.org, 42943@debbugs.gnu.org
>> Date: Sat, 24 Oct 2020 17:41:36 +0200
>>
>> >> OK, so when we are about to release a font, we need to go over all the
>> >> LGSTRING objects in gstring_hash_table, and remove from that cache
>> >> every LGSTRING whose LGSTRING_FONT object holds the font we are about
>> >> to release.
>>
>> Eli> Here, does the below give good results?
>>
>> I should really hit 'g' in Gnus before writing patches :-)
>>
>> That fixes it as well.
>
> OK, thanks. (I think clearing the entire cache of gstrings is too
> radical: we don't necessarily remove all the fonts from all the
> frames.)
>
Right
> Now the important question: should we install this on master or on the
> release branch? I believe the problem is not limited to 28.0.50, is
> it? OTOH, is this safe enough to install on emacs-27?
I can't reproduce this crash on emacs-27 built with Cairo + Harfbuzz
at all.
Robert
--
^ permalink raw reply [flat|nested] 19+ messages in thread
* bug#42943: 28.0.50; Emacsclient crashes in ftcrfont_glyph_extents
2020-10-26 12:33 ` Robert Pluim
@ 2020-10-26 16:16 ` Eli Zaretskii
2020-10-26 20:13 ` Basil L. Contovounesios
0 siblings, 1 reply; 19+ messages in thread
From: Eli Zaretskii @ 2020-10-26 16:16 UTC (permalink / raw)
To: Robert Pluim; +Cc: contovob, larsi, 42943
> From: Robert Pluim <rpluim@gmail.com>
> Cc: contovob@tcd.ie, larsi@gnus.org, 42943@debbugs.gnu.org
> Date: Mon, 26 Oct 2020 13:33:49 +0100
>
> > Now the important question: should we install this on master or on the
> > release branch? I believe the problem is not limited to 28.0.50, is
> > it? OTOH, is this safe enough to install on emacs-27?
>
> I can't reproduce this crash on emacs-27 built with Cairo + Harfbuzz
> at all.
I'm a bit surprised. But okay, let's install on master and wait for
reports about similar problems on emacs-27.
Pushed.
^ permalink raw reply [flat|nested] 19+ messages in thread
* bug#42943: 28.0.50; Emacsclient crashes in ftcrfont_glyph_extents
2020-10-26 16:16 ` Eli Zaretskii
@ 2020-10-26 20:13 ` Basil L. Contovounesios
0 siblings, 0 replies; 19+ messages in thread
From: Basil L. Contovounesios @ 2020-10-26 20:13 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: Robert Pluim, larsi, 42943-done
tags 42943 fixed
close 42943 28.1
quit
Eli Zaretskii <eliz@gnu.org> writes:
>> From: Robert Pluim <rpluim@gmail.com>
>> Cc: contovob@tcd.ie, larsi@gnus.org, 42943@debbugs.gnu.org
>> Date: Mon, 26 Oct 2020 13:33:49 +0100
>>
>> > Now the important question: should we install this on master or on the
>> > release branch? I believe the problem is not limited to 28.0.50, is
>> > it? OTOH, is this safe enough to install on emacs-27?
>>
>> I can't reproduce this crash on emacs-27 built with Cairo + Harfbuzz
>> at all.
Same here, at least with the recipe in the OP.
> I'm a bit surprised.
> But okay, let's install on master and wait for
> reports about similar problems on emacs-27.
>
> Pushed.
Thanks to both of you for debugging this. I can no longer reproduce the
reported crash on master, so I'm closing this report.
--
Basil
^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2020-10-26 20:13 UTC | newest]
Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-08-20 0:47 bug#42943: 28.0.50; Emacsclient crashes in ftcrfont_glyph_extents Basil L. Contovounesios
2020-08-20 14:28 ` Eli Zaretskii
2020-08-21 14:05 ` Lars Ingebrigtsen
2020-10-22 12:41 ` Lars Ingebrigtsen
2020-10-22 22:11 ` Basil L. Contovounesios
2020-10-24 11:24 ` Robert Pluim
2020-10-24 11:46 ` Eli Zaretskii
2020-10-24 12:14 ` Robert Pluim
2020-10-24 13:10 ` Eli Zaretskii
2020-10-24 13:35 ` Robert Pluim
2020-10-24 13:27 ` Robert Pluim
2020-10-24 14:12 ` Eli Zaretskii
2020-10-24 14:48 ` Eli Zaretskii
2020-10-24 15:41 ` Robert Pluim
2020-10-24 15:52 ` Eli Zaretskii
2020-10-26 12:33 ` Robert Pluim
2020-10-26 16:16 ` Eli Zaretskii
2020-10-26 20:13 ` Basil L. Contovounesios
2020-10-24 15:34 ` Robert Pluim
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.