Bram Moolenaar wrote: > Yukihiro Nakadaira wrote: > >> When using %! item in 'statusline' option, Vim sometimes shows an error >> and sometimes crash. >> >> vimrc.vim: >> set statusline=%!MyStatusLine() >> set laststatus=2 >> function MyStatusLine() >> return "" >> endfunction >> >> $ gvim -u vimrc.vim >> Error detected while processing function MyStatusLine: >> E121: Undefined variable: MyStatusLine >> Error detected while processing function MyStatusLine: >> E15: Invalid expression: MyStatusLine >> E15: Invalid expression: ~W^Iá3~L (message is random text) >> >> I am using GTK2 GUI. I saw the error at startup and when using >> scrollbar. >> >> The error can be reproduced by using :redraw! command in MyStatusLine(). >> >> function MyStatusLine() >> redraw! >> return "" >> endfunction >> >> >> It seems that: >> >> 1. build_stl_str_hl() >> w_p_stl is "%!MyStatusLine()". >> >> 2. eval_to_string() >> Evaluate "MyStatusLine()". >> >> 3. call_func() >> 8021 cc = name[len]; >> 8022 name[len] = NUL; >> At this time, name == w_p_stl + 2. >> Then w_p_stl is changed from "%!MyStatusLine()" to "%!MyStatusLine" >> >> 4. call_user_func() >> In this function, line_breakcheck() is invoked. Then Vim processes >> the GUI event loop. If there is an event which is cause of drawing, >> Vim draws statusline again. >> >> 5. build_stl_str_hl() >> At this time, w_p_stl is "%!MyStatusLine" by 3. call_func(). >> >> 6. eval_to_string() >> Evaluate "MyStatusLine" >> >> 7. get_var_tv() >> Echo error "E121: Undefined variable: MyStatusLine" >> >> 8. eval0() >> Echo error "E15: Invalid expression: MyStatusLine" >> >> 9. redraw_custum_statusline() >> 5907 if (called_emsg) >> 5908 set_string_option_direct((char_u *)"statusline", -1, >> 5909 (char_u *)"", OPT_FREE | (*wp->w_p_stl != NUL >> 5910 ? OPT_LOCAL : >> OPT_GLOBAL), SID_ERROR); >> Since error is raised, w_p_stl is freed. >> >> (back to first statusline drawing) >> >> 10. eval0() >> 3924 if (!aborting()) >> 3925 EMSG2(_(e_invexpr2), arg); >> Echo error "E15: Invalid expression: ~W^Iá3~L" >> At this time, arg == w_p_stl + 2. >> And w_p_stl is already freed. > > I can't reproduce it right away, but your explanation shows what is > wrong. I'll add it to the todo list.
If that helps to understand the problem and to reproduce it, this is what Valgrind shows when doing... $ cd vim7/src $ cat vimrc.vim set statusline=%!MyStatusLine() set laststatus=2 function MyStatusLine() redraw! return "" endfunction $ valgrind ./vim -u NONE -c ':so vimrc.vim' 2> vg.log ==7246== Invalid write of size 1 ==7246== at 0x807CF67: call_func (eval.c:8193) ==7246== by 0x807C9FE: get_func_tv (eval.c:7961) ==7246== by 0x8078D96: eval7 (eval.c:5013) ==7246== by 0x807869F: eval6 (eval.c:4680) ==7246== by 0x807828B: eval5 (eval.c:4496) ==7246== by 0x80777DC: eval4 (eval.c:4191) ==7246== by 0x8077634: eval3 (eval.c:4103) ==7246== by 0x80774C0: eval2 (eval.c:4032) ==7246== by 0x80772F0: eval1 (eval.c:3957) ==7246== by 0x8077257: eval0 (eval.c:3914) ==7246== by 0x8072E5C: eval_to_string (eval.c:1296) ==7246== by 0x8072FA1: eval_to_string_safe (eval.c:1340) ==7246== by 0x8058240: build_stl_str_hl (buffer.c:3415) ==7246== by 0x816DFFC: win_redr_custom (screen.c:6101) ==7246== by 0x816DAB4: redraw_custum_statusline (screen.c:5906) ==7246== by 0x8173480: showruler (screen.c:9468) ==7246== by 0x80E7AC8: main_loop (main.c:1147) ==7246== by 0x80E769A: main (main.c:942) ==7246== Address 0x54c12f2 is 18 bytes inside a block of size 21 free'd ==7246== at 0x4024E5A: free (vg_replace_malloc.c:323) ==7246== by 0x81160E0: vim_free (misc2.c:1642) ==7246== by 0x8140852: free_string_option (option.c:5207) ==7246== by 0x8140B5F: set_string_option_direct (option.c:5360) ==7246== by 0x816DB0A: redraw_custum_statusline (screen.c:5908) ==7246== by 0x816D60A: win_redr_status (screen.c:5775) ==7246== by 0x8164051: update_screen (screen.c:529) ==7246== by 0x80B0681: ex_redraw (ex_docmd.c:8600) ==7246== by 0x80A7494: do_one_cmd (ex_docmd.c:2629) ==7246== by 0x80A4CCB: do_cmdline (ex_docmd.c:1098) ==7246== by 0x8090C5B: call_user_func (eval.c:21284) ==7246== by 0x807CDBA: call_func (eval.c:8115) ==7246== by 0x807C9FE: get_func_tv (eval.c:7961) ==7246== by 0x8078D96: eval7 (eval.c:5013) ==7246== by 0x807869F: eval6 (eval.c:4680) ==7246== by 0x807828B: eval5 (eval.c:4496) ==7246== by 0x80777DC: eval4 (eval.c:4191) ==7246== by 0x8077634: eval3 (eval.c:4103) ==7246== by 0x80774C0: eval2 (eval.c:4032) ==7246== by 0x80772F0: eval1 (eval.c:3957) ==7246== by 0x8077257: eval0 (eval.c:3914) ==7246== by 0x8072E5C: eval_to_string (eval.c:1296) ==7246== by 0x8072FA1: eval_to_string_safe (eval.c:1340) ==7246== by 0x8058240: build_stl_str_hl (buffer.c:3415) ==7246== by 0x816DFFC: win_redr_custom (screen.c:6101) ==7246== by 0x816DAB4: redraw_custum_statusline (screen.c:5906) ==7246== by 0x8173480: showruler (screen.c:9468) ==7246== by 0x80E7AC8: main_loop (main.c:1147) ==7246== by 0x80E769A: main (main.c:942) (and more errors after that) Notice that in the stack, function redraw_custom_statusline() is called recursively (patch in my previous message fixed it). Cheers -- Dominique --~--~---------~--~----~------------~-------~--~----~ You received this message from the "vim_dev" maillist. For more information, visit http://www.vim.org/maillist.php -~----------~----~----~----~------~----~------~--~---