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

Re: Crash with completefunc mapping followed by text

Expand Messages
  • Dominique Pellé
    ... Hi I can still reproduce the bug with latest Vim-7.2.222. However, I have not found the way to fix it. I can see that function ins_compl_free() frees
    Message 1 of 4 , Jul 3, 2009
    • 0 Attachment
      Dominique Pellé wrote:

      > Ingo Karkat wrote:
      >
      >> Hello Vim developers,
      >>
      >> I've written a user defined completion (via 'completefunc') that uses
      >>     normal y{motion}
      >> to capture the completion matches. (I have some other completions that can use
      >> getline() to extract the text; in those, the crash doesn't happen.)
      >> If I use a straightforward mapping like
      >>     inoremap ... <C-o>:set completefunc=<SID>MotionComplete<CR><C-x><C-u>
      >> to trigger the completion, everything is working fine. I've now appended some
      >> <C-r>=pumvisible() ? "\<lt>Down>" : ""<CR> fragment to modify the popup menu
      >> selection, and now observe Vim crashes whenever I invoke the augmented mapping.
      >> In fact, any text after the <C-x><C-u> causes buffer corruptions and eventual
      >> crashes.
      >>
      >> I've whittled down my completion script to the attached version. With that, I
      >> can reproduce crashes on the default (G)VIM 7.1 and 7.2 on Windows XP (but not
      >> with 7.0, which works fine), and with the latest Vim 7.2.197 (Big version with
      >> GTK2 GUI) on Ubuntu 8.04.
      >>
      >> To reproduce (the completion is mapped to <F11>):
      >>     vim -N -u NONE -n -S CompleteAndTextMappingCrash.vim
      >>     ifoobar<CR>
      >>     foo<F11><CR> " No crash yet, but the '+' char after the mapping is lost
      >>     foo<F11>
      >>     Vim: Caught deadly signal SEGV
      >>     Vim: Finished.
      >>     Segmentation fault
      >>
      >> You can check the original, correct behavior with:
      >>     vim -N -u NONE -n --cmd 'let nobug=1' -S CompleteAndTextMappingCrash.vim
      >>
      >> Please let me know if you need any additional information.
      >>
      >> -- regards, ingo
      >
      >
      > I can reproduce the crash you describe with latest Vim-7.2.197 (huge)
      > on Linux x86 (Ubuntu-8.10).
      >
      > Valgrind memory checker also indicates that freed memory is
      > being used and it happens right after typing foo<F11> the
      > second time:
      >
      > ==4309== Invalid read of size 4
      > ==4309==    at 0x808C5F4: ins_compl_next (edit.c:4395)
      > ==4309==    by 0x808CAE1: ins_compl_check_keys (edit.c:4592)
      > ==4309==    by 0x809FF05: f_complete_check (eval.c:9013)
      > ==4309==    by 0x809ED76: call_func (eval.c:8144)
      > ==4309==    by 0x809E8B8: get_func_tv (eval.c:7961)
      > ==4309==    by 0x809AC42: eval7 (eval.c:5013)
      > ==4309==    by 0x809A54B: eval6 (eval.c:4680)
      > ==4309==    by 0x809A137: eval5 (eval.c:4496)
      > ==4309==    by 0x8099688: eval4 (eval.c:4191)
      > ==4309==    by 0x80994E0: eval3 (eval.c:4103)
      > ==4309==    by 0x809936C: eval2 (eval.c:4032)
      > ==4309==    by 0x809919C: eval1 (eval.c:3957)
      > ==4309==    by 0x8099103: eval0 (eval.c:3914)
      > ==4309==    by 0x8094BAA: eval_to_bool (eval.c:1217)
      > ==4309==    by 0x80D7BBF: ex_while (ex_eval.c:1063)
      > ==4309==    by 0x80C9323: do_one_cmd (ex_docmd.c:2620)
      > ==4309==    by 0x80C6BBF: do_cmdline (ex_docmd.c:1096)
      > ==4309==    by 0x80B2AB6: call_user_func (eval.c:21259)
      > ==4309==    by 0x809EC74: call_func (eval.c:8115)
      > ==4309==    by 0x809E8B8: get_func_tv (eval.c:7961)
      > ==4309==    by 0x80982AB: ex_call (eval.c:3337)
      > ==4309==    by 0x80C9323: do_one_cmd (ex_docmd.c:2620)
      > ==4309==    by 0x80C6BBF: do_cmdline (ex_docmd.c:1096)
      > ==4309==    by 0x80B2AB6: call_user_func (eval.c:21259)
      > ==4309==    by 0x809EC74: call_func (eval.c:8115)
      > ==4309==    by 0x809538D: call_vim_function (eval.c:1557)
      > ==4309==    by 0x80954D3: call_func_retlist (eval.c:1637)
      > ==4309==    by 0x808B1F0: expand_by_function (edit.c:3788)
      > ==4309==    by 0x808BCAE: ins_compl_get_exp (edit.c:4083)
      > ==4309==    by 0x808C71F: ins_compl_next (edit.c:4432)
      > ==4309==    by 0x808D9AF: ins_complete (edit.c:5063)
      > ==4309==    by 0x808782F: edit (edit.c:1343)
      > ==4309==    by 0x8146B4D: normal_cmd (normal.c:1367)
      > ==4309==    by 0x81092E2: main_loop (main.c:1186)
      > ==4309==    by 0x81FE7AF: mzscheme_env_main (if_mzsch.c:845)
      > ==4309==    by 0x81FE784: mzscheme_main (if_mzsch.c:809)
      > ==4309==    by 0x8108E2F: main (main.c:944)
      > ==4309==  Address 0x5b36a8c is 4 bytes inside a block of size 48 free'd
      > ==4309==    at 0x4024E5A: free (vg_replace_malloc.c:323)
      > ==4309==    by 0x81379C7: vim_free (misc2.c:1639)
      > ==4309==    by 0x808A441: ins_compl_free (edit.c:3172)
      > ==4309==    by 0x808AFB7: ins_compl_prep (edit.c:3685)
      > ==4309==    by 0x808692B: edit (edit.c:785)
      > ==4309==    by 0x8157D2B: op_change (ops.c:2654)
      > ==4309==    by 0x8147D12: do_pending_operator (normal.c:1953)
      > ==4309==    by 0x8146812: normal_cmd (normal.c:1214)
      > ==4309==    by 0x80D33B5: exec_normal_cmd (ex_docmd.c:9180)
      > ==4309==    by 0x80D3205: ex_normal (ex_docmd.c:9079)
      > ==4309==    by 0x80C9323: do_one_cmd (ex_docmd.c:2620)
      > ==4309==    by 0x80C6BBF: do_cmdline (ex_docmd.c:1096)
      > ==4309==    by 0x80AF193: ex_execute (eval.c:19552)
      > ==4309==    by 0x80C9323: do_one_cmd (ex_docmd.c:2620)
      > ==4309==    by 0x80C6BBF: do_cmdline (ex_docmd.c:1096)
      > ==4309==    by 0x80B2AB6: call_user_func (eval.c:21259)
      > ==4309==    by 0x809EC74: call_func (eval.c:8115)
      > ==4309==    by 0x809E8B8: get_func_tv (eval.c:7961)
      > ==4309==    by 0x80AD4B4: handle_subscript (eval.c:18367)
      > ==4309==    by 0x809ACE8: eval7 (eval.c:5041)
      > ==4309==    by 0x809A54B: eval6 (eval.c:4680)
      > ==4309==    by 0x809A137: eval5 (eval.c:4496)
      > ==4309==    by 0x8099688: eval4 (eval.c:4191)
      > ==4309==    by 0x80994E0: eval3 (eval.c:4103)
      > ==4309==    by 0x809936C: eval2 (eval.c:4032)
      > ==4309==    by 0x809919C: eval1 (eval.c:3957)
      > ==4309==    by 0x8099103: eval0 (eval.c:3914)
      > ==4309==    by 0x8095914: ex_let (eval.c:1829)
      > ==4309==    by 0x80C9323: do_one_cmd (ex_docmd.c:2620)
      > ==4309==    by 0x80C6BBF: do_cmdline (ex_docmd.c:1096)
      > ==4309==    by 0x80B2AB6: call_user_func (eval.c:21259)
      > ==4309==    by 0x809EC74: call_func (eval.c:8115)
      > ==4309==    by 0x809E8B8: get_func_tv (eval.c:7961)
      > ==4309==    by 0x80982AB: ex_call (eval.c:3337)
      > ==4309==    by 0x80C9323: do_one_cmd (ex_docmd.c:2620)
      > ==4309==    by 0x80C6BBF: do_cmdline (ex_docmd.c:1096)
      > ==4309==    by 0x80B2AB6: call_user_func (eval.c:21259)
      > ==4309==    by 0x809EC74: call_func (eval.c:8115)
      > ==4309==    by 0x809538D: call_vim_function (eval.c:1557)
      > ==4309==    by 0x80954D3: call_func_retlist (eval.c:1637)
      > ==4309==    by 0x808B1F0: expand_by_function (edit.c:3788)
      > ==4309==    by 0x808BCAE: ins_compl_get_exp (edit.c:4083)
      > ==4309==    by 0x808C71F: ins_compl_next (edit.c:4432)
      > ==4309==    by 0x808D9AF: ins_complete (edit.c:5063)
      > ==4309==    by 0x808782F: edit (edit.c:1343)
      > ==4309==    by 0x8146B4D: normal_cmd (normal.c:1367)
      > ==4309==    by 0x81092E2: main_loop (main.c:1186)
      > ==4309==    by 0x81FE7AF: mzscheme_env_main (if_mzsch.c:845)
      > ==4309==    by 0x81FE784: mzscheme_main (if_mzsch.c:809)
      > ==4309==    by 0x8108E2F: main (main.c:944)
      > ==4309==
      > ==4309== Invalid read of size 4
      > ==4309==    at 0x808C5F4: ins_compl_next (edit.c:4395)
      > ==4309==    by 0x808CAE1: ins_compl_check_keys (edit.c:4592)
      > ==4309==    by 0x808C2A6: ins_compl_get_exp (edit.c:4255)
      > ==4309==    by 0x808C71F: ins_compl_next (edit.c:4432)
      > ==4309==    by 0x808D9AF: ins_complete (edit.c:5063)
      > ==4309==    by 0x808782F: edit (edit.c:1343)
      > ==4309==    by 0x8146B4D: normal_cmd (normal.c:1367)
      > ==4309==    by 0x81092E2: main_loop (main.c:1186)
      > ==4309==    by 0x81FE7AF: mzscheme_env_main (if_mzsch.c:845)
      > ==4309==    by 0x81FE784: mzscheme_main (if_mzsch.c:809)
      > ==4309==    by 0x8108E2F: main (main.c:944)
      > ==4309==  Address 0x5b36a8c is 4 bytes inside a block of size 48 free'd
      > ==4309==    at 0x4024E5A: free (vg_replace_malloc.c:323)
      > ==4309==    by 0x81379C7: vim_free (misc2.c:1639)
      > ==4309==    by 0x808A441: ins_compl_free (edit.c:3172)
      > ==4309==    by 0x808AFB7: ins_compl_prep (edit.c:3685)
      > ==4309==    by 0x808692B: edit (edit.c:785)
      > ==4309==    by 0x8157D2B: op_change (ops.c:2654)
      > ==4309==    by 0x8147D12: do_pending_operator (normal.c:1953)
      > ==4309==    by 0x8146812: normal_cmd (normal.c:1214)
      > ==4309==    by 0x80D33B5: exec_normal_cmd (ex_docmd.c:9180)
      > ==4309==    by 0x80D3205: ex_normal (ex_docmd.c:9079)
      > ==4309==    by 0x80C9323: do_one_cmd (ex_docmd.c:2620)
      > ==4309==    by 0x80C6BBF: do_cmdline (ex_docmd.c:1096)
      > ==4309==    by 0x80AF193: ex_execute (eval.c:19552)
      > ==4309==    by 0x80C9323: do_one_cmd (ex_docmd.c:2620)
      > ==4309==    by 0x80C6BBF: do_cmdline (ex_docmd.c:1096)
      > ==4309==    by 0x80B2AB6: call_user_func (eval.c:21259)
      > ==4309==    by 0x809EC74: call_func (eval.c:8115)
      > ==4309==    by 0x809E8B8: get_func_tv (eval.c:7961)
      > ==4309==    by 0x80AD4B4: handle_subscript (eval.c:18367)
      > ==4309==    by 0x809ACE8: eval7 (eval.c:5041)
      > ==4309==    by 0x809A54B: eval6 (eval.c:4680)
      > ==4309==    by 0x809A137: eval5 (eval.c:4496)
      > ==4309==    by 0x8099688: eval4 (eval.c:4191)
      > ==4309==    by 0x80994E0: eval3 (eval.c:4103)
      > ==4309==    by 0x809936C: eval2 (eval.c:4032)
      > ==4309==    by 0x809919C: eval1 (eval.c:3957)
      > ==4309==    by 0x8099103: eval0 (eval.c:3914)
      > ==4309==    by 0x8095914: ex_let (eval.c:1829)
      > ==4309==    by 0x80C9323: do_one_cmd (ex_docmd.c:2620)
      > ==4309==    by 0x80C6BBF: do_cmdline (ex_docmd.c:1096)
      > ==4309==    by 0x80B2AB6: call_user_func (eval.c:21259)
      > ==4309==    by 0x809EC74: call_func (eval.c:8115)
      > ==4309==    by 0x809E8B8: get_func_tv (eval.c:7961)
      > ==4309==    by 0x80982AB: ex_call (eval.c:3337)
      > ==4309==    by 0x80C9323: do_one_cmd (ex_docmd.c:2620)
      > ==4309==    by 0x80C6BBF: do_cmdline (ex_docmd.c:1096)
      > ==4309==    by 0x80B2AB6: call_user_func (eval.c:21259)
      > ==4309==    by 0x809EC74: call_func (eval.c:8115)
      > ==4309==    by 0x809538D: call_vim_function (eval.c:1557)
      > ==4309==    by 0x80954D3: call_func_retlist (eval.c:1637)
      > ==4309==    by 0x808B1F0: expand_by_function (edit.c:3788)
      > ==4309==    by 0x808BCAE: ins_compl_get_exp (edit.c:4083)
      > ==4309==    by 0x808C71F: ins_compl_next (edit.c:4432)
      > ==4309==    by 0x808D9AF: ins_complete (edit.c:5063)
      > ==4309==    by 0x808782F: edit (edit.c:1343)
      > ==4309==    by 0x8146B4D: normal_cmd (normal.c:1367)
      > ==4309==    by 0x81092E2: main_loop (main.c:1186)
      > ==4309==    by 0x81FE7AF: mzscheme_env_main (if_mzsch.c:845)
      > ==4309==    by 0x81FE784: mzscheme_main (if_mzsch.c:809)
      > ==4309==    by 0x8108E2F: main (main.c:944)
      >
      > I should find time to try to debug it this weekend.
      >
      > Cheers
      > -- Dominique
      >

      Hi

      I can still reproduce the bug with latest Vim-7.2.222. However, I have
      not found the way to fix it.

      I can see that function ins_compl_free() frees 'compl_shown_match'
      when doing vim_free(match); at line edit.c:3172. And freed memory
      'compl_shown_match' is then later still used in ins_compl_next().

      3161 compl_curr_match = compl_first_match;
      3162 do
      3163 {
      3164 match = compl_curr_match;
      3165 compl_curr_match = compl_curr_match->cp_next;
      3166 vim_free(match->cp_str);
      3167 /* several entries may use the same fname, free it just once. */
      3168 if (match->cp_flags & FREE_FNAME)
      3169 vim_free(match->cp_fname);
      3170 for (i = 0; i < CPT_COUNT; ++i)
      3171 vim_free(match->cp_text[i]);
      3172 vim_free(match); !!!!!! can free compl_shown_match !!!!!!
      3173 } while (compl_curr_match != NULL && compl_curr_match !=
      compl_first_match);
      3174 compl_first_match = compl_curr_match = NULL;


      Since ins_compl_free() can free compl_shown_match, it's probably
      better to assign NULL to compl_shown_match when that happens
      as follows. However, that does not fix the bug.

      $ cvs diff -c edit.c
      Index: edit.c
      ===================================================================
      RCS file: /cvsroot/vim/vim7/src/edit.c,v
      retrieving revision 1.150
      diff -c -r1.150 edit.c
      *** edit.c 26 May 2009 09:02:10 -0000 1.150
      --- edit.c 14 Jun 2009 20:26:00 -0000
      ***************
      *** 3170,3175 ****
      --- 3170,3177 ----
      for (i = 0; i < CPT_COUNT; ++i)
      vim_free(match->cp_text[i]);
      vim_free(match);
      + if (match == compl_shown_match)
      + compl_shown_match = NULL;
      } while (compl_curr_match != NULL && compl_curr_match !=
      compl_first_match);
      compl_first_match = compl_curr_match = NULL;
      }


      How to fix it is unclear to me.

      Regards
      -- Dominique

      PS: I've written a page to describe how to use Valgrind to debug Vim:

      http://dominique.pelle.free.fr/valgrind.txt.html
      http://dominique.pelle.free.fr/valgrind.txt

      --~--~---------~--~----~------------~-------~--~----~
      You received this message from the "vim_dev" maillist.
      For more information, visit http://www.vim.org/maillist.php
      -~----------~----~----~----~------~----~------~--~---
    Your message has been successfully submitted and would be delivered to recipients shortly.