Subject: bug#71289: 30.0.50; cmcheckmagic aborts when tty_write_glyphs writes "Garbage collecting..." in some cases

From: Daniel Clemente <[email-masked]>
Date: Mon, 3 Jun 2024 15:36:05 +0000

Many of the backtraces I'm sending (more below) point to the same
issue: resizing the terminal while the GC messages are being displayed
can make the asserts fail.
Depending on the time I 'catch' it it shows an error or another in the
backtrace.

I still don't have a way to reproduce this, but the following recipe
seems to improve the chances:
(setq garbage-collection-messages t)

Then run some operation that clearly triggers GC. For instance I'm
using this formula (better ideas welcome):
(setq gc-cons-threshold 100000)
(cl-loop for i from 3000000 downto 1 do (+ 2.00 (+ 2.0 (+ 2.0 (+ 2.0
(+ 2.0 2.0))))))

While that operation is running (you'll repeatedly see "Garbage
collecting" "… done"), resize the terminal constantly until it
crashes.
But sometimes I can't reproduce it at all with this method!
And never could I in emacs -Q

But I'm getting tired of manually testing. I may have to automate the resizing.

Anyway this is a very rare bug which probably only happens when GC
messages are enabled, in TTY emacs, and while resizing the terminal.
An obvious workaround if this affects others is disabling
garbage-collection-messages, which seems buggy.
Maybe the problem is in message3_nolog.

Here's are two backtraces of two crashes in different points that I
didn't report yet. I suspect they are all this same bug because they
involve GC.

dispnew.c:3155: Emacs fatal error: assertion failed: vpos >= 0 && vpos
<= FRAME_TOTAL_LINES (XFRAME (w->frame))

Breakpoint 1, terminate_due_to_signal (sig=6,
backtrace_limit=2147483647) at emacs.c:443
443  signal (sig, SIG_DFL);
(gdb) bt
#0  terminate_due_to_signal (sig=6, backtrace_limit=2147483647) at emacs.c:443
#1  0x0000555555735c81 in die (msg=0x55555584e908 "vpos >= 0 && vpos
<= FRAME_TOTAL_LINES (XFRAME (w->frame))",
    file=0x55555584e231 "dispnew.c", line=3155) at alloc.c:8082
#2  0x000055555558cc96 in window_to_frame_vpos (w=0x555556559190,
vpos=26) at dispnew.c:3155
#3  0x0000555555590ea9 in update_frame_1 (f=0x5555560374b8,
force_p=true, inhibit_id_p=true, set_cursor_p=true,
    updating_menu_p=false) at dispnew.c:5089
#4  0x000055555558cfad in update_frame (f=0x5555560374b8,
force_p=true, inhibit_hairy_id_p=true) at dispnew.c:3346
#5  0x00005555555ca441 in echo_area_display (update_frame_p=true) at
xdisp.c:13487
#6  0x00005555555c63fb in message3_nolog (m=XIL(0x555557424cf4)) at
xdisp.c:12385
#7  0x00005555555c97d8 in restore_message () at xdisp.c:13166
#8  0x0000555555732cd2 in garbage_collect () at alloc.c:6690
#9  0x0000555555732817 in maybe_garbage_collect () at alloc.c:6507
#10 0x0000555555769a95 in maybe_gc () at /w/emacs/src/lisp.h:5927
#11 0x000055555576f4d7 in eval_sub (form=XIL(0x555556d39bf3)) at eval.c:2502

dispnew.c:2649: Emacs fatal error: assertion failed: glyph_row_slice_p
(window_row, frame_row)

Breakpoint 1, terminate_due_to_signal (sig=6,
backtrace_limit=2147483647) at emacs.c:443
443  signal (sig, SIG_DFL);
(gdb) bt
#0  terminate_due_to_signal (sig=6, backtrace_limit=2147483647) at emacs.c:443
#1  0x0000555555735c81 in die (msg=0x55555584e838 "glyph_row_slice_p
(window_row, frame_row)",
    file=0x55555584e231 "dispnew.c", line=2649) at alloc.c:8082
#2  0x000055555558b5f3 in build_frame_matrix_from_leaf_window
(frame_matrix=0x55555607fc20, w=0x555556037970)
    at dispnew.c:2649
