Subject: 27.0.91; Infinte loop in display_count_lines
From: Óscar Fuentes <[email-masked]>
To: [email-masked]
Date: Mon, 06 Jul 2020 00:25:19 +0200
List-Id: <debbugs-submit.debbugs.gnu.org>

When the third-party mini-modeline [1] is active, certain quick and
repeated sequence of inputs produce a hang as described here [2].

Attaching gdb to Emacs and stepping through the code it is clear that
there is an infinite loop:

26649         while (start_byte < limit_byte)
(gdb) p start_byte
$32 = 557362
(gdb) p limit_byte
$33 = 703917
(gdb) n
26651             ceiling =  BUFFER_CEILING_OF (start_byte);
(gdb) 
26652             ceiling = min (limit_byte - 1, ceiling);
(gdb) p ceiling
$34 = 557361
(gdb) n
26653             ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
(gdb) p ceiling
$35 = 557361
(gdb) n
26654             base = (cursor = BYTE_POS_ADDR (start_byte));
(gdb) p ceiling_addr 
$36 = (unsigned char *) 0x558ca0bb4241 "\037\nFile: emacs.info,  Node: Remote Files,  Next: Quoted File Names,  Prev: File Archives,  Up: Files\n\n18.15 Remote Files\n", '=' <repeats 18 times>, "\n\nYou can refer to files on other machines using a special fil"...
(gdb) n
26658                 if (selective_display)
(gdb) p base
$37 = (unsigned char *) 0x558ca0bb4241 "\037\nFile: emacs.info,  Node: Remote Files,  Next: Quoted File Names,  Prev: File Archives,  Up: Files\n\n18.15 Remote Files\n", '=' <repeats 18 times>, "\n\nYou can refer to files on other machines using a special fil"...
(gdb) p selective_display
$38 = false
(gdb) n
26668                     cursor = memchr (cursor, '\n', ceiling_addr - cursor);
(gdb) p cursor
$39 = (unsigned char *) 0x558ca0bb4241 "\037\nFile: emacs.info,  Node: Remote Files,  Next: Quoted File Names,  Prev: File Archives,  Up: Files\n\n18.15 Remote Files\n", '=' <repeats 18 times>, "\n\nYou can refer to files on other machines using a special fil"...
(gdb) n
26669                     if (! cursor)
(gdb) p cursor
$40 = (unsigned char *) 0x0
(gdb) n
26684             start_byte += ceiling_addr - base;
(gdb) p ceiling_addr
$41 = (unsigned char *) 0x558ca0bb4241 "\037\nFile: emacs.info,  Node: Remote Files,  Next: Quoted File Names,  Prev: File Archives,  Up: Files\n\n18.15 Remote Files\n", '=' <repeats 18 times>, "\n\nYou can refer to files on other machines using a special fil"...
(gdb) p base
$42 = (unsigned char *) 0x558ca0bb4241 "\037\nFile: emacs.info,  Node: Remote Files,  Next: Quoted File Names,  Prev: File Archives,  Up: Files\n\n18.15 Remote Files\n", '=' <repeats 18 times>, "\n\nYou can refer to files on other machines using a special fil"...
(gdb) n
26649         while (start_byte < limit_byte)
(gdb) p start_byte
$43 = 557362
(gdb) 

(gdb) bt
#0  0x0000558c791fa4c0 in BUFFER_CEILING_OF (bytepos=557362)
    at ../../emacs/src/xdisp.c:26727
#1  display_count_lines
    (start_byte=557362, limit_byte=limit_byte@entry=703917, count=681760, 
    count@entry=681823, byte_pos_ptr=byte_pos_ptr@entry=0x7fff2cae4c08)
    at ../../emacs/src/xdisp.c:26651
#2  0x0000558c792178ca in decode_mode_spec
    (string=<synthetic pointer>, field_width=0, c=<optimized out>, w=<optimized out>)
    at ../../emacs/src/xdisp.c:26376
#3  display_mode_element
    (it=<optimized out>, depth=<optimized out>, field_width=<optimized out>, precision=<optimized out>, elt=<optimized out>, props=0x0, risky=<optimized out>)
    at ../../emacs/src/xdisp.c:25494
#4  0x0000558c792182fd in display_mode_element
    (it=0x7fff2cae5090, depth=<optimized out>, field_width=10, precision=-40, elt=<optimized out>, props=0x0, risky=<optimized out>) at ../../emacs/src/lisp.h:1450
