public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug debug/105389] New: variable displayed as available at -O1 and -O3 but as optimized out at -Og and with an incorrect value at -O2
@ 2022-04-26 10:37 assaiante at diag dot uniroma1.it
  0 siblings, 0 replies; only message in thread
From: assaiante at diag dot uniroma1.it @ 2022-04-26 10:37 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105389

            Bug ID: 105389
           Summary: variable displayed as available at -O1 and -O3 but as
                    optimized out at -Og and with an incorrect value at
                    -O2
           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_43, defined within the scope of
function c, has wrong debug information definition that lead to optimized out
or incorrect value being shown at -Og and -O2 while it has always the correct
value with optimization levels -O1 and -O3.

At -Og the variable is marked as optimized out at line 6 when its value should
be 5 and it becomes available with its correct value only starting from line 9,
where it is assigned to 0 via pointer arithmetics. At -O2 the variable has a
wrong value at line 10 (the only one actually stepped), it should be 0 but the
value available during debugging is 5.

We provide a detailed analysis on x64 with a quick assessment of older gcc
versions.

$ cat a.c
int a ;
char b ;
void  c() {
   int l_43 = 5;
   int *d = &l_43;
e:  b++;
   for (;
       a != -8;
       --a) *d = 0;
   if (b) goto e;
}
int main() {
   c();
}

GCC and GDB version (GCC commit id: 500d3f0a302):
gcc (GCC) 12.0.0 20211227 (experimental)
GNU gdb (GDB) 11.2

GDB trace at -Og:
$ gcc -Og -g a.c -o opt-g
$ gdb -q opt-g
Reading symbols from opt-g...
(gdb) b c
Breakpoint 1 at 0x400486: file a.c, line 3.
(gdb) r
Starting program: /tmp/opt-g 

Breakpoint 1, c () at a.c:3
3       void  c() {
(gdb) info loc
l_43 = <optimized out>
d = <optimized out>
(gdb) n
6       e:  b++;
(gdb) info loc
l_43 = <optimized out>
d = <optimized out>
(gdb) n
7           for (;
(gdb) info loc
l_43 = <optimized out>
d = <optimized out>
(gdb) n
8               a != -8;
(gdb) info loc
l_43 = <optimized out>
d = <optimized out>
(gdb) n
9               --a) *d = 0;
(gdb) info loc
l_43 = 0
d = <optimized out>
(gdb) n
8               a != -8;
(gdb) info loc
l_43 = <optimized out>
d = <optimized out>
(gdb) n
9               --a) *d = 0;
(gdb) info loc
l_43 = 0
d = <optimized out>

GDB trace at -O2:
$ gcc -O2 -g a.c -o opt-2
$ gdb -q opt-2
Reading symbols from opt-2...
(gdb) b c
Breakpoint 1 at 0x4004a0: file a.c, line 10.
(gdb) r
Starting program: /tmp/opt-2 

Breakpoint 1, c () at a.c:10
10          if (b) goto e;
(gdb) info loc
l_43 = 5
d = <synthetic pointer>
e = <optimized out>


ASM at -Og:
0000000000400486 <c>:
  400486:       eb 18                   jmp    4004a0 <c+0x1a>
  400488:       83 e8 01                sub    $0x1,%eax
  40048b:       89 05 9f 0b 20 00       mov    %eax,0x200b9f(%rip)        #
601030 <a>
  400491:       8b 05 99 0b 20 00       mov    0x200b99(%rip),%eax        #
601030 <a>
  400497:       83 f8 f8                cmp    $0xfffffff8,%eax
  40049a:       75 ec                   jne    400488 <c+0x2>
  40049c:       84 d2                   test   %dl,%dl
  40049e:       74 12                   je     4004b2 <c+0x2c>
  4004a0:       0f b6 05 85 0b 20 00    movzbl 0x200b85(%rip),%eax        #
60102c <b>
  4004a7:       8d 50 01                lea    0x1(%rax),%edx
  4004aa:       88 15 7c 0b 20 00       mov    %dl,0x200b7c(%rip)        #
60102c <b>
  4004b0:       eb df                   jmp    400491 <c+0xb>
  4004b2:       c3                      retq

DWARF at -Og:
0x000000ae:     DW_TAG_variable
                  DW_AT_name    ("l_43")
                  DW_AT_decl_file       ("/tmp/a.c")
                  DW_AT_decl_line       (4)
                  DW_AT_decl_column     (0x08)
                  DW_AT_type    (0x00000041 "int")
                  DW_AT_location        (0x0000000e: 
                     [0x0000000000400488, 0x0000000000400491): DW_OP_lit0,
DW_OP_stack_value)
                  DW_AT_GNU_locviews    (0x0000000c)


