binutils-gdb/gdb/testsuite/gdb.dwarf2/dw2-line-number-zero.c
Tom de Vries 876518dd0a [gdb/symtab] Ignore zero line table entries
The DWARF standard states for the line register in the line number information
state machine the following:
...
An unsigned integer indicating a source line number.  Lines are numbered
beginning at 1.  The compiler may emit the value 0 in cases where an
instruction cannot be attributed to any source line.
...

So, it's possible to have a zero line number in the DWARF line table.

This is currently not handled by GDB.  The zero value is read in as any other
line number, but internally the zero value has a special meaning:
end-of-sequence, so the line table entry ends up having a different
interpretation than intended in some situations.

I've created a test-case where various aspects are tested, which has these 4
interesting tests.

1. Next-step through a zero-line instruction, is_stmt == 1
gdb.dwarf2/dw2-line-number-zero.exp: bar1, 2nd next

2. Next-step through a zero-line instruction, is_stmt == 0
gdb.dwarf2/dw2-line-number-zero.exp: bar2, 2nd next

3. Show source location at zero-line instruction, is_stmt == 1
gdb.dwarf2/dw2-line-number-zero.exp: continue to breakpoint: bar1_label_3

4. Show source location at zero-line instruction, is_stmt == 0
gdb.dwarf2/dw2-line-number-zero.exp: continue to breakpoint: bar2_label_3

And we have the following results:

8.3.1, 9.2:
...
FAIL: gdb.dwarf2/dw2-line-number-zero.exp: bar1, 2nd next
PASS: gdb.dwarf2/dw2-line-number-zero.exp: bar2, 2nd next
PASS: gdb.dwarf2/dw2-line-number-zero.exp: continue to breakpoint: bar1_label_3
FAIL: gdb.dwarf2/dw2-line-number-zero.exp: continue to breakpoint: bar2_label_3
...

commit 8c95582da8 "gdb: Add support for tracking the DWARF line table is-stmt
field":
...
PASS: gdb.dwarf2/dw2-line-number-zero.exp: bar1, 2nd next
PASS: gdb.dwarf2/dw2-line-number-zero.exp: bar2, 2nd next
FAIL: gdb.dwarf2/dw2-line-number-zero.exp: continue to breakpoint: bar1_label_3
FAIL: gdb.dwarf2/dw2-line-number-zero.exp: continue to breakpoint: bar2_label_3
...

commit d8cc8af6a1 "[gdb/symtab] Fix line-table end-of-sequence sorting",
master:
FAIL: gdb.dwarf2/dw2-line-number-zero.exp: bar1, 2nd next
FAIL: gdb.dwarf2/dw2-line-number-zero.exp: bar2, 2nd next
PASS: gdb.dwarf2/dw2-line-number-zero.exp: continue to breakpoint: bar1_label_3
PASS: gdb.dwarf2/dw2-line-number-zero.exp: continue to breakpoint: bar2_label_3
...

The regression in test 2 at commit d8cc8af6a1 was filed as PR symtab/26243,
where clang emits zero line numbers.

The way to fix all tests is to make sure line number zero internally doesn't
clash with special meaning values, and by handling it appropriately
everywhere.  That however looks too intrusive for the GDB 10 release.

Instead, we decide to ensure defined behaviour for line number zero by
ignoring it.  This gives us back the test results from before commit
d8cc8af6a1, fixing PR26243.

We mark the FAILs for tests 3 and 4 as KFAILs.  Test 4 was already failing for
the 9.2 release, and we consider the regression of test 3 from gdb 9.2 to gdb
10 the cost for having defined behaviour.

Build and reg-tested on x86_64-linux.

gdb/ChangeLog:

2020-07-25  Tom de Vries  <tdevries@suse.de>

	PR symtab/26243
	* dwarf2/read.c (lnp_state_machine::record_line): Ignore zero line
	entries.

gdb/testsuite/ChangeLog:

2020-07-25  Tom de Vries  <tdevries@suse.de>

	PR symtab/26243
	* gdb.dwarf2/dw2-line-number-zero.c: New test.
	* gdb.dwarf2/dw2-line-number-zero.exp: New file.
2020-07-25 00:23:06 +02:00

63 lines
1.4 KiB
C

/*
Copyright 2020 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/>. */
void
foo (int x)
{
}
void
bar1 (void)
{
asm ("bar1_label: .globl bar1_label");
foo (1);
asm ("bar1_label_2: .globl bar1_label_2");
foo (2);
asm ("bar1_label_3: .globl bar1_label_3");
foo (3);
asm ("bar1_label_4: .globl bar1_label_4");
foo (4);
asm ("bar1_label_5: .globl bar1_label_5");
}
void
bar2 (void)
{
asm ("bar2_label: .globl bar2_label");
foo (1);
asm ("bar2_label_2: .globl bar2_label_2");
foo (2);
asm ("bar2_label_3: .globl bar2_label_3");
foo (3);
asm ("bar2_label_4: .globl bar2_label_4");
foo (4);
asm ("bar2_label_5: .globl bar2_label_5");
}
int
main (void)
{
asm ("main_label: .globl main_label");
bar1 ();
bar2 ();
return 0;
}