#5  0x0000558c792182fd in display_mode_element
    (it=0x7fff2cae5090, depth=<optimized out>, field_width=-3, precision=-40, elt=<optimized out>, props=0x0, risky=<optimized out>) at ../../emacs/src/lisp.h:1450
#6  0x0000558c792182fd in display_mode_element
    (it=0x7fff2cae5090, depth=<optimized out>, field_width=0, precision=-37, elt=<optimized out>, props=0x0, risky=<optimized out>) at ../../emacs/src/lisp.h:1450
#7  0x0000558c792182fd in display_mode_element
    (it=0x7fff2cae5090, depth=<optimized out>, field_width=0, precision=0, elt=<optimized out>, props=0x0, risky=<optimized out>) at ../../emacs/src/lisp.h:1450
#8  0x0000558c79218cc6 in Fformat_mode_line
    (format=0x558c7cd189f3, face=<optimized out>, window=0x558c8721fe55, buffer=<optimized out>) at ../../emacs/src/lisp.h:1033
#9  0x0000558c79323c9a in eval_sub (form=<optimized out>) at ../../emacs/src/lisp.h:2110
#10 0x0000558c79323762 in apply_lambda
    (fun=0x558c810684f3, args=<optimized out>, count=count@entry=45)
    at ../../emacs/src/eval.c:2922
#11 0x0000558c79323a73 in eval_sub (form=<optimized out>) at ../../emacs/src/eval.c:2349
--Type <RET> for more, q to quit, c to continue without paging--
#12 0x0000558c79324507 in Fsetq (args=<optimized out>) at ../../emacs/src/eval.c:509
#13 0x0000558c79323be9 in eval_sub (form=<optimized out>) at ../../emacs/src/lisp.h:2110
#14 0x0000558c793243bd in Fprogn (body=0x558c81063503) at ../../emacs/src/eval.c:462
#15 Fif (args=<optimized out>) at ../../emacs/src/eval.c:418
#16 Fif (args=<optimized out>) at ../../emacs/src/eval.c:404
#17 0x0000558c79323be9 in eval_sub (form=<optimized out>) at ../../emacs/src/lisp.h:2110
#18 0x0000558c79323f7d in Fprogn (body=0x558c8106ab43) at ../../emacs/src/eval.c:462
#19 0x0000558c79323be9 in eval_sub (form=<optimized out>) at ../../emacs/src/lisp.h:2110
#20 0x0000558c79323be9 in eval_sub (form=<optimized out>) at ../../emacs/src/lisp.h:2110
#21 0x0000558c7932500d in Fprogn (body=0x0) at ../../emacs/src/eval.c:462
#22 Flet (args=0x558c8106ab83) at ../../emacs/src/eval.c:987
#23 0x0000558c79323be9 in eval_sub (form=<optimized out>) at ../../emacs/src/lisp.h:2110
#24 0x0000558c79323f7d in Fprogn (body=0x0, body@entry=0x558c8106abb3)
    at ../../emacs/src/eval.c:462
#25 0x0000558c793159ba in Fsave_current_buffer (args=0x558c8106abb3)
    at ../../emacs/src/editfns.c:855
#26 0x0000558c79323be9 in eval_sub (form=<optimized out>) at ../../emacs/src/lisp.h:2110
#27 0x0000558c793243bd in Fprogn (body=0x0) at ../../emacs/src/eval.c:462
#28 Fif (args=<optimized out>) at ../../emacs/src/eval.c:418
#29 Fif (args=<optimized out>) at ../../emacs/src/eval.c:404
#30 0x0000558c79323be9 in eval_sub (form=<optimized out>) at ../../emacs/src/lisp.h:2110
#31 0x0000558c79323f7d in Fprogn (body=0x0) at ../../emacs/src/eval.c:462
#32 0x0000558c79323be9 in eval_sub (form=<optimized out>) at ../../emacs/src/lisp.h:2110
#33 0x0000558c793252af in Funwind_protect (args=0x558c8106a483)
    at ../../emacs/src/lisp.h:1444
#34 0x0000558c79323be9 in eval_sub (form=<optimized out>) at ../../emacs/src/lisp.h:2110
#35 0x0000558c793251ff in Fprogn (body=0x0) at ../../emacs/src/eval.c:462
#36 FletX (args=0x558c8106a4d3) at ../../emacs/src/eval.c:919
#37 0x0000558c79323be9 in eval_sub (form=<optimized out>) at ../../emacs/src/lisp.h:2110
#38 0x0000558c793254e9 in internal_lisp_condition_case
    (var=0x29e960379b48, bodyform=0x558c8106a4e3, handlers=<optimized out>)
    at ../../emacs/src/eval.c:1327
