public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug debug/102534] New: RFE epilog is not reliably a statement
@ 2021-09-29 22:34 woodard at redhat dot com
  2021-09-29 23:28 ` [Bug debug/102534] RFE epilog is not reliably a statement with optimization pinskia at gcc dot gnu.org
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: woodard at redhat dot com @ 2021-09-29 22:34 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 102534
           Summary: RFE epilog is not reliably a statement
           Product: gcc
           Version: 12.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: debug
          Assignee: unassigned at gcc dot gnu.org
          Reporter: woodard at redhat dot com
  Target Milestone: ---

Created attachment 51523
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=51523&action=edit
demonstration program

Given a program like this:

     1  #include <stdio.h>
     2   
     3  static void do_print(char *s)
     4  {
     5     printf("%s", s);
     6  }
     7   
     8  int main(int argc, char *argv[])
     9  {
    10     int i = 0;
    11     for (;;) {
    12        do_print(argv[i]);
    13        i++;
    14        if (argv[i] == NULL) {
    15           do_print("\n");
    16           return 0;
    17        }
    18        do_print(", ");
    19     }
    20     #ifdef BAD_MATT_CODE
    21     //no longer used
    22     return -1;
    23     }
    24     #endif
    25  }
    26   
    27  /**
    28  * Just a comment taking a few lines of code
    29  * What do you call cheese that isn't yours?
    30  * Nacho cheese.
    31  **/
    32  int unused_variable;
    33   
    34  void unused_function()
    35  {
    36     printf("I'm not called anywhere\n");
    37  }

When you try to set a breakpoint on the closing brace of a function, it skips
to the beginning of the next function in the file:

$ gdb a.out 
GNU gdb (GDB) Fedora 10.2-3.fc34
Reading symbols from a.out...
(gdb) break 6
Breakpoint 1 at 0x401060: file line-range.c, line 9.

That is the start of main() which is not what was intended which I would assert
means “break before you leave the context of do_print()” in other words the
epilog of the function. 

On the other hand “b 5” works as expected

(gdb) break 5
Breakpoint 2 at 0x401070: /home/ben/Shared/test/line-ranges/line-range.c:5. (3
locations)
(gdb) info break
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x0000000000401060 in main at line-range.c:9
2       breakpoint     keep y   <MULTIPLE>         
2.1                         y   0x0000000000401070 in do_print at
line-range.c:5
2.2                         y   0x0000000000401081 in do_print at
line-range.c:5
2.3                         y   0x000000000040109a in do_print at
line-range.c:5

In that particular case the function ends up being inlined and the "ret"
instruction where the epilog is_stmt would be has been eliminated. We believe
it should still mark the first instruction after the code from the function.
Where their would have been a ret.

It isn't just inline functions are affected.

(gdb) break 25
Breakpoint 1 at 0x4011a0: file line-range.c, line 35.

Once again this the first instruction of the function defined after the one
where the epilog for main should be. There is even a ret instruction there:

(gdb) disassemble main
Dump of assembler code for function main:
   0x0000000000401060 <+0>:     push   %rbx
   0x0000000000401061 <+1>:     mov    %rsi,%rbx
   0x0000000000401064 <+4>:     jmp    0x401081 <main+33>
   0x0000000000401066 <+6>:     nopw   %cs:0x0(%rax,%rax,1)
   0x0000000000401070 <+16>:    mov    $0x402013,%esi
   0x0000000000401075 <+21>:    mov    $0x402010,%edi
   0x000000000040107a <+26>:    xor    %eax,%eax
   0x000000000040107c <+28>:    call   0x401050 <printf@plt>
   0x0000000000401081 <+33>:    mov    (%rbx),%rsi
   0x0000000000401084 <+36>:    xor    %eax,%eax
   0x0000000000401086 <+38>:    mov    $0x402010,%edi
   0x000000000040108b <+43>:    add    $0x8,%rbx
   0x000000000040108f <+47>:    call   0x401050 <printf@plt>
   0x0000000000401094 <+52>:    cmpq   $0x0,(%rbx)
   0x0000000000401098 <+56>:    jne    0x401070 <main+16>
   0x000000000040109a <+58>:    mov    $0xa,%edi
   0x000000000040109f <+63>:    call   0x401030 <putchar@plt>
   0x00000000004010a4 <+68>:    xor    %eax,%eax
   0x00000000004010a6 <+70>:    pop    %rbx
   0x00000000004010a7 <+71>:    ret    
End of assembler dump.

it even has linemap entries

$ readelf --debug-dump=decodedline a.out | egrep ^File\|25
File name                            Line number    Starting address    View   
Stmt
line-range.c                                  25            0x4010a4       2
line-range.c                                  25            0x4010a8        

But the problem seems to be that none of the linemap entries is adorned with
is_stmt. We believe that that should point at 4010a7.

Putting the is-stmt for the closing brace of a functopm on the ret instruction
of normal extern function is easy but we would like all the other complicating
situations to be handled as well some of which include: 

- inline functions
- void functions
- multiple returns from a function
- functions which optimize into being empty.
- external functions that are not used but could be called from another
function in a different CU. However that means that they could be dropped when
compiling with LTO. Several of these complications are demonstrated in the
attached program.

We have found that this works a bit better for C++ rather than C because C++
frequently has code for destructors for local variables that are executed in
the epilog of the function and the statement that it is tied to is the closing
brace of the function.

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

* [Bug debug/102534] RFE epilog is not reliably a statement with optimization
  2021-09-29 22:34 [Bug debug/102534] New: RFE epilog is not reliably a statement woodard at redhat dot com
@ 2021-09-29 23:28 ` pinskia at gcc dot gnu.org
  2021-09-29 23:30 ` [Bug debug/102534] RFE epilog is not reliably a statement with inlining pinskia at gcc dot gnu.org
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: pinskia at gcc dot gnu.org @ 2021-09-29 23:28 UTC (permalink / raw)
  To: gcc-bugs

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

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|RFE epilog is not reliably  |RFE epilog is not reliably
                   |a statement                 |a statement with
                   |                            |optimization

--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
For -O0 -g we get:

        call    printf
        .loc 1 6 1
        nop
        leave
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc


Oh you are doing this at -O2.

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

* [Bug debug/102534] RFE epilog is not reliably a statement with inlining
  2021-09-29 22:34 [Bug debug/102534] New: RFE epilog is not reliably a statement woodard at redhat dot com
  2021-09-29 23:28 ` [Bug debug/102534] RFE epilog is not reliably a statement with optimization pinskia at gcc dot gnu.org