#3  0x000055555558b10f in build_frame_matrix_from_window_tree
(matrix=0x55555607fc20, w=0x555556037970) at dispnew.c:2538
#4  0x000055555558b0a4 in build_frame_matrix (f=0x5555560374b8) at
dispnew.c:2522
#5  0x000055555558cf68 in update_frame (f=0x5555560374b8,
force_p=true, inhibit_hairy_id_p=true) at dispnew.c:3336
#6  0x00005555555ca441 in echo_area_display (update_frame_p=true) at
xdisp.c:13487
#7  0x00005555555c63fb in message3_nolog (m=XIL(0x555559663284)) at
xdisp.c:12385
#8  0x00005555555c64a7 in message1_nolog (m=0x55555586f976 "Garbage
collecting...") at xdisp.c:12413
#9  0x0000555555732a80 in garbage_collect () at alloc.c:6587
#10 0x0000555555732817 in maybe_garbage_collect () at alloc.c:6507
#11 0x0000555555769a95 in maybe_gc () at /w/emacs/src/lisp.h:5927
#12 0x000055555576f4d7 in eval_sub (form=XIL(0x555559b8e323)) at eval.c:2502
#13 0x000055555576a6f5 in Fprogn (body=XIL(0)) at eval.c:439
#14 0x000055555576a725 in prog_ignore (body=XIL(0x555559b8e3c3)) at eval.c:450
#15 0x000055555576c30a in Fwhile (args=XIL(0x555559b8e453)) at eval.c:1130
#16 0x000055555576f82d in eval_sub (form=XIL(0x555559b8e463)) at eval.c:2549
#17 0x000055555576a6f5 in Fprogn (body=XIL(0x555559b8e393)) at eval.c:439
#18 0x000055555576beb8 in FletX (args=XIL(0x555559b8e4b3)) at eval.c:1042
#19 0x000055555576f82d in eval_sub (form=XIL(0x555559b8e4c3)) at eval.c:2549
#20 0x000055555576f2ad in Feval (form=XIL(0x555559b8e4c3),
lexical=XIL(0)) at eval.c:2462
#21 0x0000555555771416 in funcall_subr (subr=0x555555ec5a80 <Seval>,
numargs=2, args=0x7fffffffc8c8) at eval.c:3163
#22 0x0000555555770db6 in funcall_general (fun=XIL(0x555555ec5a85),
numargs=2, args=0x7fffffffc8c8) at eval.c:3040
#23 0x00005555557710bf in Ffuncall (nargs=3, args=0x7fffffffc8c0) at eval.c:3093
#24 0x00007ffff1488d94 in
F656c6973702d2d6576616c2d6c6173742d73657870_elisp__eval_last_sexp_0 ()
   from /opt/dc/emacs/bin/../lib/emacs/30.0.50/native-lisp/30.0.50-3670981c/preloaded/elisp-mode-90dbfe40-73c5a2ea.eln
#25 0x00005555557713ef in funcall_subr (subr=0x7ffff1d49010,
numargs=1, args=0x7ffff05ff038) at eval.c:3161
#26 0x00005555557cd7bc in exec_byte_code (fun=XIL(0x5555599b90fd),
args_template=0, nargs=0, args=0x7fffffffcfd0)
    at bytecode.c:812
#27 0x0000555555771a68 in funcall_lambda (fun=XIL(0x5555599b90fd),
nargs=0, arg_vector=0x7fffffffcfd0) at eval.c:3252
#28 0x0000555555770e02 in funcall_general (fun=XIL(0x5555599b90fd),
numargs=0, args=0x7fffffffcfd0) at eval.c:3044
#29 0x00005555557710bf in Ffuncall (nargs=1, args=0x7fffffffcfc8) at eval.c:3093
#30 0x000055555576937e in call0 (fn=XIL(0x5555599b90fd)) at
/w/emacs/src/lisp.h:3515
#31 0x000055555576cbe2 in Fhandler_bind_1 (nargs=3,
args=0x7fffffffd050) at eval.c:1478
#32 0x00007ffff14892c4 in F6576616c2d6c6173742d73657870_eval_last_sexp_0 ()
   from /opt/dc/emacs/bin/../lib/emacs/30.0.50/native-lisp/30.0.50-3670981c/preloaded/elisp-mode-90dbfe40-73c5a2ea.eln
#33 0x00005555557713ef in funcall_subr (subr=0x7ffff1d056e0,
numargs=1, args=0x7fffffffd330) at eval.c:3161
#34 0x0000555555770db6 in funcall_general (fun=XIL(0x7ffff1d056e5),
numargs=1, args=0x7fffffffd330) at eval.c:3040
#35 0x00005555557710bf in Ffuncall (nargs=2, args=0x7fffffffd328) at eval.c:3093
#36 0x00005555557656ec in Ffuncall_interactively (nargs=2,
args=0x7fffffffd328) at callint.c:250
#37 0x000055555577164f in funcall_subr (subr=0x555555ec4d00
<Sfuncall_interactively>, numargs=2, args=0x7fffffffd328)
    at eval.c:3184
#38 0x0000555555770db6 in funcall_general (fun=XIL(0x555555ec4d05),
numargs=2, args=0x7fffffffd328) at eval.c:3040
#39 0x00005555557710bf in Ffuncall (nargs=3, args=0x7fffffffd320) at eval.c:3093
#40 0x0000555555767d88 in Fcall_interactively
(function=XIL(0x2aaa9bdbe9b0), record_flag=XIL(0),
    keys=XIL(0x5555596dec2d)) at callint.c:789
