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.
  • [Bug debug/104938] New: Pos... assaiante at diag dot uniroma1.it via Gcc-bugs

Reply via email to