Dominique Pelle wrote:
> Once in a while, I see that Vim enters an endless loop and takes 100% of
> the CPU. I've seen this bug a couple times when using the Perforce plugin:
> I try to edit file, the perforce plugin asks to checkout the file, I enter
> 'Y',
> the file gets checked-out but then Vim sometimes loops forever using
> 100% of the CPU!?
>
> It does not happens all the time and it's quite rare. I don't have
> a reproducible test case, which makes it hard to debug. It just
> happened today using Vim-7.2.163 (in xterm on Linux x86_64).
> I attached to the runaway process with cgcb and I can see where
> it's looping forever:
>
> edit.c:
>
> 6433 for (;;)
> 6434 {
> 6435†> if (gchar_cursor() == NUL && curwin->w_cursor.col > 0)
> 6436 --curwin->w_cursor.col;
> 6437 cc = gchar_cursor();
> 6438 if (!vim_iswhite(cc))
> 6439 break;
> 6440 (void)del_char(TRUE);
> 6441 }
>
> Stepping over line by line with gdb, the following lines in edit.c
> are being executed indefinitely:
>
> 6435, 6437, 6438, 6440 and then back to
> 6435, 6437, 6438, 6440, etc.
>
> While looping, I see that 'curwin->w_cursor' and 'cc' always remained
> identical:
>
> (gdb) p curwin->w_cursor
> $11 = {
> lnum = 133,
> col = 2,
> coladd = 0
> }
>
> (gdb) p cc
> $12 = 32
>
> The file I was editing has 1487 lines. Line 133 is an empty line.
> So the column of the cursor (2) looks wrong I think.
>
> When stepping into del_char(TRUE) at line 6440, I see that del_bytes()
> always returns FAIL at misc1.c:2213:
>
> #0 del_bytes (count=1, fixpos_arg=1, use_delcombine=1) at misc1.c:2213
> #1 0x00000000004cd622 in del_chars (count=1, fixpos=1) at misc1.c:2180
> #2 0x00000000004cd58c in del_char (fixpos=1) at misc1.c:2153
> #3 0x000000000042a7c9 in stop_insert (end_insert_pos=0x83b870, esc=1)
> at edit.c:6440
> #4 0x000000000042c968 in ins_esc (count=0x7fff8c049c68, cmdchar=65,
> nomove=0) at edit.c:7954
> #5 0x0000000000421a86 in edit (cmdchar=65, startln=0, count=-1) at edit.c:927
> #6 0x00000000004f66f4 in invoke_edit (cap=0x7fff8c049db0, repl=0,
> cmd=65, startln=0) at normal.c:8888
> #7 0x00000000004f6691 in nv_edit (cap=0x7fff8c049db0) at normal.c:8861
> #8 0x00000000004e946d in normal_cmd (oap=0x7fff8c049e80, toplevel=1)
> at normal.c:1189
> #9 0x00000000004a90a2 in main_loop (cmdwin=0, noexmode=0) at main.c:1180
> #10 0x00000000004a8be8 in main (argc=2, argv=0x7fff8c04a178) at main.c:939
>
>
> 2193 del_bytes(count, fixpos_arg, use_delcombine)
> 2194 long count;
> 2195 int fixpos_arg;
> 2196 int use_delcombine; /* 'delcombine' option applies */
> 2197 {
> 2198 char_u *oldp, *newp;
> 2199 colnr_T oldlen;
> 2200 linenr_T lnum = curwin->w_cursor.lnum;
> 2201 colnr_T col = curwin->w_cursor.col;
> 2202 int was_alloced;
> 2203 long movelen;
> 2204 int fixpos = fixpos_arg;
> 2205
> 2206 oldp = ml_get(lnum);
> 2207 oldlen = (int)STRLEN(oldp);
> 2208
> 2209 /*
> 2210 * Can't do anything when the cursor is on the NUL after the line.
> 2211 */
> 2212 if (col >= oldlen)
> 2213†> return FAIL;
>
> (gdb) p col
> $34 = 2
> (gdb) p oldlen
> $35 = 0
>
> (gdb) p oldp
> $36 = (char_u *) 0x8f59a7 ""
> (gdb) p lnum
> $37 = 133
>
> I also see the following thing which is probably wrong in this stack trace:
>
> (gdb) bt
> #0 ml_get_buf (buf=0x83d0b0, lnum=133, will_change=0) at memline.c:2143
> #1 0x00000000004ba367 in ml_get_cursor () at memline.c:2064
> #2 0x00000000004cdaac in gchar_cursor () at misc1.c:2394
> #3 0x000000000042a789 in stop_insert (end_insert_pos=0x83b870, esc=1)
> at edit.c:6435
> #4 0x000000000042c968 in ins_esc (count=0x7fff8c049c68, cmdchar=65,
> nomove=0) at edit.c:7954
> #5 0x0000000000421a86 in edit (cmdchar=65, startln=0, count=-1) at edit.c:927
> #6 0x00000000004f66f4 in invoke_edit (cap=0x7fff8c049db0, repl=0,
> cmd=65, startln=0) at normal.c:8888
> #7 0x00000000004f6691 in nv_edit (cap=0x7fff8c049db0) at normal.c:8861
> #8 0x00000000004e946d in normal_cmd (oap=0x7fff8c049e80, toplevel=1)
> at normal.c:1189
> #9 0x00000000004a90a2 in main_loop (cmdwin=0, noexmode=0) at main.c:1180
> #10 0x00000000004a8be8 in main (argc=2, argv=0x7fff8c04a178) at main.c:939
>
> 2058 /*
> 2059 * ml_get_cursor: get pointer to cursor position
> 2060 */
> 2061 char_u *
> 2062 ml_get_cursor()
> 2063 {
> 2064 return (ml_get_buf(curbuf, curwin->w_cursor.lnum, FALSE) +
> 2065
> curwin->w_cursor.col);
> 2066†>}
>
> At line 2064, ml_get_buf(...) returns an empty string "" (consistent
> with the fact that my file has an empty line at line 133) but
> curwin->w_cursor.col
> is 2 which looks wrong. Adding 2 to the empty string goes beyond the
> end of string.
> So it seems that curwin->w_cursor.col is incorrect.
>
> ml_get_cursor() ends up returning 32 in this case:
>
> (gdb) p buf->b_ml.ml_line_ptr
> $49 = (char_u *) 0x8f59a7 ""
>
> (gdb) p ((char_u *) 0x8f59a7)[2]
> $50 = 32 ' '
>
> Since getchar_cursor() at edit.c:6435 returns 32, lines edit.c:6436 is
> never executed so curwin->w_cursor.col is never decremented and remains 2
> all the time.
>
> I suspect that code should check the return code of del_char(TRUE)
> at edit.c:6440 and break from the loop if it fails to avoid
> an infinite loop. But I think that would only be working around
> the real bug: curwin->w_cursor.col being incorrect.
>
> Since I don't know how to systematically reproduce this bug, it's
> hard to experiment to see how to fix it. Hopefully the above
> information might be enough to figure it out. Sorry, no patch for
> this yet.
We can use the return value of del_char() to break the loop. But I
wonder how the cursor ever ended up pointing beyond the end of the line.
I suppose some auto-indenting was done, which the loop is supposed to
remove. Either something happened in between the auto-indenting and
setting end_insert_pos, or there never was any auto-indenting.
--
ARTHUR: Listen, old crone! Unless you tell us where we can buy a shrubbery,
my friend and I will ... we will say "Ni!"
CRONE: Do your worst!
"Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD
/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ download, build and distribute -- http://www.A-A-P.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_dev" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---