This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: PATCH: error reading variable: value has been optimized out
- From: Jan Kratochvil <jan dot kratochvil at redhat dot com>
- To: Andrew Burgess <aburgess at broadcom dot com>
- Cc: "gdb-patches at sourceware dot org" <gdb-patches at sourceware dot org>
- Date: Sun, 26 Aug 2012 19:18:40 +0200
- Subject: Re: PATCH: error reading variable: value has been optimized out
- References: <50376F3B.1080407@broadcom.com>
On Fri, 24 Aug 2012 14:10:35 +0200, Andrew Burgess wrote:
> Looking through, value.c is seems there might also support for having values
> partially optimised out, this would seem like a better solution, but I'm not
> sure the right way to hook this in, if anyone would like to offer
> suggestions I'm happy to create a new patch, alternatively, this could be
> improved on later...
GDB supports partially unavailable values from partially stored traces.
This is AFAIK not applicable for partially optimized out values.
#0 0x0000000000400524 in function ()
#1 0x000000000040051c in broken (operand0=<error reading variable: value has been optimized out>, operand0@entry=1, [...]) at bad.c:10
#2 0x0000000000400415 in main () at main.c:4
The problem is not normally visible because this reproducer comes from old GCC:
.ident "GCC: (GNU) 4.2.1"
(gdb) info addr operand0
Symbol "operand0" is multi-location:
Range 0x400510-0x40051c: a variable in $rdi
(gdb) disass
[...]
0x0000000000400517 <+7>: callq 0x400524 <function>
=> 0x000000000040051c <+12>: nop
That is here it says 'operand0' is valid in all caller instructions till and
including 0x40051b (but not including 0x40051c). This means that 'operand0'
would be valid in $rdi even when the CPU already executes arbitrary 'function'
instructions which have right to clobber callee-clobbered registers. This is
incorrect from GCC.
Callee here undefines the value of %rdi for unwind, unaware why, this is
normally assumed as %rdi is callee-clobbered register.
00000038 00000014 ffffffff CIE
DW_CFA_def_cfa: r7 (rsp) ofs 8
DW_CFA_offset: r16 (rip) at cfa-8
DW_CFA_undefined: r4 (rsi)
DW_CFA_undefined: r5 (rdi)
00000050 0000001c 00000038 FDE cie=00000038 pc=00400524..00400531
^^^^^^^^
Newer GCCs do not say anything is in callee-clobberred register when inside the
call, being more correct and making it easier for GDB:
GNU C 4.7.1 20120720 (Red Hat 4.7.1-5) -mtune=generic -march=x86-64 -g -O2 -fno-var-tracking-assignments
#0 f () at 67.c:4
#1 0x0000000000400515 in g (x=<optimized out>) at 67.c:10
at frame #1:
(gdb) info addr x
Symbol "x" is multi-location:
Range 0x400510-0x400514: a variable in $rdi
Dump of assembler code for function g:
0x0000000000400510 <+0>: callq 0x400500 <f>
=> 0x0000000000400515 <+5>: xor %eax,%eax
Here you can see 'x' is valid till and including 0x400513 (that is before
'callq' is executed) but when 'callq' is executing (0x400514) then 'x' is
already <optimized out>. So GDB does not try to unwind such value.
I agree with the fix but it should have GDB-testsuite compatible testcase.
Also FYI it is only for backward compatibility with old GCCs.
Thanks,
Jan