#39 0x0000558c79323be9 in eval_sub (form=<optimized out>) at ../../emacs/src/lisp.h:2110
--Type <RET> for more, q to quit, c to continue without paging--
#40 0x0000558c79323f7d in Fprogn (body=0x0) at ../../emacs/src/eval.c:462
#41 0x0000558c79323be9 in eval_sub (form=<optimized out>) at ../../emacs/src/lisp.h:2110
#42 0x0000558c793252af in Funwind_protect (args=0x558c8106a583)
    at ../../emacs/src/lisp.h:1444
#43 0x0000558c79323be9 in eval_sub (form=<optimized out>) at ../../emacs/src/lisp.h:2110
#44 0x0000558c7932500d in Fprogn (body=0x0) at ../../emacs/src/eval.c:462
#45 Flet (args=0x558c8106a5d3) at ../../emacs/src/eval.c:987
#46 0x0000558c79323be9 in eval_sub (form=<optimized out>) at ../../emacs/src/lisp.h:2110
#47 0x0000558c79324255 in Fprogn (body=0x0) at ../../emacs/src/eval.c:462
#48 funcall_lambda (fun=0x558c8106a683, nargs=1, arg_vector=0x7fff2cae72a0)
    at ../../emacs/src/eval.c:3061
#49 0x0000558c793237a3 in apply_lambda
    (fun=0x558c8106a693, args=<optimized out>, count=count@entry=20)
    at ../../emacs/src/eval.c:2927
#50 0x0000558c79323a73 in eval_sub (form=<optimized out>) at ../../emacs/src/eval.c:2349
#51 0x0000558c793251ff in Fprogn (body=0x0) at ../../emacs/src/eval.c:462
#52 FletX (args=0x558c81068693) at ../../emacs/src/eval.c:919
#53 0x0000558c79323be9 in eval_sub (form=<optimized out>) at ../../emacs/src/lisp.h:2110
#54 0x0000558c793243bd in Fprogn (body=0x0) at ../../emacs/src/eval.c:462
#55 Fif (args=<optimized out>) at ../../emacs/src/eval.c:418
#56 Fif (args=<optimized out>) at ../../emacs/src/eval.c:404
#57 0x0000558c79323be9 in eval_sub (form=<optimized out>) at ../../emacs/src/lisp.h:2110
#58 0x0000558c79324255 in Fprogn (body=0x0) at ../../emacs/src/eval.c:462
#59 funcall_lambda (fun=0x558c81068153, nargs=5, arg_vector=0x7fff2cae7668)
    at ../../emacs/src/eval.c:3061
#60 0x0000558c79321d47 in Ffuncall (nargs=6, args=0x7fff2cae7660)
    at ../../emacs/src/eval.c:2809
#61 0x0000558c79322072 in Fapply (nargs=3, args=0x7fff2cae7778)
    at ../../emacs/src/eval.c:2425
#62 0x0000558c79321de3 in Ffuncall (nargs=4, args=args@entry=0x7fff2cae7770)
    at ../../emacs/src/lisp.h:2110
#63 0x0000558c79355c48 in exec_byte_code
    (bytestr=<optimized out>, vector=<optimized out>, maxdepth=<optimized out>, args_template--Type <RET> for more, q to quit, c to continue without paging--
=<optimized out>, nargs=<optimized out>, args=<optimized out>)
    at ../../emacs/src/bytecode.c:633
#64 0x0000558c79321d47 in Ffuncall (nargs=5, args=args@entry=0x7fff2cae7a70)
    at ../../emacs/src/eval.c:2809
#65 0x0000558c79355c48 in exec_byte_code
    (bytestr=<optimized out>, vector=<optimized out>, maxdepth=<optimized out>, args_template=<optimized out>, nargs=<optimized out>, args=<optimized out>)
    at ../../emacs/src/bytecode.c:633
#66 0x0000558c79321d47 in Ffuncall (nargs=2, args=args@entry=0x7fff2cae7e68)
    at ../../emacs/src/eval.c:2809
#67 0x0000558c79355c48 in exec_byte_code
    (bytestr=<optimized out>, vector=<optimized out>, maxdepth=<optimized out>, args_template=<optimized out>, nargs=<optimized out>, args=<optimized out>)
    at ../../emacs/src/bytecode.c:633
#68 0x0000558c79321d47 in Ffuncall (nargs=nargs@entry=2, args=args@entry=0x7fff2cae83e8)
    at ../../emacs/src/eval.c:2809
