public inbox for gdb-prs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/17315] New: 'until' behavion in watchpoint.c (for loops) incompatible with loop condition instructions at the top of the loop
@ 2014-08-26 22:20 dblaikie at gmail dot com
  2021-12-09 14:34 ` [Bug c++/17315] " blarsen at redhat dot com
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: dblaikie at gmail dot com @ 2014-08-26 22:20 UTC (permalink / raw)
  To: gdb-prs

https://sourceware.org/bugzilla/show_bug.cgi?id=17315

            Bug ID: 17315
           Summary: 'until' behavion in watchpoint.c (for loops)
                    incompatible with loop condition instructions at the
                    top of the loop
           Product: gdb
           Version: 7.7
            Status: NEW
          Severity: normal
          Priority: P2
         Component: c++
          Assignee: unassigned at sourceware dot org
          Reporter: dblaikie at gmail dot com

Simplifying the watchpoint.c code down to:

  void func() {}

  int main() {
    int a;
    for (a = 0; a != 2; ++a) {
      func();
    }
    return 0;
  }

And running this through clang (assembly attached) and gdb, the following
behavior is observed:

=> 0x00000000004005af <main+15>:        c7 45 f8 00 00 00 00    movl  
$0x0,-0x8(%rbp)
(gdb) until
=> 0x00000000004005c3 <main+35>:        e8 c8 ff ff ff  callq  0x400590 <func>
(gdb) 
=> 0x00000000004005c8 <main+40>:        8b 45 f8        mov    -0x8(%rbp),%eax
   0x00000000004005cb <main+43>:        05 01 00 00 00  add    $0x1,%eax
   0x00000000004005d0 <main+48>:        89 45 f8        mov    %eax,-0x8(%rbp)
(gdb) 
=> 0x00000000004005c3 <main+35>:        e8 c8 ff ff ff  callq  0x400590 <func>

so 'until' doesn't cause the loop to be skipped at all - continuing to run
'until' will just behave as though the user is stepping through the entire
loop.

I believe the issue here is that Clang keeps the loop condition at the top of
the loop, whereas GCC puts it at the end, the theory being 'until' really looks
for an instruction with a higher PC than the /last/ instruction on the line you
started at, not the specific instruction you started at.

(eg: while I ran "until" from <main+40>, I went through 40, 43, 48, then
<main+51> jumped up to the top of the loop (+22) but on the same line according
to the line table, continued on to 29, and then to 35 - since 35 is on a
distinct line from 29 and 29 > 35, GDB stopped here, even though 40 !> 35)

And GCC puts the condition at the end of the loop, so you go from increment, to
condition, then jump up from the condition to the body - changing lines and
decreasing the PC, so that causes until to skip that and keep going... until
eventually it gets out of the loop.

-- 
You are receiving this mail because:
You are on the CC list for the bug.


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug c++/17315] 'until' behavion in watchpoint.c (for loops) incompatible with loop condition instructions at the top of the loop
  2014-08-26 22:20 [Bug c++/17315] New: 'until' behavion in watchpoint.c (for loops) incompatible with loop condition instructions at the top of the loop dblaikie at gmail dot com
@ 2021-12-09 14:34 ` blarsen at redhat dot com
  2022-01-05 20:31 ` blarsen at redhat dot com
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: blarsen at redhat dot com @ 2021-12-09 14:34 UTC (permalink / raw)
  To: gdb-prs

https://sourceware.org/bugzilla/show_bug.cgi?id=17315

B. Larsen <blarsen at redhat dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |evans_chen1 at dell dot com

--- Comment #2 from B. Larsen <blarsen at redhat dot com> ---
*** Bug 27196 has been marked as a duplicate of this bug. ***

-- 
You are receiving this mail because:
You are on the CC list for the bug.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug c++/17315] 'until' behavion in watchpoint.c (for loops) incompatible with loop condition instructions at the top of the loop
  2014-08-26 22:20 [Bug c++/17315] New: 'until' behavion in watchpoint.c (for loops) incompatible with loop condition instructions at the top of the loop dblaikie at gmail dot com
  2021-12-09 14:34 ` [Bug c++/17315] " blarsen at redhat dot com
