)]}'
{
  "commit": "9ab50efc463ff723b8e9102f1f68a6983d320517",
  "tree": "1daaefad5d325dc20ea22ec4be58df257041930a",
  "parents": [
    "b4b0dcfd03b6b40bec2e9fb21723f30d43e52f41"
  ],
  "author": {
    "name": "Bruno Larsen",
    "email": "blarsen@redhat.com",
    "time": "Wed Jan 26 10:08:13 2022 -0300"
  },
  "committer": {
    "name": "Andrew Burgess",
    "email": "aburgess@redhat.com",
    "time": "Fri Feb 11 15:15:48 2022 +0000"
  },
  "message": "gdb: fix until behavior with trailing !is_stmt lines\n\nWhen using the command \"until\", it is expected that GDB will exit a\nloop if the current instruction is the last one related to that loop.\nHowever, if there were trailing non-statement instructions, \"until\"\nwould just behave as \"next\".  This was noticeable in clang-compiled\ncode, but might happen with gcc-compiled as well.  PR gdb/17315 relates\nto this problem, as running gdb.base/watchpoint.exp with clang\nwould fail for this reason.\n\nTo better understand this issue, consider the following source code,\nwith line numbers marked on the left:\n\n  10:\tfor (i \u003d 0; i \u003c 10; ++i)\n  11:     loop_body ();\n  12:   other_stuff ();\n\nIf we transform this to pseudo-assembler, and generate a line table,\nwe could end up with something like this:\n\n  Address | Pseudo-Assembler | Line | Is-Statement?\n\n  0x100   | i \u003d 0            | 10   | Yes\n  0x104   | loop_body ()     | 11   | Yes\n  0x108   | i \u003d i + 1        | 10   | Yes\n  0x10c   | if (i \u003c 10):     | 10   | No\n  0x110   |     goto 0x104   | 10   | No\n  0x114   | other_stuff ()   | 12   | Yes\n\nNotice the two non-statement instructions at the end of the loop.\n\nThe problem is that when we reach address 0x108 and use \u0027until\u0027,\nhoping to leave the loop, GDB sets up a stepping range that runs from\nthe start of the function (0x100 in our example) to the end of the\ncurrent line table entry, that is 0x10c in our example.  GDB then\nstarts stepping forward.\n\nWhen 0x10c is reached GDB spots that we have left the stepping range,\nthat the new location is not a statement, and that the new location is\nassociated with the same source line number as the previous stepping\nrange.  GDB then sets up a new stepping range that runs from 0x10c to\n0x114, and continues stepping forward.\n\nWithin that stepping range the inferior hits the goto (at 0x110) and\nloops back to address 0x104.\n\nAt 0x104 GDB spots that we have left the previous stepping range, that\nthe new address is marked as a statement, and that the new address is\nfor a different source line.  As a result, GDB stops and returns\ncontrol to the user.  This is not what the user was expecting, they\nexpected GDB to exit the loop.\n\nThe fix proposed in this patch, is that, when the user issues the\n\u0027until\u0027 command, and GDB sets up the initial stepping range, GDB will\ncheck subsequent SALs (symtab_and_lines) to see if they are\nnon-statements associated with the same line number.  If they are then\nthe end of the initial stepping range is extended to the end of the\nnon-statement SALs.\n\nIn our example above, the user is at 0x108 and uses \u0027until\u0027, GDB now\nsets up a stepping range from the start of the function 0x100 to\n0x114, the first address associated with a different line.\n\nNow as GDB steps around the loop it never leaves the initial stepping\nrange.  It is only when GDB exits the loop that we leave the stepping\nrange, and the stepping finishes at address 0x114.\n\nThis patch also adds a test case that can be run with gcc to test that\nthis functionality is not broken in the future.\n\nBug: https://sourceware.org/bugzilla/show_bug.cgi?id\u003d17315\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "48dda9b23ee2a04b72b63d6f6c3eb9f6c5e74d96",
      "old_mode": 33188,
      "old_path": "gdb/infcmd.c",
      "new_id": "0e1cfcbadcd6e57ed4244f2247a0fe43258fb266",
      "new_mode": 33188,
      "new_path": "gdb/infcmd.c"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "749695b3db1fc03211833719e74438a9e5a17c06",
      "new_mode": 33188,
      "new_path": "gdb/testsuite/gdb.base/until-trailing-insns.c"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "e87f4a317e7ed3ba8032962432f78e9a65249e3a",
      "new_mode": 33188,
      "new_path": "gdb/testsuite/gdb.base/until-trailing-insns.exp"
    }
  ]
}
