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