binutils-gdb/gdb/testsuite/gdb.base/break-include.c
Joel Brobecker a9e408182d wrong line number in breakpoint location
Consider the following situation, where we have one file containing...

    $ cat -n body.inc
         1  i = i + 1;

... we include that file from some code, like so:

    $ cat -n cat -n small.c
        [...]
        17  int
        18  next (int i)
        19  {
        20  #include "body.inc"
        21    return i;
        22  }

When trying to insert a breakpoint on line 18, for instance:

    (gdb) b small.c:18
    Breakpoint 1 at 0x40049f: file body.inc, line 18.
                                                  ^^
                                                  ||

Here, the issue is that GDB reports the breakpoint to be in file
body.inc, which is true, but with the line number that corresponding
to the user-requested location, which is not correct.

Although the simple reproducer may look slightly artificial,
the above is simply one way to reproduce the same issue observed
when trying to insert a breakpoint on a function provided in
a .h files and then subsequently inlined in a C file.

What happens is the following:

  1. We resolve the small.c:18 linespec into a symtab_and_line which
     has "small.c" and 18 as the symtab and line number.

  2. Next, we call skip_prologue_sal, which calculates the PC
     past the prologue, and updates the symtab_and_line: PC,
     but also symtab (now body.inc) and the new line (now 1).

  3. However, right after that, we do:

            /* Make sure the line matches the request, not what was
               found.  */
            intermediate_results.sals[i].line = val.line;

We should either restore both symtab and line, or leave the actual
line to match the actual symtab.  This patch chose the latter.
This introduces a few changes in a few tests, which required some
updates, but looking at those change, I believe them to be expected.

gdb/ChangeLog:

        * linespec.c (create_sals_line_offset): Remove code that preserved
        the symtab_and_line's line number.

gdb/testsuite/ChangeLog:

        * gdb.base/break-include.c, gdb.base/break-include.inc,
        gdb.base/break-include.exp: New files.
        * gdb.base/ending-run.exp: Minor adaptations due to the breakpoint's
        line number now being the actual line number where the breakpoint
        was inserted.
        * gdb.mi/mi-break.exp: Likewise.
        * gdb.mi/mi-reverse.exp: Likewise.
        * gdb.mi/mi-simplerun.exp: Ditto.

Tested on x86_64-linux.
2018-01-21 23:14:50 -05:00

58 lines
2.1 KiB
C

/* This testcase is part of GDB, the GNU debugger.
Copyright 2016-2018 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
int next (int i);
int
main (void)
{
int result = -1;
result = next (result);
return result;
}
/* The following function's implementation starts by including a file
(break-include.inc) which contains a copyright header followed by
a single C statement. When we place a breakpoint on the line where
the function name is declared, we expect GDB to skip the function's
prologue, and insert the breakpoint on the first line of "user" code
for that function, which we have set up to be that single statement
break-include.inc provides.
The purpose of this testcase is to verify that, when we insert
that breakpoint, GDB reports the location as being in that include
file, but also using the correct line number inside that include
file -- NOT the line number we originally used to insert the
breakpoint, nor the location where the file is included from.
In order to verify that GDB shows the right line number, we must
be careful that this first statement located in break-include.inc
and our function are not on the same line number. Otherwise,
we could potentially have a false PASS.
This is why we implement the following function as far away
from the start of this file as possible, as we know that
break-include.inc is a fairly short file (copyright header
and single statement only). */
int
next (int i) /* break here */
{
#include "break-include.inc"
return i;
}