ASM and DWARF analysis at -Og:
>From DWARF information we can see how there is only a location range defined
for variable l_43 and it has value 0 associated with it.
The range includes the instructions associated with line 9 making the variable
available at line 9, but there is no location defined for the instructions
associated with line 6, thus making the variable marked as optimized out when
its value is 5. 

For instance, at -O1 this information is correctly computed:

ASM at -O1:
0000000000400486 <c>:
  400486:       0f b6 15 9f 0b 20 00    movzbl 0x200b9f(%rip),%edx        #
60102c <b>
  40048d:       8b 05 9d 0b 20 00       mov    0x200b9d(%rip),%eax        #
601030 <a>
  400493:       b9 00 00 00 00          mov    $0x0,%ecx
  400498:       be 01 00 00 00          mov    $0x1,%esi
  40049d:       83 c2 01                add    $0x1,%edx
  4004a0:       83 f8 f8                cmp    $0xfffffff8,%eax
  4004a3:       74 0a                   je     4004af <c+0x29>
  4004a5:       83 e8 01                sub    $0x1,%eax
  4004a8:       83 f8 f8                cmp    $0xfffffff8,%eax
  4004ab:       75 f8                   jne    4004a5 <c+0x1f>
  4004ad:       89 f1                   mov    %esi,%ecx
  4004af:       b8 f8 ff ff ff          mov    $0xfffffff8,%eax
  4004b4:       84 d2                   test   %dl,%dl
  4004b6:       75 e5                   jne    40049d <c+0x17>
  4004b8:       c6 05 6d 0b 20 00 00    movb   $0x0,0x200b6d(%rip)        #
60102c <b>
  4004bf:       84 c9                   test   %cl,%cl
  4004c1:       74 0a                   je     4004cd <c+0x47>
  4004c3:       c7 05 63 0b 20 00 f8    movl   $0xfffffff8,0x200b63(%rip)      
 # 601030 <a>
  4004ca:       ff ff ff 
  4004cd:       c3                      retq 

DWARF at -O1:
0x000000ae:     DW_TAG_variable
                  DW_AT_name    ("l_43")
                  DW_AT_decl_file       ("/tmp/a.c")
                  DW_AT_decl_line       (4)
                  DW_AT_decl_column     (0x08)
                  DW_AT_type    (0x00000041 "int")
                  DW_AT_location        (0x00000010: 
                     [0x0000000000400486, 0x000000000040049d): DW_OP_lit5,
DW_OP_stack_value
                     [0x00000000004004a5, 0x00000000004004af): DW_OP_lit0,
DW_OP_stack_value)
                  DW_AT_GNU_locviews    (0x0000000c)


ASM at -O2:
00000000004004a0 <c>:
  4004a0:       83 3d 89 0b 20 00 f8    cmpl   $0xfffffff8,0x200b89(%rip)      
 # 601030 <a>
  4004a7:       c6 05 7e 0b 20 00 00    movb   $0x0,0x200b7e(%rip)        #
60102c <b>
  4004ae:       74 0a                   je     4004ba <c+0x1a>
  4004b0:       c7 05 76 0b 20 00 f8    movl   $0xfffffff8,0x200b76(%rip)      
 # 601030 <a>
  4004b7:       ff ff ff 
  4004ba:       c3                      retq


DWARF at -O2:
0x000000aa:     DW_TAG_variable
                  DW_AT_name    ("l_43")
                  DW_AT_decl_file       ("/tmp/a.c")
                  DW_AT_decl_line       (4)
                  DW_AT_decl_column     (0x08)
                  DW_AT_type    (0x0000003d "int")
                  DW_AT_location        (0x0000000e: 
                     [0x00000000004004a0, 0x00000000004004ba): DW_OP_lit5,
DW_OP_stack_value)
                  DW_AT_GNU_locviews    (0x0000000c)



ASM and DWARF analysis at -O2:
>From DWARF information we can see how there is only a location range defined
for variable l_43 and it has value 5 associated with it.
The range includes the instructions associated with line 10, thus making the
variable to have a wrong value when stepping on line 10.

We tested older gcc versions (6.4, 7.5, 8.4, 9.3, 10.3, 11.1) and the results
are identical to the git version starting with gcc-8 for what happens at -O2
and the results are always identical to the git version for what happens at
-Og. For previous versions at –O2, the debug information was not generated at
all.

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-04-26 10:37 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-26 10:37 [Bug debug/105389] New: variable displayed as available at -O1 and -O3 but as optimized out at -Og and with an incorrect value at -O2 assaiante at diag dot uniroma1.it

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).