@ 2022-01-05 20:31 ` blarsen at redhat dot com
  2022-02-11 15:15 ` cvs-commit at gcc dot gnu.org
  2022-05-17 19:26 ` blarsen at redhat dot com
  3 siblings, 0 replies; 5+ messages in thread
From: blarsen at redhat dot com @ 2022-01-05 20:31 UTC (permalink / raw)
  To: gdb-prs

https://sourceware.org/bugzilla/show_bug.cgi?id=17315

B. Larsen <blarsen at redhat dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |ASSIGNED
                 CC|                            |blarsen at redhat dot com

--- Comment #3 from B. Larsen <blarsen at redhat dot com> ---
I believe I have a solution for this problem. The issue wasn't that the loop
condition was at the top, but rather that there were lines at the bottom that
weren't marked as is_stmt. 

This way, when calculating the maximum PC to execute to, it landed on that
!is_stmt instruction, assumed the inferior was out of the block and GDB stopped
at the next is_stmt instruction, the one inside the loop

My patch fixes this by searching the first instance of an is_stmt instruction,
or the first instruction that happens on a different line, and sets that as the
stopping PC

The patch is available here:
https://sourceware.org/pipermail/gdb-patches/2022-January/184799.html

-- 
You are receiving this mail because:
You are on the CC list for the bug.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug c++/17315] 'until' behavion in watchpoint.c (for loops) incompatible with loop condition instructions at the top of the loop
  2014-08-26 22:20 [Bug c++/17315] New: 'until' behavion in watchpoint.c (for loops) incompatible with loop condition instructions at the top of the loop dblaikie at gmail dot com
  2021-12-09 14:34 ` [Bug c++/17315] " blarsen at redhat dot com
  2022-01-05 20:31 ` blarsen at redhat dot com
@ 2022-02-11 15:15 ` cvs-commit at gcc dot gnu.org
  2022-05-17 19:26 ` blarsen at redhat dot com
  3 siblings, 0 replies; 5+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2022-02-11 15:15 UTC (permalink / raw)
  To: gdb-prs

https://sourceware.org/bugzilla/show_bug.cgi?id=17315

--- Comment #4 from cvs-commit at gcc dot gnu.org <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Andrew Burgess <aburgess@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=9ab50efc463ff723b8e9102f1f68a6983d320517

commit 9ab50efc463ff723b8e9102f1f68a6983d320517
Author: Bruno Larsen <blarsen@redhat.com>
Date:   Wed Jan 26 10:08:13 2022 -0300

    gdb: fix until behavior with trailing !is_stmt lines

    When using the command "until", it is expected that GDB will exit a
    loop if the current instruction is the last one related to that loop.
    However, if there were trailing non-statement instructions, "until"
    would just behave as "next".  This was noticeable in clang-compiled
    code, but might happen with gcc-compiled as well.  PR gdb/17315 relates
    to this problem, as running gdb.base/watchpoint.exp with clang
    would fail for this reason.

    To better understand this issue, consider the following source code,
    with line numbers marked on the left:

      10:   for (i = 0; i < 10; ++i)
      11:     loop_body ();
      12:   other_stuff ();

    If we transform this to pseudo-assembler, and generate a line table,
    we could end up with something like this:

      Address | Pseudo-Assembler | Line | Is-Statement?

      0x100   | i = 0            | 10   | Yes
      0x104   | loop_body ()     | 11   | Yes
      0x108   | i = i + 1        | 10   | Yes
      0x10c   | if (i < 10):     | 10   | No
      0x110   |     goto 0x104   | 10   | No
      0x114   | other_stuff ()   | 12   | Yes

    Notice the two non-statement instructions at the end of the loop.

    The problem is that when we reach address 0x108 and use 'until',
    hoping to leave the loop, GDB sets up a stepping range that runs from
    the start of the function (0x100 in our example) to the end of the
    current line table entry, that is 0x10c in our example.  GDB then
    starts stepping forward.

    When 0x10c is reached GDB spots that we have left the stepping range,
    that the new location is not a statement, and that the new location is
    associated with the same source line number as the previous stepping
    range.  GDB then sets up a new stepping range that runs from 0x10c to
    0x114, and continues stepping forward.

    Within that stepping range the inferior hits the goto (at 0x110) and
    loops back to address 0x104.

    At 0x104 GDB spots that we have left the previous stepping range, that
    the new address is marked as a statement, and that the new address is
    for a different source line.  As a result, GDB stops and returns
    control to the user.  This is not what the user was expecting, they
    expected GDB to exit the loop.

    The fix proposed in this patch, is that, when the user issues the
    'until' command, and GDB sets up the initial stepping range, GDB will
    check subsequent SALs (symtab_and_lines) to see if they are
    non-statements associated with the same line number.  If they are then
    the end of the initial stepping range is extended to the end of the
    non-statement SALs.

    In our example above, the user is at 0x108 and uses 'until', GDB now
    sets up a stepping range from the start of the function 0x100 to
    0x114, the first address associated with a different line.

    Now as GDB steps around the loop it never leaves the initial stepping
    range.  It is only when GDB exits the loop that we leave the stepping
    range, and the stepping finishes at address 0x114.

    This patch also adds a test case that can be run with gcc to test that
    this functionality is not broken in the future.

    Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=17315

-- 
You are receiving this mail because:
You are on the CC list for the bug.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug c++/17315] 'until' behavion in watchpoint.c (for loops) incompatible with loop condition instructions at the top of the loop
  2014-08-26 22:20 [Bug c++/17315] New: 'until' behavion in watchpoint.c (for loops) incompatible with loop condition instructions at the top of the loop dblaikie at gmail dot com
                   ` (2 preceding siblings ...)
  2022-02-11 15:15 ` cvs-commit at gcc dot gnu.org
@ 2022-05-17 19:26 ` blarsen at redhat dot com
  3 siblings, 0 replies; 5+ messages in thread
From: blarsen at redhat dot com @ 2022-05-17 19:26 UTC (permalink / raw)
  To: gdb-prs

https://sourceware.org/bugzilla/show_bug.cgi?id=17315

B. Larsen <blarsen at redhat dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|ASSIGNED                    |RESOLVED
         Resolution|---                         |FIXED

--- Comment #5 from B. Larsen <blarsen at redhat dot com> ---
Sorry for the delay in closing this. The above-mentioned commit should fix this
issue

-- 
You are receiving this mail because:
You are on the CC list for the bug.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2022-05-17 19:26 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-08-26 22:20 [Bug c++/17315] New: 'until' behavion in watchpoint.c (for loops) incompatible with loop condition instructions at the top of the loop dblaikie at gmail dot com
2021-12-09 14:34 ` [Bug c++/17315] " blarsen at redhat dot com
2022-01-05 20:31 ` blarsen at redhat dot com
2022-02-11 15:15 ` cvs-commit at gcc dot gnu.org
2022-05-17 19:26 ` blarsen at redhat dot com

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).