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

Bug in tag stack?

Expand Messages
  • Corinna Vinschen
    Hi, I don t know if that counts as a bug, therefore I m a bit wary. I can reproduce this situation with vim 6.1.300 as well as with 6.2f. Normally, when
    Message 1 of 8 , May 27, 2003
    • 0 Attachment
      Hi,

      I don't know if that counts as a bug, therefore I'm a bit wary. I can
      reproduce this situation with vim 6.1.300 as well as with 6.2f.

      Normally, when jumping through tags multiple times, it's possible to return
      to the previous file positions by <C-T>. This can be used as often as you
      want (well, at least very often), up to the point where you the first time
      pressed e.g. <C-]>.

      But I found a situation in which this doesn't work anymore.

      I'm using g<C-]> pretty often and I have a situation like this:

      I'm in a file called fhandler_socket.cc. I'm on a function call to a
      method fixup_before_fork_exec() which exists in two classes, defined in
      two different files, one of them fhandler_socket.cc itself. Now I press
      g<C-]> which shows me the list of possible matches:

      # pri kind tag file
      1 F C f fixup_before_fork_exec fhandler_socket.cc
      class:fhandler_socket
      fhandler_socket::fixup_before_fork_exec (DWORD win_proc_id)
      2 F f fixup_before_fork_exec fhandler.h
      class:fhandler_base
      virtual void fixup_before_fork_exec (DWORD) {}
      Enter nr of choice (<CR> to abort):

      I press 1<CR> which jumps to the tag'ed method in the same file:

      void
      fhandler_socket::fixup_before_fork_exec (DWORD win_proc_id)
      {
      [...]

      Now I go to the name of the method, right after the double colon
      and press g<C-]> again:

      # pri kind tag file
      1 F C f fixup_before_fork_exec fhandler_socket.cc
      class:fhandler_socket
      fhandler_socket::fixup_before_fork_exec (DWORD win_proc_id)
      2 F f fixup_before_fork_exec fhandler.h
      class:fhandler_base
      virtual void fixup_before_fork_exec (DWORD) {}
      Enter nr of choice (<CR> to abort):

      But this time I just press <CR> to abort. And now it happens. If I
      now press <C-T> to return to the original position I was coming from,
      I'm getting the following message in the last line:

      E92: Buffer 0 not found

      and it just stays where it is. For some reason the last known position
      in the tag stack is not available anymore. Note that the tag stack
      still looks ok after that:

      :tags
      # TO tag FROM line in file/text
      1 1 fixup_before_fork_exec 398 fhs->fixup_before_fork_exec (GetCurrentProcessId
      >

      However, let's say I return to the last known position by scrolling
      to it. Then I use g<C-]> again on the same method call, again I choose
      to go to the method in the same file. When I know look into the tag
      stack, something weird happened:

      :tags
      # TO tag FROM line in file/text
      1 1 fixup_before_fork_exec 398 fhs->fixup_before_fork_exec (GetCurrentProcessId
      3 1 fixup_before_fork_exec 398 fhs->fixup_before_fork_exec (GetCurrentProcessId

      You see the tag #? The tag # 2 is suddenly missing. This happens
      as often as I repeat the above. The even numbered tags just don't
      exist then.

      Am I expecting something which doesn't work for a good reason or is
      that perhaps actually a bug?

      Thanks in advance,
      Corinna

      --
      Corinna Vinschen
      Cygwin Developer
      Red Hat, Inc.
      mailto:vinschen@...
    • Corinna Vinschen
      Ping? Corinna ... -- Corinna Vinschen Cygwin Developer Red Hat, Inc. mailto:vinschen@redhat.com
      Message 2 of 8 , Jun 1, 2003
      • 0 Attachment
        Ping?

        Corinna

        On Tue, May 27, 2003 at 10:56:28AM +0200, Corinna Vinschen wrote:
        > Hi,
        >
        > I don't know if that counts as a bug, therefore I'm a bit wary. I can
        > reproduce this situation with vim 6.1.300 as well as with 6.2f.
        >
        > Normally, when jumping through tags multiple times, it's possible to return
        > to the previous file positions by <C-T>. This can be used as often as you
        > want (well, at least very often), up to the point where you the first time
        > pressed e.g. <C-]>.
        >
        > But I found a situation in which this doesn't work anymore.
        >
        > I'm using g<C-]> pretty often and I have a situation like this:
        >
        > I'm in a file called fhandler_socket.cc. I'm on a function call to a
        > method fixup_before_fork_exec() which exists in two classes, defined in
        > two different files, one of them fhandler_socket.cc itself. Now I press
        > g<C-]> which shows me the list of possible matches:
        >
        > # pri kind tag file
        > 1 F C f fixup_before_fork_exec fhandler_socket.cc
        > class:fhandler_socket
        > fhandler_socket::fixup_before_fork_exec (DWORD win_proc_id)
        > 2 F f fixup_before_fork_exec fhandler.h
        > class:fhandler_base
        > virtual void fixup_before_fork_exec (DWORD) {}
        > Enter nr of choice (<CR> to abort):
        >
        > I press 1<CR> which jumps to the tag'ed method in the same file:
        >
        > void
        > fhandler_socket::fixup_before_fork_exec (DWORD win_proc_id)
        > {
        > [...]
        >
        > Now I go to the name of the method, right after the double colon
        > and press g<C-]> again:
        >
        > # pri kind tag file
        > 1 F C f fixup_before_fork_exec fhandler_socket.cc
        > class:fhandler_socket
        > fhandler_socket::fixup_before_fork_exec (DWORD win_proc_id)
        > 2 F f fixup_before_fork_exec fhandler.h
        > class:fhandler_base
        > virtual void fixup_before_fork_exec (DWORD) {}
        > Enter nr of choice (<CR> to abort):
        >
        > But this time I just press <CR> to abort. And now it happens. If I
        > now press <C-T> to return to the original position I was coming from,
        > I'm getting the following message in the last line:
        >
        > E92: Buffer 0 not found
        >
        > and it just stays where it is. For some reason the last known position
        > in the tag stack is not available anymore. Note that the tag stack
        > still looks ok after that:
        >
        > :tags
        > # TO tag FROM line in file/text
        > 1 1 fixup_before_fork_exec 398 fhs->fixup_before_fork_exec (GetCurrentProcessId
        > >
        >
        > However, let's say I return to the last known position by scrolling
        > to it. Then I use g<C-]> again on the same method call, again I choose
        > to go to the method in the same file. When I know look into the tag
        > stack, something weird happened:
        >
        > :tags
        > # TO tag FROM line in file/text
        > 1 1 fixup_before_fork_exec 398 fhs->fixup_before_fork_exec (GetCurrentProcessId
        > 3 1 fixup_before_fork_exec 398 fhs->fixup_before_fork_exec (GetCurrentProcessId
        >
        > You see the tag #? The tag # 2 is suddenly missing. This happens
        > as often as I repeat the above. The even numbered tags just don't
        > exist then.
        >
        > Am I expecting something which doesn't work for a good reason or is
        > that perhaps actually a bug?
        >
        > Thanks in advance,
        > Corinna
        >
        > --
        > Corinna Vinschen
        > Cygwin Developer
        > Red Hat, Inc.
        > mailto:vinschen@...

        --
        Corinna Vinschen
        Cygwin Developer
        Red Hat, Inc.
        mailto:vinschen@...
      • Bram Moolenaar
        Corinna Vinschen wrote: I had this in my inbox for a while... ... [...] I cannot reproduce this. I can see the code where it could go wrong: in do_tag() this
        Message 3 of 8 , Jun 1, 2003
        • 0 Attachment
          Corinna Vinschen wrote:

          I had this in my inbox for a while...

          > I don't know if that counts as a bug, therefore I'm a bit wary. I can
          > reproduce this situation with vim 6.1.300 as well as with 6.2f.
          >
          > Normally, when jumping through tags multiple times, it's possible to return
          > to the previous file positions by <C-T>. This can be used as often as you
          > want (well, at least very often), up to the point where you the first time
          > pressed e.g. <C-]>.
          >
          > But I found a situation in which this doesn't work anymore.
          [...]

          I cannot reproduce this.

          I can see the code where it could go wrong: in do_tag() this code is
          used when cancelling a selection:

          /* no valid choice: don't change anything */
          if (use_tagstack)
          {
          tagstack[tagstackidx].fmark = saved_fmark;
          ++tagstackidx;
          }

          Apparently this is exeuted while saved_fmark wasn't set and/or
          tagstackidx is incremented one too much. But I don't see when that
          could happen.

          This is quite complicated code. Can you step through it with a debugger
          in the situation where you cancel the selection? That should show what
          happens and why use_tagstack is set when it shouldn't.

          --
          Bumper sticker: Honk if you love peace and quiet.

          /// 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 at Amazon -- http://ICCF.nl/click1.html ///
        • Corinna Vinschen
          ... This is way more complex code for me since I m not at all familar with it. A great help would be if you could give some directions where to set sensible
          Message 4 of 8 , Jun 1, 2003
          • 0 Attachment
            On Sun, Jun 01, 2003 at 12:07:03PM +0200, Bram Moolenaar wrote:
            > I cannot reproduce this.
            >
            > I can see the code where it could go wrong: in do_tag() this code is
            > used when cancelling a selection:
            >
            > /* no valid choice: don't change anything */
            > if (use_tagstack)
            > {
            > tagstack[tagstackidx].fmark = saved_fmark;
            > ++tagstackidx;
            > }
            >
            > Apparently this is exeuted while saved_fmark wasn't set and/or
            > tagstackidx is incremented one too much. But I don't see when that
            > could happen.
            >
            > This is quite complicated code. Can you step through it with a debugger
            > in the situation where you cancel the selection? That should show what
            > happens and why use_tagstack is set when it shouldn't.

            This is way more complex code for me since I'm not at all familar with it.

            A great help would be if you could give some directions where to set
            sensible breakpoints. I'll have a look into it then.

            Corinna

            --
            Corinna Vinschen
            Cygwin Developer
            Red Hat, Inc.
            mailto:vinschen@...
          • Bram Moolenaar
            ... The best method would be to do everything normally up to the point where you are about to use g^] for the choice you will cancel. Then put a breakpoint at
            Message 5 of 8 , Jun 1, 2003
            • 0 Attachment
              Corinna Vinschen wrote:

              > On Sun, Jun 01, 2003 at 12:07:03PM +0200, Bram Moolenaar wrote:
              > > I cannot reproduce this.
              > >
              > > I can see the code where it could go wrong: in do_tag() this code is
              > > used when cancelling a selection:
              > >
              > > /* no valid choice: don't change anything */
              > > if (use_tagstack)
              > > {
              > > tagstack[tagstackidx].fmark = saved_fmark;
              > > ++tagstackidx;
              > > }
              > >
              > > Apparently this is exeuted while saved_fmark wasn't set and/or
              > > tagstackidx is incremented one too much. But I don't see when that
              > > could happen.
              > >
              > > This is quite complicated code. Can you step through it with a debugger
              > > in the situation where you cancel the selection? That should show what
              > > happens and why use_tagstack is set when it shouldn't.
              >
              > This is way more complex code for me since I'm not at all familar with it.
              >
              > A great help would be if you could give some directions where to set
              > sensible breakpoints. I'll have a look into it then.

              The best method would be to do everything normally up to the point where
              you are about to use g^] for the choice you will cancel. Then put a
              breakpoint at do_tag() and step through that. Watch what happens with
              tagstackidx and saved_fmark.

              --
              Despite the cost of living, have you noticed how it remains so popular?

              /// 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 at Amazon -- http://ICCF.nl/click1.html ///
            • Corinna Vinschen
              ... I m not entirely sure but I think I found the problem. The following ... +++ tag.c 2003-06-01 14:21:04.000000000 +0200 @@ -716,10 +716,7 @@ do_tag(tag,
              Message 6 of 8 , Jun 1, 2003
              • 0 Attachment
                On Sun, Jun 01, 2003 at 01:44:56PM +0200, Bram Moolenaar wrote:
                > The best method would be to do everything normally up to the point where
                > you are about to use g^] for the choice you will cancel. Then put a
                > breakpoint at do_tag() and step through that. Watch what happens with
                > tagstackidx and saved_fmark.

                I'm not entirely sure but I think I found the problem. The following
                patch seem to do the trick:

                --- tag.c.ORIG 2003-06-01 14:20:28.000000000 +0200
                +++ tag.c 2003-06-01 14:21:04.000000000 +0200
                @@ -716,10 +716,7 @@ do_tag(tag, type, count, forceit, verbos
                {
                /* no valid choice: don't change anything */
                if (use_tagstack)
                - {
                tagstack[tagstackidx].fmark = saved_fmark;
                - ++tagstackidx;
                - }
                #ifdef FEAT_CSCOPE
                cs_free_tags();
                jumped_to_tag = TRUE;


                Incrementing tagstackidx should be valid only if the choice was valid.
                Otherwise the tagstack remains unchanged, so also tagstackidx should
                remain unchanged. Adding one up if nothing happens results in wrong
                information on top of the stack.

                Is the patch ok? It helped in my case but I'm not sure if I'm missing
                something.


                Corinna

                --
                Corinna Vinschen
                Cygwin Developer
                Red Hat, Inc.
                mailto:vinschen@...
              • Bram Moolenaar
                ... I don t think incrementing tagstackidx was done for no reason. You can see around line 375 that tagstackidx is decremented: if (--tagstackidx
                Message 7 of 8 , Jun 1, 2003
                • 0 Attachment
                  Corinna Vinschen wrote:

                  > On Sun, Jun 01, 2003 at 01:44:56PM +0200, Bram Moolenaar wrote:
                  > > The best method would be to do everything normally up to the point where
                  > > you are about to use g^] for the choice you will cancel. Then put a
                  > > breakpoint at do_tag() and step through that. Watch what happens with
                  > > tagstackidx and saved_fmark.
                  >
                  > I'm not entirely sure but I think I found the problem. The following
                  > patch seem to do the trick:
                  >
                  > --- tag.c.ORIG 2003-06-01 14:20:28.000000000 +0200
                  > +++ tag.c 2003-06-01 14:21:04.000000000 +0200
                  > @@ -716,10 +716,7 @@ do_tag(tag, type, count, forceit, verbos
                  > {
                  > /* no valid choice: don't change anything */
                  > if (use_tagstack)
                  > - {
                  > tagstack[tagstackidx].fmark = saved_fmark;
                  > - ++tagstackidx;
                  > - }
                  > #ifdef FEAT_CSCOPE
                  > cs_free_tags();
                  > jumped_to_tag = TRUE;
                  >
                  >
                  > Incrementing tagstackidx should be valid only if the choice was valid.
                  > Otherwise the tagstack remains unchanged, so also tagstackidx should
                  > remain unchanged. Adding one up if nothing happens results in wrong
                  > information on top of the stack.
                  >
                  > Is the patch ok? It helped in my case but I'm not sure if I'm missing
                  > something.

                  I don't think incrementing tagstackidx was done for no reason. You can
                  see around line 375 that tagstackidx is decremented:

                  if (--tagstackidx < 0)
                  tagstackidx = 0;
                  cur_match = tagstack[tagstackidx].cur_match;

                  When cancelling the tag selection it should remain unmodified. Perhaps
                  the exception that tagstackidx becomes negative is what bites you here?

                  Another solution would be to keep the value before decrementing and
                  restoring it when the selection was cancelled. Please try if this patch
                  fixes your problem:

                  *** ../vim-6.2f.039/src/tag.c Thu May 29 19:54:32 2003
                  --- src/tag.c Sun Jun 1 14:41:25 2003
                  ***************
                  *** 139,144 ****
                  --- 139,145 ----
                  int tagstacklen = curwin->w_tagstacklen;
                  int cur_match = 0;
                  int oldtagstackidx = tagstackidx;
                  + int prevtagstackidx = tagstackidx;
                  int prev_num_matches;
                  int new_tag = FALSE;
                  int other_name;
                  ***************
                  *** 363,368 ****
                  --- 364,372 ----
                  }
                  else /* go to other matching tag */
                  {
                  + /* Save index for when selection is cancelled. */
                  + prevtagstackidx = tagstackidx;
                  +
                  #if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
                  if (g_do_tagpreview)
                  cur_match = ptag_entry.cur_match;
                  ***************
                  *** 718,724 ****
                  if (use_tagstack)
                  {
                  tagstack[tagstackidx].fmark = saved_fmark;
                  ! ++tagstackidx;
                  }
                  #ifdef FEAT_CSCOPE
                  cs_free_tags();
                  --- 722,728 ----
                  if (use_tagstack)
                  {
                  tagstack[tagstackidx].fmark = saved_fmark;
                  ! tagstackidx = prevtagstackidx;
                  }
                  #ifdef FEAT_CSCOPE
                  cs_free_tags();

                  --
                  Just remember...if the world didn't suck, we'd all fall off.

                  /// 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 at Amazon -- http://ICCF.nl/click1.html ///
                • Corinna Vinschen
                  ... I tried it and it fixes the problem. Thanks, Corinna -- Corinna Vinschen Cygwin Developer Red Hat, Inc. mailto:vinschen@redhat.com
                  Message 8 of 8 , Jun 1, 2003
                  • 0 Attachment
                    On Sun, Jun 01, 2003 at 02:44:29PM +0200, Bram Moolenaar wrote:
                    > Another solution would be to keep the value before decrementing and
                    > restoring it when the selection was cancelled. Please try if this patch
                    > fixes your problem:

                    I tried it and it fixes the problem.

                    Thanks,
                    Corinna

                    --
                    Corinna Vinschen
                    Cygwin Developer
                    Red Hat, Inc.
                    mailto:vinschen@...
                  Your message has been successfully submitted and would be delivered to recipients shortly.