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
-~----------~----~----~----~------~----~------~--~---

Raspunde prin e-mail lui