On Sun, Jan 06, 2019 at 07:18:27PM -0800, Eduardo A. Bustamante López wrote: (...) > malloc: unknown:0: assertion botched > malloc: 0x555555769408: allocated: last allocated from unknown:0 > realloc: start and end chunk sizes differ
OK, I think I know what the problem is. I noticed that `rl_insert_text' writes past the end of the rl_line_buffer buffer: | Hardware watchpoint 1: rl_line_buffer[255] | | Old value = -33 '\337' | New value = 48 '0' | __strncpy_ssse3 () at ../sysdeps/x86_64/multiarch/strcpy-ssse3.S:2399 | 2399 ../sysdeps/x86_64/multiarch/strcpy-ssse3.S: No such file or directory. | | (gdb) bt | #0 __strncpy_ssse3 () at ../sysdeps/x86_64/multiarch/strcpy-ssse3.S:2399 | #1 0x0000555555659522 in rl_insert_text (string=0x55555576bc88 '0' <repeats 30 times>) at text.c:99 | #2 0x0000555555655a9f in rl_yank (count=1, key=25) at kill.c:494 | #3 0x0000555555639ef2 in _rl_dispatch_subseq (key=25, map=0x5555556aa200 <emacs_standard_keymap>, got_subseq=0) at readline.c:852 | #4 0x0000555555639c69 in _rl_dispatch (key=1433844896, map=0x5555556aa200 <emacs_standard_keymap>) at readline.c:798 | #5 0x00005555556398ec in readline_internal_char () at readline.c:632 | #6 0x0000555555639947 in readline_internal_charloop () at readline.c:659 | #7 0x0000555555639967 in readline_internal () at readline.c:671 | #8 0x0000555555639385 in readline (prompt=0x5555556809dc "") at readline.c:377 | #9 0x0000555555611bdd in edit_line (p=0x5555556809dc "", itext=0x0) at ./read.def:1107 | #10 0x0000555555610906 in read_builtin (list=0x0) at ./read.def:566 | #11 0x00005555555a5b3f in execute_builtin (builtin=0x55555560fa81 <read_builtin>, words=0x555555762d08, flags=0, subshell=0) at execute_cmd.c:4706 | #12 0x00005555555a6ae7 in execute_builtin_or_function (words=0x555555762d08, builtin=0x55555560fa81 <read_builtin>, var=0x0, redirects=0x5555557629c8, fds_to_close=0x555555762a08, flags=0) | at execute_cmd.c:5214 | #13 0x00005555555a53aa in execute_simple_command (simple_command=0x555555762948, pipe_in=-1, pipe_out=-1, async=0, fds_to_close=0x555555762a08) at execute_cmd.c:4476 | #14 0x000055555559ea39 in execute_command_internal (command=0x555555762908, asynchronous=0, pipe_in=-1, pipe_out=-1, fds_to_close=0x555555762a08) at execute_cmd.c:842 | #15 0x0000555555608586 in parse_and_execute (string=0x55555574b268 "read -e < ~/xxx", from_file=0x5555556690f0 "-c", flags=4) at evalstring.c:436 | #16 0x0000555555585632 in run_one_command (command=0x7fffffffec14 "read -e < ~/xxx") at shell.c:1416 | #17 0x000055555558477d in main (argc=3, argv=0x7fffffffe948, env=0x7fffffffe968) at shell.c:735 | | (gdb) frame 1 | #1 0x0000555555659522 in rl_insert_text (string=0x55555576bc88 '0' <repeats 30 times>) at text.c:99 | 99 strncpy (rl_line_buffer + rl_point, string, l); | | (gdb) l | 94 if (rl_end + l >= rl_line_buffer_len) | 95 rl_extend_line_buffer (rl_end + l); | 96 | 97 for (i = rl_end; i >= rl_point; i--) | 98 rl_line_buffer[i + l] = rl_line_buffer[i]; | 99 strncpy (rl_line_buffer + rl_point, string, l); | 100 | 101 /* Remember how to undo this if we aren't undoing something. */ | 102 if (_rl_doing_an_undo == 0) | 103 { | | (gdb) p rl_end | $1 = 213 | (gdb) p l | $2 = 30 | (gdb) p rl_end + l | $3 = 243 | (gdb) p string | $4 = 0x55555576bc88 '0' <repeats 30 times> | (gdb) p strlen(string) | $5 = 30 | (gdb) p rl_point | $6 = 227 So somehow rl_point ended up with an invalid value. Tracing that problem: | Hardware watchpoint 5: (rl_point > 0 && rl_point > rl_end + 1) | | Old value = 0 | New value = 1 | rl_do_undo () at undo.c:199 | 199 rl_insert_text (rl_undo_list->text); | (gdb) p rl_end | $12 = 0 | (gdb) p rl_point | $13 = 14 | (gdb) bt | #0 rl_do_undo () at undo.c:199 | #1 0x000055555565685c in rl_undo_command (count=1, key=31) at undo.c:356 | #2 0x0000555555639ef2 in _rl_dispatch_subseq (key=31, map=0x5555556aa200 <emacs_standard_keymap>, got_subseq=0) at readline.c:852 | #3 0x0000555555639c69 in _rl_dispatch (key=1433812680, map=0x5555556aa200 <emacs_standard_keymap>) at readline.c:798 | #4 0x00005555556398ec in readline_internal_char () at readline.c:632 | #5 0x0000555555639947 in readline_internal_charloop () at readline.c:659 | #6 0x0000555555639967 in readline_internal () at readline.c:671 | #7 0x0000555555639385 in readline (prompt=0x5555556809dc "") at readline.c:377 | #8 0x0000555555611bdd in edit_line (p=0x5555556809dc "", itext=0x0) at ./read.def:1107 | #9 0x0000555555610906 in read_builtin (list=0x0) at ./read.def:566 | #10 0x00005555555a5b3f in execute_builtin (builtin=0x55555560fa81 <read_builtin>, words=0x555555762d08, flags=0, subshell=0) at execute_cmd.c:4706 | #11 0x00005555555a6ae7 in execute_builtin_or_function (words=0x555555762d08, builtin=0x55555560fa81 <read_builtin>, var=0x0, redirects=0x5555557629c8, fds_to_close=0x555555762a08, flags=0) | at execute_cmd.c:5214 | #12 0x00005555555a53aa in execute_simple_command (simple_command=0x555555762948, pipe_in=-1, pipe_out=-1, async=0, fds_to_close=0x555555762a08) at execute_cmd.c:4476 | #13 0x000055555559ea39 in execute_command_internal (command=0x555555762908, asynchronous=0, pipe_in=-1, pipe_out=-1, fds_to_close=0x555555762a08) at execute_cmd.c:842 | #14 0x0000555555608586 in parse_and_execute (string=0x55555574b268 "read -e < ~/xxx", from_file=0x5555556690f0 "-c", flags=4) at evalstring.c:436 | #15 0x0000555555585632 in run_one_command (command=0x7fffffffec14 "read -e < ~/xxx") at shell.c:1416 | #16 0x000055555558477d in main (argc=3, argv=0x7fffffffe948, env=0x7fffffffe968) at shell.c:735 | (gdb) l | 194 switch (rl_undo_list->what) | 195 { | 196 /* Undoing deletes means inserting some text. */ | 197 case UNDO_DELETE: | 198 rl_point = start; | 199 rl_insert_text (rl_undo_list->text); | 200 xfree (rl_undo_list->text); | 201 break; | 202 | 203 /* Undoing inserts means deleting some text. */ I still don't know how to trigger this with "human" input, but I think the problem is that rl_point should be bounded by the value of rl_end, thus the following patch makes the problem go away: dualbus@system76-pc:~/src/gnu/bash$ git diff -- lib/readline/undo.c diff --git a/lib/readline/undo.c b/lib/readline/undo.c index ae65d380..12952555 100644 --- a/lib/readline/undo.c +++ b/lib/readline/undo.c @@ -196,6 +196,8 @@ rl_do_undo (void) /* Undoing deletes means inserting some text. */ case UNDO_DELETE: rl_point = start; + if (rl_point > rl_end) + rl_point = rl_end; rl_insert_text (rl_undo_list->text); xfree (rl_undo_list->text); break;