@ 2021-09-29 23:30 ` pinskia at gcc dot gnu.org
  2021-09-29 23:32 ` pinskia at gcc dot gnu.org
  2021-09-30 21:37 ` woodard at redhat dot com
  3 siblings, 0 replies; 5+ messages in thread
From: pinskia at gcc dot gnu.org @ 2021-09-29 23:30 UTC (permalink / raw)
  To: gcc-bugs

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

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|RFE epilog is not reliably  |RFE epilog is not reliably
                   |a statement with            |a statement with inlining
                   |optimization                |

--- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
-Og -g2 GCC produces:

        .loc 1 5 4 is_stmt 0 view .LVU3
        movl    $0, %eax
        call    printf
.LVL2:
        .loc 1 6 1 view .LVU4
        addq    $8, %rsp
        .cfi_def_cfa_offset 8
        ret
        .cfi_endproc

Which looks good too.

So this must be an issue with inlining.

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

* [Bug debug/102534] RFE epilog is not reliably a statement with inlining
  2021-09-29 22:34 [Bug debug/102534] New: RFE epilog is not reliably a statement woodard at redhat dot com
  2021-09-29 23:28 ` [Bug debug/102534] RFE epilog is not reliably a statement with optimization pinskia at gcc dot gnu.org
  2021-09-29 23:30 ` [Bug debug/102534] RFE epilog is not reliably a statement with inlining pinskia at gcc dot gnu.org
@ 2021-09-29 23:32 ` pinskia at gcc dot gnu.org
  2021-09-30 21:37 ` woodard at redhat dot com
  3 siblings, 0 replies; 5+ messages in thread
From: pinskia at gcc dot gnu.org @ 2021-09-29 23:32 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #3 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
With -O1 or -O2 (and -g2), there are no .loc for line 6 at all.


There might not be anything that can be done for that case as inlining removes
it ....

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

* [Bug debug/102534] RFE epilog is not reliably a statement with inlining
  2021-09-29 22:34 [Bug debug/102534] New: RFE epilog is not reliably a statement woodard at redhat dot com
                   ` (2 preceding siblings ...)
  2021-09-29 23:32 ` pinskia at gcc dot gnu.org
@ 2021-09-30 21:37 ` woodard at redhat dot com
  3 siblings, 0 replies; 5+ messages in thread
From: woodard at redhat dot com @ 2021-09-30 21:37 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #4 from Ben Woodard <woodard at redhat dot com> ---
There continues to be an instruction after the completion of the inlining, the
next instruction in the sequence, At the time when the inlining occurs why
can’t the .loc 1 6 1 be placed there as part of the process of folding the
instructions for the inlined code into the calling function. This is analogous
to the placement of loc 1 5 4 for the first first line inside the function in
every location where the the function is called. It just gets attached to the
next instruction after the function’s completion.

In other words we argue that .loc 1 6 1 should be attached to the instructions
at: 401081 401094 4010a4

Another case that we would like to see work even though it optimizes to no
machine instructions which we tried to include in this fragment of source is
the case where we call a function that gets completely optimized away to a call
for another function. Even when that happens, we would like the residue of its
former existence to be in the line map matrix. That is why we included both a
static and a potentially external function, were this to be compiled as PIE
then the unused function could still be called. We thought that the two
situations while highly related, were different.

Also you didn’t explain why the main() function at line 25 did not get a
breakpoint associated with the closing brace for it. It does have a ret
instruction and it is not inlined. If that needs to be a separate PR, I do not
mind splitting it off.

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

end of thread, other threads:[~2021-09-30 21:37 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-29 22:34 [Bug debug/102534] New: RFE epilog is not reliably a statement woodard at redhat dot com
2021-09-29 23:28 ` [Bug debug/102534] RFE epilog is not reliably a statement with optimization pinskia at gcc dot gnu.org
2021-09-29 23:30 ` [Bug debug/102534] RFE epilog is not reliably a statement with inlining pinskia at gcc dot gnu.org
2021-09-29 23:32 ` pinskia at gcc dot gnu.org
2021-09-30 21:37 ` woodard at redhat dot com

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).