https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104938
Bug ID: 104938
Summary: Possibly wrong location definition in DWARF with
-ftree-cpp at -Og only
Product: gcc
Version: 12.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: debug
Assignee: unassigned at gcc dot gnu.org
Reporter: assaiante at diag dot uniroma1.it
Target Milestone: ---
In this minimized C example, variable l_3, which is initialized at line 5, is
associated to DWARF symbols having a possibly wrong location definition. This
causes the variable to not be available during debugging, for instance at line
6, until line 11 is reached. We observe the bug at -Og with the cause likely
being -ftree-ccp, while with other optimizations levels the variable is
correctly available at the lines where gdb can step (line 6 with -O1/O2/O3/Os,
also line 8 with -O1/Os). Please find below a detailed analysis for -Og on x64.
$ cat a.c
char a;
int b;
void foo(int *d) { a = 0; }
int main() {
int *l_3 = &b;
int **e = &l_3;
f:
if (a)
goto f;
*e = l_3;
foo(*e);
}
GCC and GDB version (GCC commit id: 500d3f0a302):
$ gcc --version
gcc (GCC) 12.0.0 20211227 (experimental)
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ gdb --version
GNU gdb (GDB) 11.2
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
GDB trace:
$ gcc -Og -g a.c -o opt
$ gdb -q opt
Reading symbols from opt...
(gdb) start
Temporary breakpoint 1 at 0x40048e: file a.c, line 8.
Starting program: /home/stepping/132/reduce/opt
Temporary breakpoint 1, main () at a.c:8
8 if (a)
(gdb) info locals
l_3 = <optimized out>
e = <optimized out>
(gdb) n
11 foo(*e);
(gdb) info locals
l_3 = 0x60102c <b>
e = <optimized out>
By dumping the DWARF info, we can see how the location associated to the
variable is defined with a range that does not include the instruction
associated to line 8, where the variable's value is not available despite the
original program has assigned (and, incidentally, also used) it by then.
ASM:
000000000040048e <main>:
40048e: 80 3d 9b 0b 20 00 00 cmpb $0x0,0x200b9b(%rip) #
601030 <a>
400495: 75 f7 jne 40048e <main>
400497: bf 2c 10 60 00 mov $0x60102c,%edi
40049c: e8 e5 ff ff ff callq 400486 <c>
4004a1: b8 00 00 00 00 mov $0x0,%eax
4004a6: c3 retq
4004a7: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1)
4004ae: 00 00
DWARF info:
0x00000084: DW_TAG_variable
DW_AT_name ("l_3")
DW_AT_decl_file ("/home/stepping/132/reduce/a.c")
DW_AT_decl_line (5)
DW_AT_decl_column (0x08)
DW_AT_type (0x000000cc "int*")
DW_AT_location (0x0000000e:
[0x0000000000400497, 0x00000000004004a1): DW_OP_addr
0x60102c, DW_OP_stack_value)
DW_AT_GNU_locviews (0x0000000c)
Through some testing we found out that the optimization flag that introduces
the bug is likely -ftree-ccp. If we add -fno-tree-ccp to the compilation
command line used above, variable l_3 appears in the current frame with its
value correctly available at line 8. The location of the variable appears now
to be correctly defined with the range including the cmp instruction that
corresponds to line 8 according to the line number table in DWARF info.
ASM with -fno-tree-ccp:
40048e: 48 83 ec 10 sub $0x10,%rsp
400492: 48 c7 44 24 08 2c 10 movq $0x60102c,0x8(%rsp)
400499: 60 00
40049b: 80 3d 8e 0b 20 00 00 cmpb $0x0,0x200b8e(%rip) #
601030 <a>
4004a2: 75 f7 jne 40049b <main+0xd>
4004a4: bf 2c 10 60 00 mov $0x60102c,%edi
4004a9: e8 d8 ff ff ff callq 400486 <c>
4004ae: b8 00 00 00 00 mov $0x0,%eax
4004b3: 48 83 c4 10 add $0x10,%rsp
4004b7: c3 retq
4004b8: 0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1)
4004bf: 00
DWARF info with -fno-tree-ccp:
0x00000093: DW_TAG_variable
DW_AT_name ("e")
DW_AT_decl_file ("/home/stepping/132/reduce/a.c")
DW_AT_decl_line (6)
DW_AT_decl_column (0x09)
DW_AT_type (0x000000d4 "int**")
DW_AT_location (0x0000000e:
[0x000000000040049b, 0x00000000004004b8): DW_OP_fbreg -16,
DW_OP_stack_value)
DW_AT_GNU_locviews (0x0000000c)
We also tested the program against older versions of gcc (6, 7, 8, 9, 10, 11)
and the issue is present in all of them.