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

Re: %! item in 'statusline' option causes an error.

Expand Messages
  • Dominique Pellé
    ... Hi I can reproduce the crash too with the redraw! inside the MyStatusLine() function as you describe. The attached patch fixes it for me but please verify
    Message 1 of 6 , Nov 2, 2009
    • 0 Attachment
      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

      Hi

      I can reproduce the crash too with the redraw! inside the
      MyStatusLine() function as you describe.

      The attached patch fixes it for me but please verify it and review it.
      Patch prevents recursive call of redraw_custum_statusline().

      Regards
      -- Dominique

      --~--~---------~--~----~------------~-------~--~----~
      You received this message from the "vim_dev" maillist.
      For more information, visit http://www.vim.org/maillist.php
      -~----------~----~----~----~------~----~------~--~---
    • Bram Moolenaar
      ... I can t reproduce it right away, but your explanation shows what is wrong. I ll add it to the todo list. -- ARTHUR: But if he was dying, he
      Message 2 of 6 , Nov 2, 2009
      • 0 Attachment
        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.

        --
        ARTHUR: But if he was dying, he wouldn't bother to carve
        "Aaaaarrrrrrggghhh". He'd just say it.
        BROTHER MAYNARD: It's down there carved in stone.
        GALAHAD: Perhaps he was dictating.
        "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD

        /// Bram Moolenaar -- Bram@... -- http://www.Moolenaar.net \\\
        /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
        \\\ download, build and distribute -- http://www.A-A-P.org ///
        \\\ help me help AIDS victims -- http://ICCF-Holland.org ///

        --~--~---------~--~----~------------~-------~--~----~
        You received this message from the "vim_dev" maillist.
        For more information, visit http://www.vim.org/maillist.php
        -~----------~----~----~----~------~----~------~--~---
      • Dominique Pellé
        ... 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
        Message 3 of 6 , Nov 2, 2009
        • 0 Attachment
          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
          -~----------~----~----~----~------~----~------~--~---
        • Yukihiro Nakadaira
          ... Thank you. I cannot see error with your patch. Although this is minor problem, I got double statusline like the following. ... +-------------------------+
          Message 4 of 6 , Nov 3, 2009
          • 0 Attachment
            Dominique Pellé wrote:
            > I can reproduce the crash too with the redraw! inside the
            > MyStatusLine() function as you describe.
            >
            > The attached patch fixes it for me but please verify it and review it.
            > Patch prevents recursive call of redraw_custum_statusline().

            Thank you. I cannot see error with your patch.

            Although this is minor problem, I got double statusline like the
            following.

            |~ |
            |~ |
            |[No Name] ... |
            |[No Name] ... |
            +-------------------------+

            After CTRL-L, statusline is displayed normally.


            --
            Yukihiro Nakadaira - yukihiro.nakadaira@...


            --~--~---------~--~----~------------~-------~--~----~
            You received this message from the "vim_dev" maillist.
            For more information, visit http://www.vim.org/maillist.php
            -~----------~----~----~----~------~----~------~--~---
          • Yukihiro Nakadaira
            ... Actually this script cannot reproduce an error. More lines are required. set statusline=%!MyStatusLine() set laststatus=2 function MyStatusLine() return
            Message 5 of 6 , Nov 3, 2009
            • 0 Attachment
              > set statusline=%!MyStatusLine()
              > set laststatus=2
              > function MyStatusLine()
              > return ""
              > endfunction

              Actually this script cannot reproduce an error. More lines are
              required.

              set statusline=%!MyStatusLine()
              set laststatus=2
              function MyStatusLine()
              return ""
              endfunction

              " count up breakcheck_count of misc1.c
              call substitute('x', 'x', 'x', '')
              call substitute('x', 'x', 'x', '')
              call substitute('x', 'x', 'x', '')
              ...
              ... depends on compiler flag or locale or something.

              And when this line is executed
              main.c:main_loop()
              1147 showruler(FALSE);
              breakcheck_count must be "breakcheck_count >= BREAKCHECK_SKIP - 1".

              And run vim many times.

              for i in 1 2 3 4 5 6 7 8 9 10; do
              ./vim -u NONE -S vimrc.vim -g
              done

              One of them might show an error.


              --
              Yukihiro Nakadaira - yukihiro.nakadaira@...



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