#69 0x0000558c7931e7f1 in Ffuncall_interactively (nargs=2, args=0x7fff2cae83e8)
    at ../../emacs/src/callint.c:254
#70 0x0000558c79321de3 in Ffuncall (nargs=3, args=0x7fff2cae83e0)
    at ../../emacs/src/lisp.h:2110
#71 0x0000558c79322133 in Fapply (nargs=nargs@entry=3, args=args@entry=0x7fff2cae83e0)
    at ../../emacs/src/eval.c:2382
#72 0x0000558c7931fd0a in Fcall_interactively
    (function=0x29e960243620, record_flag=0x0, keys=0x558c8952c9b5)
    at ../../emacs/src/lisp.h:1033
#73 0x0000558c79321de3 in Ffuncall (nargs=4, args=args@entry=0x7fff2cae84d8)
    at ../../emacs/src/lisp.h:2110
#74 0x0000558c79355c48 in exec_byte_code
    (bytestr=<optimized out>, vector=<optimized out>, maxdepth=<optimized out>, args_template=<optimized out>, nargs=<optimized out>, args=<optimized out>)
    at ../../emacs/src/bytecode.c:633
#75 0x0000558c79321d47 in Ffuncall (nargs=2, args=0x7fff2cae8870)
    at ../../emacs/src/eval.c:2809
--Type <RET> for more, q to quit, c to continue without paging--
#76 0x0000558c79321e8a in call1 (fn=fn@entry=0x3d50, arg1=<optimized out>)
    at ../../emacs/src/eval.c:2655
#77 0x0000558c792bbec8 in command_loop_1 () at ../../emacs/src/lisp.h:1033
#78 0x0000558c793210f7 in internal_condition_case
    (bfun=bfun@entry=0x558c792bbaf0 <command_loop_1>, handlers=handlers@entry=0x90, hfun=hfun@entry=0x558c792b2d50 <cmd_error>) at ../../emacs/src/eval.c:1356
#79 0x0000558c792adbb4 in command_loop_2 (ignore=ignore@entry=0x0)
    at ../../emacs/src/lisp.h:1033
#80 0x0000558c79321051 in internal_catch
    (tag=tag@entry=0xcc60, func=func@entry=0x558c792adb90 <command_loop_2>, arg=arg@entry=0x0) at ../../emacs/src/eval.c:1117
#81 0x0000558c792adb5b in command_loop () at ../../emacs/src/lisp.h:1033
#82 0x0000558c792b2966 in recursive_edit_1 () at ../../emacs/src/keyboard.c:714
#83 0x0000558c792b2c92 in Frecursive_edit () at ../../emacs/src/keyboard.c:786
#84 0x0000558c791e4ae6 in main (argc=1, argv=<optimized out>)
    at ../../emacs/src/emacs.c:2062

(gdb) xbacktrace
"format-mode-line" (0x2cae6410)
"mini-modeline--multi-lr-render" (0x2cae6538)
"setq" (0x2cae6618)
"if" (0x2cae66e8)
"progn" (0x2cae67a8)
"if" (0x2cae6858)
"let" (0x2cae6998)
"save-current-buffer" (0x2cae6a78)
"if" (0x2cae6b48)
"progn" (0x2cae6c08)
"unwind-protect" (0x2cae6cd8)
"let*" (0x2cae6dd8)
"condition-case" (0x2cae6ef8)
"progn" (0x2cae6fb8)
"unwind-protect" (0x2cae7088)
"let" (0x2cae71a8)
"mini-modeline-display" (0x2cae72a0)
"let*" (0x2cae7438)
"if" (0x2cae7508)
"mini-modeline--reroute-msg" (0x2cae7668)
"apply" (0x2cae7778)
"message" (0x2cae7a78)
"Info-index-next" (0x2cae7e70)
"Info-index" (0x2cae83f0)
"funcall-interactively" (0x2cae83e8)
"call-interactively" (0x2cae84e0)
"command-execute" (0x2cae8878)

References:

1. https://github.com/kiennq/emacs-mini-modeline
2. https://github.com/kiennq/emacs-mini-modeline/issues/34

In GNU Emacs 27.0.91 (build 1, x86_64-pc-linux-gnu, X toolkit)
 of 2020-05-02 built on sky
Repository revision: 5a5d8a8ec0610aa4b26011ebae434bcf3e11c993
Repository branch: emacs-27
Windowing system distributor 'The X.Org Foundation', version 11.0.12008000
System Description: Debian GNU/Linux bullseye/sid