Loading ...
Sorry, an error occurred while loading the content.
 

Re: [bug] Vim-7.3a crashes with persistent undo and autocmd FileChangedRO

Expand Messages
  • Bram Moolenaar
    ... Was this actually changed during the recent undo feature changes? No, Vim 7.2 has the same code. Thus it s actually an old problem. -- Did you hear about
    Message 1 of 3 , Jul 1, 2010
      Dominique Pelle wrote:

      > Vim-7.3a (2278:e41433ea71df) crashed while I was using undo.
      > It happened when doing undo on a file which was read-only
      > in perforce (not checked-out). The Vim perforce plugin has
      > a FileChangedRO autocommand to automatically check-out
      > a file when attempting to change it. It causes a crash when
      > using persistent undo.
      >
      > I found a simpler way to reproduce it without using the perforce
      > Plugin. The following script is enough to cause Vim to crash:
      >
      > =========================================================
      > #!/bin/sh
      >
      > cd /tmp
      > rm -f foobar foobar.undo
      > vim -u NONE -N foobar \
      > -c ':call feedkeys("aFOO\<Esc>:wundo! foobar.undo\<CR>:wq\<CR>")'
      > chmod a-w foobar
      >
      > # Vim-7.3a (2278:e41433ea71df) will crash here.
      > vim -u NONE -N foobar \
      > -c 'au FileChangedRO * :e!' \
      > -c 'rundo foobar.undo' \
      > -c 'undo'
      > =========================================================
      >
      > Valgrind gives the following error (in the 2nd invocation of Vim):
      >
      > ==2892== Invalid read of size 4
      > ==2892== at 0x81C2FC1: u_freeentry (undo.c:3063)
      > ==2892== by 0x81C2F78: u_freeentries (undo.c:3044)
      > ==2892== by 0x81C2E55: u_freeheader (undo.c:2985)
      > ==2892== by 0x81C32E9: u_blockfree (undo.c:3173)
      > ==2892== by 0x8053C98: buf_freeall (buffer.c:579)
      > ==2892== by 0x8098C37: do_ecmd (ex_cmds.c:3573)
      > ==2892== by 0x80AF21E: do_exedit (ex_docmd.c:7626)
      > ==2892== by 0x80AEEDB: ex_edit (ex_docmd.c:7522)
      > ==2892== by 0x80A7AB8: do_one_cmd (ex_docmd.c:2640)
      > ==2892== by 0x80A5391: do_cmdline (ex_docmd.c:1109)
      > ==2892== by 0x80CE2CC: apply_autocmds_group (fileio.c:9334)
      > ==2892== by 0x80CDCDE: apply_autocmds (fileio.c:8943)
      > ==2892== by 0x810C467: change_warning (misc1.c:2995)
      > ==2892== by 0x810B78C: changed (misc1.c:2493)
      > ==2892== by 0x810BC8D: changed_common (misc1.c:2747)
      > ==2892== by 0x810BBA1: changed_lines (misc1.c:2692)
      > ==2892== by 0x81C2082: u_undoredo (undo.c:2487)
      > ==2892== by 0x81C127B: u_doit (undo.c:1962)
      > ==2892== by 0x81C112F: u_undo (undo.c:1907)
      > ==2892== by 0x80B0594: ex_undo (ex_docmd.c:8466)
      > ==2892== by 0x80A7AB8: do_one_cmd (ex_docmd.c:2640)
      > ==2892== by 0x80A5391: do_cmdline (ex_docmd.c:1109)
      > ==2892== by 0x80A4A4B: do_cmdline_cmd (ex_docmd.c:715)
      > ==2892== by 0x80EA19E: exe_commands (main.c:2755)
      > ==2892== by 0x80E7955: main (main.c:880)
      > ==2892== Address 0x4fc017c is 4 bytes inside a block of size 8 free'd
      > ==2892== at 0x4024B8A: free (vg_replace_malloc.c:366)
      > ==2892== by 0x8116ED6: vim_free (misc2.c:1702)
      > ==2892== by 0x81C1F9F: u_undoredo (undo.c:2473)
      > ==2892== by 0x81C127B: u_doit (undo.c:1962)
      > ==2892== by 0x81C112F: u_undo (undo.c:1907)
      > ==2892== by 0x80B0594: ex_undo (ex_docmd.c:8466)
      > ==2892== by 0x80A7AB8: do_one_cmd (ex_docmd.c:2640)
      > ==2892== by 0x80A5391: do_cmdline (ex_docmd.c:1109)
      > ==2892== by 0x80A4A4B: do_cmdline_cmd (ex_docmd.c:715)
      > ==2892== by 0x80EA19E: exe_commands (main.c:2755)
      > ==2892== by 0x80E7955: main (main.c:880)
      > (several more errors after that)
      >
      > Source of src/undo.c:
      >
      > 2458 /* insert the lines in u_array between top and bot */
      > 2459 if (newsize)
      > 2460 {
      > 2461 for (lnum = top, i = 0; i < newsize; ++i, ++lnum)
      > 2462 {
      > 2463 /*
      > 2464 * If the file is empty, there is an empty line 1 that we
      > 2465 * should get rid of, by replacing it with the new line
      > 2466 */
      > 2467 if (empty_buffer && lnum == 0)
      > 2468 ml_replace((linenr_T)1, uep->ue_array[i], TRUE);
      > 2469 else
      > 2470 ml_append(lnum, uep->ue_array[i], (colnr_T)0, FALSE);
      > 2471 vim_free(uep->ue_array[i]);
      > 2472 }
      > 2473 vim_free((char_u *)uep->ue_array); <--- MEMORY IS FREED
      > 2474 }
      > 2475
      > 2476 /* adjust marks */
      > 2477 if (oldsize != newsize)
      > 2478 {
      > 2479 mark_adjust(top + 1, top + oldsize, (long)MAXLNUM,
      > 2480 (long)newsize - (long)oldsize);
      > 2481 if (curbuf->b_op_start.lnum > top + oldsize)
      > 2482 curbuf->b_op_start.lnum += newsize - oldsize;
      > 2483 if (curbuf->b_op_end.lnum > top + oldsize)
      > 2484 curbuf->b_op_end.lnum += newsize - oldsize;
      > 2485 }
      > 2486
      > 2487 changed_lines(top + 1, 0, bot, newsize - oldsize); <--- USE FREE MEM
      >
      > Not sure how to fix it yet,

      Was this actually changed during the recent undo feature changes?
      No, Vim 7.2 has the same code. Thus it's actually an old problem.

      --
      Did you hear about the new 3 million dollar West Virginia State Lottery?
      The winner gets 3 dollars a year for a million years.

      /// Bram Moolenaar -- Bram@... -- 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.
      Do not top-post! Type your reply below the text you are replying to.
      For more information, visit http://www.vim.org/maillist.php
    • Dominique Pellé
      ... You re right. I now see that it also happens with Vim-7.2.444. The way to reproduce it has to be different though. Following command crashes with both
      Message 2 of 3 , Jul 1, 2010
        Bram Moolenaar wrote:

        > Dominique Pelle wrote:
        >
        >> Vim-7.3a (2278:e41433ea71df) crashed while I was using undo.
        >> It happened when doing undo on a file which was read-only
        >> in perforce (not checked-out).  The Vim perforce plugin has
        >> a FileChangedRO autocommand to automatically check-out
        >> a file when attempting to change it. It causes a crash when
        >> using persistent undo.
        >>
        >> I found a simpler way to reproduce it without using the perforce
        >> Plugin. The following script is enough to cause Vim to crash:
        >>
        >> =========================================================
        >>  #!/bin/sh
        >>
        >> cd /tmp
        >> rm -f foobar foobar.undo
        >> vim -u NONE -N foobar \
        >>   -c ':call feedkeys("aFOO\<Esc>:wundo! foobar.undo\<CR>:wq\<CR>")'
        >> chmod a-w foobar
        >>
        >> # Vim-7.3a (2278:e41433ea71df) will crash here.
        >> vim -u NONE -N foobar \
        >>   -c 'au FileChangedRO * :e!' \
        >>   -c 'rundo foobar.undo' \
        >>   -c 'undo'
        >> =========================================================
        >>
        >> Valgrind gives the following error (in the 2nd invocation of Vim):
        >>
        >> ==2892== Invalid read of size 4
        >> ==2892==    at 0x81C2FC1: u_freeentry (undo.c:3063)
        >> ==2892==    by 0x81C2F78: u_freeentries (undo.c:3044)
        >> ==2892==    by 0x81C2E55: u_freeheader (undo.c:2985)
        >> ==2892==    by 0x81C32E9: u_blockfree (undo.c:3173)
        >> ==2892==    by 0x8053C98: buf_freeall (buffer.c:579)
        >> ==2892==    by 0x8098C37: do_ecmd (ex_cmds.c:3573)
        >> ==2892==    by 0x80AF21E: do_exedit (ex_docmd.c:7626)
        >> ==2892==    by 0x80AEEDB: ex_edit (ex_docmd.c:7522)
        >> ==2892==    by 0x80A7AB8: do_one_cmd (ex_docmd.c:2640)
        >> ==2892==    by 0x80A5391: do_cmdline (ex_docmd.c:1109)
        >> ==2892==    by 0x80CE2CC: apply_autocmds_group (fileio.c:9334)
        >> ==2892==    by 0x80CDCDE: apply_autocmds (fileio.c:8943)
        >> ==2892==    by 0x810C467: change_warning (misc1.c:2995)
        >> ==2892==    by 0x810B78C: changed (misc1.c:2493)
        >> ==2892==    by 0x810BC8D: changed_common (misc1.c:2747)
        >> ==2892==    by 0x810BBA1: changed_lines (misc1.c:2692)
        >> ==2892==    by 0x81C2082: u_undoredo (undo.c:2487)
        >> ==2892==    by 0x81C127B: u_doit (undo.c:1962)
        >> ==2892==    by 0x81C112F: u_undo (undo.c:1907)
        >> ==2892==    by 0x80B0594: ex_undo (ex_docmd.c:8466)
        >> ==2892==    by 0x80A7AB8: do_one_cmd (ex_docmd.c:2640)
        >> ==2892==    by 0x80A5391: do_cmdline (ex_docmd.c:1109)
        >> ==2892==    by 0x80A4A4B: do_cmdline_cmd (ex_docmd.c:715)
        >> ==2892==    by 0x80EA19E: exe_commands (main.c:2755)
        >> ==2892==    by 0x80E7955: main (main.c:880)
        >> ==2892==  Address 0x4fc017c is 4 bytes inside a block of size 8 free'd
        >> ==2892==    at 0x4024B8A: free (vg_replace_malloc.c:366)
        >> ==2892==    by 0x8116ED6: vim_free (misc2.c:1702)
        >> ==2892==    by 0x81C1F9F: u_undoredo (undo.c:2473)
        >> ==2892==    by 0x81C127B: u_doit (undo.c:1962)
        >> ==2892==    by 0x81C112F: u_undo (undo.c:1907)
        >> ==2892==    by 0x80B0594: ex_undo (ex_docmd.c:8466)
        >> ==2892==    by 0x80A7AB8: do_one_cmd (ex_docmd.c:2640)
        >> ==2892==    by 0x80A5391: do_cmdline (ex_docmd.c:1109)
        >> ==2892==    by 0x80A4A4B: do_cmdline_cmd (ex_docmd.c:715)
        >> ==2892==    by 0x80EA19E: exe_commands (main.c:2755)
        >> ==2892==    by 0x80E7955: main (main.c:880)
        >> (several more errors after that)
        >>
        >> Source of src/undo.c:
        >>
        >> 2458   /* insert the lines in u_array between top and bot */
        >> 2459   if (newsize)
        >> 2460   {
        >> 2461       for (lnum = top, i = 0; i < newsize; ++i, ++lnum)
        >> 2462       {
        >> 2463           /*
        >> 2464            * If the file is empty, there is an empty line 1 that we
        >> 2465            * should get rid of, by replacing it with the new line
        >> 2466            */
        >> 2467           if (empty_buffer && lnum == 0)
        >> 2468               ml_replace((linenr_T)1, uep->ue_array[i], TRUE);
        >> 2469           else
        >> 2470               ml_append(lnum, uep->ue_array[i], (colnr_T)0, FALSE);
        >> 2471           vim_free(uep->ue_array[i]);
        >> 2472       }
        >> 2473       vim_free((char_u *)uep->ue_array);  <--- MEMORY IS FREED
        >> 2474   }
        >> 2475
        >> 2476   /* adjust marks */
        >> 2477   if (oldsize != newsize)
        >> 2478   {
        >> 2479       mark_adjust(top + 1, top + oldsize, (long)MAXLNUM,
        >> 2480                                          (long)newsize - (long)oldsize);
        >> 2481       if (curbuf->b_op_start.lnum > top + oldsize)
        >> 2482           curbuf->b_op_start.lnum += newsize - oldsize;
        >> 2483       if (curbuf->b_op_end.lnum > top + oldsize)
        >> 2484           curbuf->b_op_end.lnum += newsize - oldsize;
        >> 2485   }
        >> 2486
        >> 2487   changed_lines(top + 1, 0, bot, newsize - oldsize); <--- USE FREE MEM
        >>
        >> Not sure how to fix it yet,
        >
        > Was this actually changed during the recent undo feature changes?
        > No, Vim 7.2 has the same code.  Thus it's actually an old problem.


        You're right. I now see that it also happens with Vim-7.2.444.
        The way to reproduce it has to be different though.
        Following command crashes with both Vim-7.2.444 and
        Vim-7.3a (2278:e41433ea71df):

        $ rm foobar .foobar* ; ./vim -u NONE -N foobar \
        -c 'au FileChangedRO * e!' \
        -c 'norm iFOO' \
        -c 'set ro' \
        -c 'undo|redo'
        Segmentation fault (core dumped)

        -- Dominique

        --
        You received this message from the "vim_dev" maillist.
        Do not top-post! Type your reply below the text you are replying to.
        For more information, visit http://www.vim.org/maillist.php
      Your message has been successfully submitted and would be delivered to recipients shortly.