#41 0x00007ffff16848fd in F636f6d6d616e642d65786563757465_command_execute_0 ()
   from /opt/dc/emacs/bin/../lib/emacs/30.0.50/native-lisp/30.0.50-3670981c/preloaded/simple-fab5b0cf-651091ae.eln
#42 0x0000555555771484 in funcall_subr (subr=0x7ffff212eff8,
numargs=1, args=0x7fffffffda98) at eval.c:3167
#43 0x0000555555770db6 in funcall_general (fun=XIL(0x7ffff212effd),
numargs=1, args=0x7fffffffda98) at eval.c:3040
#44 0x00005555557710bf in Ffuncall (nargs=2, args=0x7fffffffda90) at eval.c:3093
#45 0x0000555555691eb7 in command_loop_1 () at keyboard.c:1550
#46 0x000055555576d295 in internal_condition_case (bfun=0x55555569167e
<command_loop_1>, handlers=XIL(0x90),
    hfun=0x555555690b29 <cmd_error>) at eval.c:1613
#47 0x000055555569125c in command_loop_2 (handlers=XIL(0x90)) at keyboard.c:1168
#48 0x000055555576c6c2 in internal_catch (tag=XIL(0xfc60),
func=0x555555691232 <command_loop_2>, arg=XIL(0x90))
    at eval.c:1292
#49 0x00005555556911ee in command_loop () at keyboard.c:1146
#50 0x00005555556905cb in recursive_edit_1 () at keyboard.c:754
#51 0x00005555556907f7 in Frecursive_edit () at keyboard.c:837
--Type <RET> for more, q to quit, c to continue without paging--q
Quit
(gdb) xbacktrace
DCL: step0 in handle_window_change_signal, sig 28
DCL: handle_window_change_signal, tty
"Automatic GC" (0x0)
"while" (0xffffc430)
"let*" (0xffffc630)
"eval" (0xffffc8c8)
"elisp--eval-last-sexp" (0xf05ff038)
0x599b90f8 PVEC_CLOSURE
"eval-last-sexp" (0xffffd330)
"funcall-interactively" (0xffffd328)
"command-execute" (0xffffda98)
(gdb) bt full
#0  terminate_due_to_signal (sig=6, backtrace_limit=2147483647) at emacs.c:443
No locals.
#1  0x0000555555735c81 in die (msg=0x55555584e838 "glyph_row_slice_p
(window_row, frame_row)",
    file=0x55555584e231 "dispnew.c", line=2649) at alloc.c:8082
No locals.
#2  0x000055555558b5f3 in build_frame_matrix_from_leaf_window
(frame_matrix=0x55555607fc20, w=0x555556037970)
    at dispnew.c:2649
        frame_row = 0x555559e21520
        window_row = 0x55555a498010
        current_row_p = false
        window_matrix = 0x55555925ac50
        window_y = 0
        frame_y = 12
        right_border_glyph = {
          ch = 0,
          face_id = 0
        }
#3  0x000055555558b10f in build_frame_matrix_from_window_tree
(matrix=0x55555607fc20, w=0x555556037970) at dispnew.c:2538
No locals.
#4  0x000055555558b0a4 in build_frame_matrix (f=0x5555560374b8) at
dispnew.c:2522
        i = 13
#5  0x000055555558cf68 in update_frame (f=0x5555560374b8,
force_p=true, inhibit_hairy_id_p=true) at dispnew.c:3336
        paused_p = false
        root_window = 0x555556082ac0
#6  0x00005555555ca441 in echo_area_display (update_frame_p=true) at
xdisp.c:13487
        n = 0
        mini_window = XIL(0x555556037975)
        w = 0x555556037970
        f = 0x5555560374b8
        window_height_changed_p = false
        sf = 0x5555560374b8
#7  0x00005555555c63fb in message3_nolog (m=XIL(0x555559663284)) at
xdisp.c:12385
        mini_window = XIL(0x555556037975)
        frame = XIL(0x5555560374bd)
        f = 0x5555560374b8
        sf = 0x5555560374b8
#8  0x00005555555c64a7 in message1_nolog (m=0x55555586f976 "Garbage
collecting...") at xdisp.c:12413
No locals.
#9  0x0000555555732a80 in garbage_collect () at alloc.c:6587
        tail = XIL(0)
        buffer = XIL(0x555557a3418d)
        stack_top_variable = 0 '\000'
        message_p = true
        count = {
          bytes = 480
        }
        start = {
          tv_sec = 1717410695,
          tv_nsec = 985484457
        }
        tot_before = 18446744073709551615
        visitor = {
          visit = 0x7fffffffc180,
          data = 0x555555732639 <consing_threshold+116>
        }