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