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

Raspunde prin e-mail lui