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