public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug debug/104891] New: Possibly wrong location definition in DWARF with -fschedule-insns2 at -O2/-O3
@ 2022-03-12 12:42 assaiante at diag dot uniroma1.it
  0 siblings, 0 replies; only message in thread
From: assaiante at diag dot uniroma1.it @ 2022-03-12 12:42 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 104891
           Summary: Possibly wrong location definition in DWARF with
                    -fschedule-insns2 at -O2/-O3
           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 variables l_29 and l_30, which are defined and used
in the scope within brackets spanning lines 4-8, are associated to DWARF
symbols having a possibly wrong location definition, which causes variables to
not be available during debugging, despite their DIEs being correctly defined.
We observe the bug at -O2 and -O3 with the cause likely being
-fschedule-insns2. Please find below a detailed analysis for -O3 on x64,
including a comparison with prior gcc versions where the bug is sometimes not
present.

$ cat a.c
volatile char a;
int main() {
  int print_hash_value = 0;
  {
    int l_29 = 7, l_30 = 9551615;
    a = l_30 >= l_29;
    printf("%X\n", 0);
  }
}

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 -O3 -g a.c -o opt
$ gdb -q opt
Reading symbols from opt...
(gdb) b 6
Breakpoint 1 at 0x400410: file a.c, line 6.
(gdb) r
Starting program: /home/stepping/debuginfo-analysis/dd-mismatches/66/reduce/opt 

Breakpoint 1, main () at a.c:6
6           a = l_30 >= l_29;
(gdb) info locals
print_hash_value = 0

By dumping the DWARF info, we can see how the location of the lexical block
associated to the inner scope is defined by ranges where the first one is empty
(400410-400410), while the values for l_29 and l_30 are correctly specified:

ASM:
0000000000400410 <main>:
  400410:       48 83 ec 08             sub    $0x8,%rsp
  400414:       31 f6                   xor    %esi,%esi
  400416:       bf a4 05 40 00          mov    $0x4005a4,%edi
  40041b:       31 c0                   xor    %eax,%eax
  40041d:       c6 05 0d 0c 20 00 01    movb   $0x1,0x200c0d(%rip)        #
601031 <a>
  400424:       e8 d7 ff ff ff          call   400400 <printf@plt>
  400429:       31 c0                   xor    %eax,%eax
  40042b:       48 83 c4 08             add    $0x8,%rsp
  40042f:       c3                      ret 

DWARF info:
0x0000007d:     DW_TAG_lexical_block
                  DW_AT_ranges  (0x0000000c
                     [0x0000000000400410, 0x0000000000400410)
                     [0x0000000000400414, 0x0000000000400429))

0x00000082:       DW_TAG_variable
                    DW_AT_name  ("l_29")
                    DW_AT_decl_file     ("/home/test/dd/66/reduce/a.c")
                    DW_AT_decl_line     (5)
                    DW_AT_decl_column   (0x09)
                    DW_AT_type  (0x000000d6 "int")
                    DW_AT_const_value   (0x07)

0x0000008e:       DW_TAG_variable
                    DW_AT_name  ("l_30")
                    DW_AT_decl_file     ("/home/test/dd/66/reduce/a.c")
                    DW_AT_decl_line     (5)
                    DW_AT_decl_column   (0x13)
                    DW_AT_type  (0x000000d6 "int")
                    DW_AT_const_value   (0x0091beff)

When we manually patch the first range to be (400410-400414), the variables are
displayed correctly in gdb.

Through some testing we found out that the optimization flag that introduces
the bug is likely -fschedule-insns2. If we add -fno-schedule-insns2 to the
compilation command line used above, variables l_29 and l_30 appear in the
current frame with their values correctly available at line 6. The location of
the lexical block appears now to be correctly defined (see low pc and high pc
attributes):

ASM with -fno-schedule-insns2:
0000000000400410 <main>:
  400410:       48 83 ec 08             sub    $0x8,%rsp
  400414:       c6 05 16 0c 20 00 01    movb   $0x1,0x200c16(%rip)        #
601031 <a>
  40041b:       31 f6                   xor    %esi,%esi
  40041d:       bf a4 05 40 00          mov    $0x4005a4,%edi
  400422:       31 c0                   xor    %eax,%eax
  400424:       e8 d7 ff ff ff          call   400400 <printf@plt>
  400429:       31 c0                   xor    %eax,%eax
  40042b:       48 83 c4 08             add    $0x8,%rsp
  40042f:       c3                      ret    

DWARF info with -fno-schedule-insns2:
0x0000007d:     DW_TAG_lexical_block
                  DW_AT_low_pc  (0x0000000000400414)
                  DW_AT_high_pc (0x0000000000400429)

And the DWARF information for variable values is identical to when using -O3 -g
alone.

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 except 6 and 7: when debugging the
executable generated from either, variables are displayed and more generally
debug info looks correct.

ASM from gcc-7:
0000000000000540 <main>:
 540:   48 8d 3d bd 01 00 00    lea    0x1bd(%rip),%rdi        # 704
<_IO_stdin_used+0x4>
 547:   48 83 ec 08             sub    $0x8,%rsp
 54b:   31 f6                   xor    %esi,%esi
 54d:   31 c0                   xor    %eax,%eax
 54f:   c6 05 bb 0a 20 00 01    movb   $0x1,0x200abb(%rip)        # 201011 <a>
 556:   e8 c5 ff ff ff          call   520 <printf@plt>
 55b:   31 c0                   xor    %eax,%eax
 55d:   48 83 c4 08             add    $0x8,%rsp
 561:   c3                      ret

DWARF info from gcc-7:
0x0000007a:     DW_TAG_lexical_block
                  DW_AT_ranges  (0x00000000
                     [0x0000000000000540, 0x0000000000000547)
                     [0x000000000000054b, 0x000000000000055b))

0x0000007f:       DW_TAG_variable
                    DW_AT_name  ("l_29")
                    DW_AT_decl_file     ("/home/test/dd/66/reduce/a.c")
                    DW_AT_decl_line     (5)
                    DW_AT_type  (0x000000d2 "int")
                    DW_AT_const_value   (0x07)

0x0000008b:       DW_TAG_variable
                    DW_AT_name  ("l_30")
                    DW_AT_decl_file     ("/home/test/dd/66/reduce/a.c")
                    DW_AT_decl_line     (5)
                    DW_AT_type  (0x000000d2 "int")
                    DW_AT_const_value   (0x0091beff)

We also tested the program against different gdb versions but this factor does
not appear to affect the bug.

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

only message in thread, other threads:[~2022-03-12 12:42 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-12 12:42 [Bug debug/104891] New: Possibly wrong location definition in DWARF with -fschedule-insns2 at -O2/-O3 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).