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

RE: remote debugging ideas for vimscripts

Expand Messages
  • Michael Geddes
    This is getting a bit gnarly, so I ll let somebody who has had more experience with this area have a go. I ve found the basic reason for the problem, which is
    Message 1 of 5 , Jul 1, 2003
    • 0 Attachment
      This is getting a bit gnarly, so I'll let somebody who has had more
      experience with this area have a go.

      I've found the basic reason for the problem, which is that within
      do_debug, it is doing an 'inchar' passing a pointer indexing into the
      global typebuf.tb_buf ... the problem is then that when you send a
      message via remote_send, this calls 'server_to_input_buf' which calls
      'ins_typebuf' which frees the memory pointed to by typebuf.tb_buf.

      Then when the original gui_mch_wait_for_chars returns, the 'buf'
      pointer passed in is pointing at freed memory.

      I believe this bug could happen in the normal remote_send (not in
      debug), but in this case, it appears to always reach the 'simple' case
      where there is enough room in the type-ahead buffer.

      (Steps to reproduce are still the same as the original mail in this
      thread - the second case).

      //.



      ins_typebuf(unsigned char * 0x00c42008, int 0xffffffff, int 0x00000000,
      int 0x00000001, int 0x00000000) line 954
      server_to_input_buf(unsigned char * 0x00c42008) line 3031 + 17 bytes
      Messaging_WndProc(HWND__ * 0x00130e9a, unsigned int 0x0000004a, unsigned
      int 0x000b0d3a, long 0x0012ef0c) line 2304 + 12 bytes
      USER32! 77d43a68()
      USER32! 77d43b37()
      USER32! 77d4450d()
      USER32! 77d4c3a9()
      NTDLL! 77fb4da6()
      process_message() line 1466
      gui_mch_wait_for_chars(int 0xffffffff) line 1738
      gui_wait_for_chars(long 0xffffffff) line 2609 + 7 bytes
      ui_inchar(unsigned char * 0x00c422a0, int 0x00000058, long 0xffffffff)
      line 165 + 9 bytes
      inchar(unsigned char * 0x00c422a0, int 0x00000108, long 0xffffffff) line
      2663 + 25 bytes
      vgetorpeek(int 0x00000001) line 2464 + 179 bytes
      vgetc() line 1421 + 7 bytes
      safe_vgetc() line 1552 + 5 bytes
      getcmdline(int 0x0000003e, long 0x00000001, int 0x00000000) line 285 + 5
      bytes
      getcmdline_prompt(int 0x0000003e, unsigned char * 0x00000000, int
      0x00000000) line 1628 + 13 bytes
      do_debug(unsigned char * 0x00c43240) line 113 + 11 bytes
      dbg_check_breakpoint(exarg * 0x0012f4fc) line 297 + 12 bytes
      do_one_cmd(unsigned char * * 0x0012f608, int 0x00000001, condstack *
      0x0012f614, unsigned char * (int, void *, int)* 0x00000000, void *
      0x00000000) line 1483 + 9 bytes
      do_cmdline(unsigned char * 0x00c439ee, unsigned char * (int, void *,
      int)* 0x00000000, void * 0x00000000, int 0x0000000b) line 873 + 34 bytes
      do_cmdline_cmd(unsigned char * 0x00c439ee) line 548 + 15 bytes
      ex_debug(exarg * 0x0012f8bc) line 239 + 11 bytes

      -----Original Message-----
      From: Michael Geddes
      Sent: Wednesday, 2 July 2003 12:00 PM
      To: Hari Krishna Dara
      Cc: Vim-dev@...
      Subject: RE: remote debugging ideas for vimscripts


      Hari et al,

      I think the remote debugging idea is quite kool.. so I've done a bit of
      digging.

      As a start, I suggest that we turn off debug mode and redir_off at
      the start of the
      message handler for remote_expr() on the server and restore them at the
      end.

      In os_mswin.c.. this is done by adding the + lines in the code block
      below. This fixed problem number 1.. which is that the call doesn't
      return until you type 'cont' on the server. I've also checked that you
      can still :breakadd the function that is being called to allow debugging
      of remote calls.

      The second problem I haven't got much info on.. or time to do it.
      However running the debug version under msdev debugger, I'm seeing:

      HEAP[gvimd.exe]: HEAP: Free Heap block c41610 modified at c41638
      after it was freed

      on the server when you type

      :call remote_send('GVIMD', ":let @z=GetVimCmdOutput('ls')\<CR>")

      on the client vim... which isn't very promising. If I do get time I'll
      investigate!

      //.





      //.
      ----------8<---------------

      static LRESULT CALLBACK
      Messaging_WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
      if (msg == WM_COPYDATA)
      {
      /* This is a message from another Vim. The dwData member of the
      * COPYDATASTRUCT determines the type of message:
      * COPYDATA_KEYS:
      * A key sequence. We are a server, and a client wants
      these keys
      * adding to the input queue.
      * COPYDATA_REPLY:
      * A reply. We are a client, and a server has sent this
      message
      * in response to a request. (server2client())
      * COPYDATA_EXPR:
      * An expression. We are a server, and a client wants us to
      * evaluate this expression.
      * COPYDATA_RESULT:
      * A reply. We are a client, and a server has sent this
      message
      * in response to a COPYDATA_EXPR.
      * COPYDATA_ERROR_RESULT:
      * A reply. We are a client, and a server has sent this
      message
      * in response to a COPYDATA_EXPR that failed to evaluate.
      */
      COPYDATASTRUCT *data = (COPYDATASTRUCT*)lParam;
      HWND sender = (HWND)wParam;
      COPYDATASTRUCT reply;
      char_u *res;
      char_u winstr[30];
      int retval;
      + int debug_break_level_save = debug_break_level;
      + BOOL redir_off_save = redir_off;


      switch (data->dwData)
      {
      case COPYDATA_KEYS:
      /* Remember who sent this, for <client> */
      clientWindow = sender;

      /* Add the received keys to the input buffer. The loop
      waiting
      * for the user to do something should check the input
      buffer. */
      server_to_input_buf((char_u *)(data->lpData));

      # ifdef FEAT_GUI
      /* Wake up the main GUI loop. */
      if (s_hwnd != 0)
      PostMessage(s_hwnd, WM_NULL, 0, 0);
      # endif
      return 1;

      case COPYDATA_EXPR:
      /* Remember who sent this, for <client> */
      clientWindow = sender;

      ++emsg_skip;
      + debug_break_level = -1;
      + redir_off = 0;
      res = eval_to_string(data->lpData, NULL);
      + redir_off = redir_off_save;
      + debug_break_level = debug_break_level_save;
      --emsg_skip;
      if (res == NULL)
      {
      res = vim_strsave(_(e_invexprmsg));
      reply.dwData = COPYDATA_ERROR_RESULT;
      }
      else
      reply.dwData = COPYDATA_RESULT;
      reply.lpData = res;
      reply.cbData = STRLEN(res) + 1;

      retval = SendMessage(sender, WM_COPYDATA,
      (WPARAM)message_window,

      (LPARAM)(&reply));
      vim_free(res);
      return retval;

      case COPYDATA_REPLY:
      case COPYDATA_RESULT:
      case COPYDATA_ERROR_RESULT:
      if (data->lpData != NULL)
      {
      save_reply(sender, data->lpData,
      (data->dwData == COPYDATA_REPLY ? 0 :
      (data->dwData == COPYDATA_RESULT ? 1 :
      2)));
      #ifdef FEAT_AUTOCMD
      if (data->dwData == COPYDATA_REPLY)
      {
      sprintf((char *)winstr, "0x%x", (unsigned)sender);
      apply_autocmds(EVENT_REMOTEREPLY, winstr,
      data->lpData,
      TRUE,
      curbuf);
      }
      #endif
      }
      return 1;
      }

      return 0;
      }

      else if (msg == WM_ACTIVATE && wParam == WA_ACTIVE)
      {
      /* When the message window is activated (brought to the
      foreground),
      * this actually applies to the text window. */
      #ifndef FEAT_GUI
      GetConsoleHwnd(); /* get value of s_hwnd */
      #endif
      if (s_hwnd != 0)
      {
      SetForegroundWindow(s_hwnd);
      return 0;
      }
      }

      return DefWindowProc(hwnd, msg, wParam, lParam);
      }
    • Bram Moolenaar
      ... Thanks for figuring it out this far. It s really a problem of the event handling doing something unexpected. It is not obvious how this should be fixed.
      Message 2 of 5 , Jul 2, 2003
      • 0 Attachment
        Michael Geddes wrote:

        > This is getting a bit gnarly, so I'll let somebody who has had more
        > experience with this area have a go.
        >
        > I've found the basic reason for the problem, which is that within
        > do_debug, it is doing an 'inchar' passing a pointer indexing into the
        > global typebuf.tb_buf ... the problem is then that when you send a
        > message via remote_send, this calls 'server_to_input_buf' which calls
        > 'ins_typebuf' which frees the memory pointed to by typebuf.tb_buf.
        >
        > Then when the original gui_mch_wait_for_chars returns, the 'buf'
        > pointer passed in is pointing at freed memory.
        >
        > I believe this bug could happen in the normal remote_send (not in
        > debug), but in this case, it appears to always reach the 'simple' case
        > where there is enough room in the type-ahead buffer.
        >
        > (Steps to reproduce are still the same as the original mail in this
        > thread - the second case).

        Thanks for figuring it out this far. It's really a problem of the event
        handling doing something unexpected. It is not obvious how this should
        be fixed. I'll add a remark in the todo list.

        --
        Eight Megabytes And Continually Swapping.

        /// Bram Moolenaar -- Bram@... -- http://www.Moolenaar.net \\\
        /// Creator of Vim - Vi IMproved -- http://www.Vim.org \\\
        \\\ Project leader for A-A-P -- http://www.A-A-P.org ///
        \\\ Help AIDS victims, buy here: http://ICCF-Holland.org/click1.html ///
      • Bram Moolenaar
        ... That makes sense in most situations, but what if the user really wants to debug the commands being send remotely? -- The psychic said, God bless you. I
        Message 3 of 5 , Jul 2, 2003
        • 0 Attachment
          Michael Geddes wrote:

          > I think the remote debugging idea is quite kool.. so I've done a bit of
          > digging.
          >
          > As a start, I suggest that we turn off debug mode and redir_off at
          > the start of the message handler for remote_expr() on the server and
          > restore them at the end.

          That makes sense in most situations, but what if the user really wants
          to debug the commands being send remotely?

          --
          The psychic said, "God bless you." I said, "I didn't sneeze." She
          looked deep into my eyes and said, "You will, eventually." And, damn
          if she wasn't right. Two days later, I sneezed. --Ellen Degeneres

          /// Bram Moolenaar -- Bram@... -- http://www.Moolenaar.net \\\
          /// Creator of Vim - Vi IMproved -- http://www.Vim.org \\\
          \\\ Project leader for A-A-P -- http://www.A-A-P.org ///
          \\\ Help AIDS victims, buy here: http://ICCF-Holland.org/click1.html ///
        • Michael Geddes
          That works. Even with this patch, if you :breakadd the function being called, then it will break back into the debugger as expected (very nice, I thought)! We
          Message 4 of 5 , Jul 2, 2003
          • 0 Attachment
            That works.

            Even with this patch, if you :breakadd the function being called, then
            it will break back into the debugger as expected (very nice, I thought)!

            We could always add support for doing
            :breakadd func remote_expr
            that would cause the debugger to run on any remote_expr, which would
            then go into debug mode whether we were in debug mode originally or not!
            This, I believe, would be MUCH prefereable.

            //.ichael G.

            -----Original Message-----
            From: Bram Moolenaar [mailto:Bram@...]
            Sent: Thursday, 3 July 2003 6:15 AM
            To: Michael Geddes
            Cc: Hari Krishna Dara; Vim-dev@...
            Subject: RE: remote debugging ideas for vimscripts



            Michael Geddes wrote:

            > I think the remote debugging idea is quite kool.. so I've done a bit
            > of digging.
            >
            > As a start, I suggest that we turn off debug mode and redir_off at
            > the start of the message handler for remote_expr() on the server and
            > restore them at the end.

            That makes sense in most situations, but what if the user really wants
            to debug the commands being send remotely?

            --
            The psychic said, "God bless you." I said, "I didn't sneeze." She
            looked deep into my eyes and said, "You will, eventually." And, damn if
            she wasn't right. Two days later, I sneezed. --Ellen Degeneres

            /// Bram Moolenaar -- Bram@... -- http://www.Moolenaar.net
            \\\
            /// Creator of Vim - Vi IMproved -- http://www.Vim.org
            \\\
            \\\ Project leader for A-A-P -- http://www.A-A-P.org
            ///
            \\\ Help AIDS victims, buy here: http://ICCF-Holland.org/click1.html
            ///
          Your message has been successfully submitted and would be delivered to recipients shortly.