public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug debug/105108] New: incomplete/incorrect DWARF information at -O1 and -Og after inlining a function returning a constant
@ 2022-03-30 14:38 assaiante at diag dot uniroma1.it
  2022-03-31  6:39 ` [Bug debug/105108] " rguenth at gcc dot gnu.org
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: assaiante at diag dot uniroma1.it @ 2022-03-30 14:38 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 105108
           Summary: incomplete/incorrect DWARF information at -O1 and -Og
                    after inlining a function returning a constant
           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_144 is not available when debugging
(optimized out) when used in the assignment of variable a.

We found this odd since -O2/-O3 generate nearly identical ASM but with complete
debug information for l_144. At -O1/-Og the DIE of the variable misses instead
the const value attribute.

We were not able to pinpoint the root cause to a specific compilation option,
but suspect an interaction of inlining and constant propagation. We provide
below additional analysis for x64.

Then, much to our surprise, when we modify line 4 to assign l_144 with e.g. 8,
the debugger shows 8 instead of 0 as its value at line 7, therefore exposing
incorrect debug information. At a first look, this happened also with -O2/O3:
however, we then found -O2/-O3 DWARF information to be correct (also, lldb
displays 0), with the issue likely being a bug in gdb that we will report
separately.

$ cat a.c
int a;
char b() { return 0; }
int main() {
 char l_144;
 short l_165 = 128;
 l_144 = b();
 a = l_144 != l_165;
}


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

GDB trace:
$ gcc -Og -g a.c -o opt
$ gdb opt
Reading symbols from opt...
(gdb) b 7
Breakpoint 1 at 0x40048c: file a.c, line 7.
(gdb) r
Starting program: /home/stepping/35/reduce/opt 

Breakpoint 1, main () at a.c:7
7         a = l_144 != l_165;
(gdb) info locals
l_144 = <optimized out>
l_165 = 128


ASM at Og (identical at O1):
000000000040048c <main>:
 40048c:       c7 05 96 0b 20 00 01    movl   $0x1,0x200b96(%rip)        #
60102c <a>
 400493:       00 00 00  
 400496:       b8 00 00 00 00          mov    $0x0,%eax
 40049b:       c3                      retq    
 40049c:       0f 1f 40 00             nopl   0x0(%rax)

DWARF at Og (identical at O1):
0x00000049:   DW_TAG_subprogram
                DW_AT_external  (true)
                DW_AT_name      ("main")
                DW_AT_decl_file ("/home/stepping/35/reduce/a.c")
                DW_AT_decl_line (3)
                DW_AT_decl_column       (0x05)
                DW_AT_type      (0x00000042 "int")
                DW_AT_low_pc    (0x000000000040048c)
                DW_AT_high_pc   (0x000000000040049c)
                DW_AT_frame_base        (DW_OP_call_frame_cfa)
                DW_AT_call_all_calls    (true)
                DW_AT_sibling   (0x00000085)

0x0000006b:     DW_TAG_variable
                  DW_AT_name    ("l_144")
                  DW_AT_decl_file       ("/home/stepping/35/reduce/a.c")
                  DW_AT_decl_line       (4)
                  DW_AT_decl_column     (0x08)
                  DW_AT_type    (0x00000085 "char")

0x00000077:     DW_TAG_variable
                  DW_AT_name    ("l_165")
                  DW_AT_decl_file       ("/home/stepping/35/reduce/a.c")
                  DW_AT_decl_line       (5)
                  DW_AT_decl_column     (0x09)
                  DW_AT_type    (0x0000008c "short int")
                  DW_AT_const_value     (0x80)


At higher optimization levels the ASM is nearly the same, except the use of xor
instead of mov to set the return value to zero:

00000000004003a0 <main>:
 4003a0:       c7 05 82 0c 20 00 01    movl   $0x1,0x200c82(%rip)        #
60102c <a>
 4003a7:       00 00 00  
 4003aa:       31 c0                   xor    %eax,%eax
 4003ac:       c3                      retq    
 4003ad:       0f 1f 00                nopl   (%rax)

But the variable is correctly visible when stepping on line 7 since the const
value attribute is present in its debug information:

0x00000045:   DW_TAG_subprogram
                DW_AT_external  (true)
                DW_AT_name      ("main")
                DW_AT_decl_file ("/home/stepping/35/reduce/a.c")
                DW_AT_decl_line (3)
                DW_AT_decl_column       (0x05)
                DW_AT_type      (0x0000003e "int")
                DW_AT_low_pc    (0x00000000004003a0)
                DW_AT_high_pc   (0x00000000004003ad)
                DW_AT_frame_base        (DW_OP_call_frame_cfa)
                DW_AT_call_all_calls    (true)
                DW_AT_sibling   (0x00000080)

0x00000067:     DW_TAG_variable
                  DW_AT_name    ("l_144")
                  DW_AT_decl_line       (4)
                  DW_AT_decl_column     (0x08)
                  DW_AT_type    (0x00000080 "char")
                  DW_AT_const_value     (0x00)

0x00000073:     DW_TAG_variable
                  DW_AT_name    ("l_165")
                  DW_AT_decl_line       (5)
                  DW_AT_decl_column     (0x09)
                  DW_AT_type    (0x00000087 "short int")
                  DW_AT_const_value     (0x80)

We also tested the program with older gcc (6, 7, 8, 9, 10, 11) versions. In
gcc-{6,7}, the information about the variable l_144 value is never generated at
any optimization level. From gcc-8 to gcc-11, we encounter the same exact
behavior as in the git version we have tested, including the variant where
variable l_144 is assigned upon its definition. In fact, also in older gcc
versions, such assignment ultimately leads to a wrong value available during
debugging when optimization level is Og or O1. At higher levels, the debug
information is correctly generated but, as mentioned before, a potential gdb
bug leads to a wrong value being displayed.

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2022-03-31 16:55 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-30 14:38 [Bug debug/105108] New: incomplete/incorrect DWARF information at -O1 and -Og after inlining a function returning a constant assaiante at diag dot uniroma1.it
2022-03-31  6:39 ` [Bug debug/105108] " rguenth at gcc dot gnu.org
2022-03-31  9:20 ` jakub at gcc dot gnu.org
2022-03-31  9:25 ` jakub at gcc dot gnu.org
2022-03-31 10:20 ` rguenth at gcc dot gnu.org
2022-03-31 10:32 ` jakub at gcc dot gnu.org
2022-03-31 10:36 ` jakub at gcc dot gnu.org
2022-03-31 10:41 ` jakub at gcc dot gnu.org
2022-03-31 16:55 ` assaiante at diag dot uniroma1.it
2022-03-31 16:55 ` 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).