This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: PATCH: error reading variable: value has been optimized out


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]