bug-bash
[Top][All Lists]
Advanced

[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;



reply via email to

[Prev in Thread] Current Thread [Next in Thread]