[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: realloc: start and end chunk sizes differ - rl_extend_line_buffer in
From: |
Eduardo A . Bustamante López |
Subject: |
Re: realloc: start and end chunk sizes differ - rl_extend_line_buffer in lib/readline/util.c |
Date: |
Sun, 6 Jan 2019 20:46:33 -0800 |
User-agent: |
Mutt/1.10.1 (2018-07-13) |
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;