PATCH: error reading variable: value has been optimized out

Andrew Burgess aburgess@broadcom.com
Fri Aug 24 12:11:00 GMT 2012


I found some behaviour that has changed, I believe, for the worse.  I have found an example where, in the backtrace, gdb used to say this:

   #0  0x0000000000400504 in function ()
   #1  0x00000000004004fc in broken (operand0=<optimized out>, operand1=<optimized out>) at bad.c:10
   #2  0x00000000004004e5 in main () at main.c:4

But now gdb says this:

   #0  0x0000000000400504 in function ()
   #1  0x00000000004004fc in broken (operand0=<error reading variable: value has been optimized out>, operand1=<error reading variable: value has been optimized out>) at bad.c:10
   #2  0x00000000004004e5 in main () at main.c:4

We now get an error about the value being optimised out.  I believe this should not be marked as an error as the value is quite legitimately no longer available.

At the end of this email is a patch to restore the old behaviour.  What follows here is a description of what causes the new behaviour.

[ Using git clone from git://sourceware.org/git/gdb.git ]

Things first changed with commit 25993ce40950a8b34b31efd49790a16be3d5c519 (http://sourceware.org/ml/gdb-cvs/2011-07/msg00184.html), after this the backtrace looked like this:

#0  0x0000000000400504 in function ()
#1  0x00000000004004fc in broken (operand0=value has been optimized out
) at bad.c:10
#2  0x00000000004004e5 in main () at main.c:4

Clearly things went a little off the rails at this point, I think the old "<optimized out>" is better than the new "value has been optimized out" text, but it doesn't really matter, as things changed again with commit 3d0a5ee6551a1f2036a574f7802c1abc47eada41 (http://sourceware.org/ml/gdb-cvs/2011-09/msg00043.html), the behaviour is now:

#0  0x0000000000400504 in function ()
#1  0x00000000004004fc in broken (operand0=<error reading variable: value has been optimized out>, operand1=<error reading variable: value has been optimized out>) at bad.c:10
#2  0x00000000004004e5 in main () at main.c:4

We get operand1 back again, along with the error message text.

The example given by Jan when proposing the patch (http://sourceware.org/ml/gdb-patches/2011-08/msg00575.html) was this, "<error reading variable: Asked for position 0 of stack, stack only has 0 elements on it.>", in this case the format seems fine, there really was an error while reading the variable, however, in the example I have, there was no _error_, it's just the variable really has gone.  I suggest then that the behaviour we have arrived at is a regression, and we should try to get back to a situation where, for my optimised out variables we see the original behaviour, but in the example Jan gave, we see the new error message style behaviour.

The test attached (bad-bt.tar.bz2) is fairly contrived, and is x86 specific, but hopefully it's good enough to allow people to reproduce the error if they want to.  I'm happy to discus the test if anyone things it's not valid.  To run the test,

  tar -xjvf bad-bt.tar.bz2
  cd bad-bt
  make check GDB=<path-to-gdb>
  # This will run gdb and show the backtrace... 

When gdb tries to figure out where the variable is we eventually end up in dwarf2loc.c:dwarf2_evaluate_loc_desc_full, this tells us that at the address in question the variable is in a register, we then call findvar.c:value_from_register, which calls findvar.c:read_frame_register_value, this then calls get_frame_register_value followed by value_contents_copy.

The problem is that value_contents_copy throws an error if the value returned by get_frame_register_value is optimised out, as it can quite legitimately be if a younger frame has marked the register in question as undefined.

There is currently only one user of read_frame_register_value, which is the path I just described, I suggest then that we change the behaviour of this function to mark the whole result value as optimised out if any of the registers read to acquire the value are optimised out.  I've included the patch do do this below.

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



Ok to commit? Or is more work required?

Cheers,
Andrew

gdb/ChangeLog

2012-08-24  Andrew Burgess  <aburgess@broadcom.com>

	* findvar.c (read_frame_register_value): Mark the result value as
	optimized out if any of the input registers have been optimized out.

diff --git a/gdb/findvar.c b/gdb/findvar.c
index 66bcebe..ec9dde7 100644
--- a/gdb/findvar.c
+++ b/gdb/findvar.c
@@ -677,7 +677,10 @@ default_value_from_register (struct type *type, int regnum,
 /* VALUE must be an lval_register value.  If regnum is the value's
    associated register number, and len the length of the values type,
    read one or more registers in FRAME, starting with register REGNUM,
-   until we've read LEN bytes.  */
+   until we've read LEN bytes.
+
+   If any of the registers we try to read are optimized out, then mark the
+   complete resulting value as optimized out.  */
 
 void
 read_frame_register_value (struct value *value, struct frame_info *frame)
@@ -703,6 +706,12 @@ read_frame_register_value (struct value *value, struct fram
       struct value *regval = get_frame_register_value (frame, regnum);
       int reg_len = TYPE_LENGTH (value_type (regval)) - reg_offset;
 
+      if (value_optimized_out (regval))
+       {
+         set_value_optimized_out (value, 1);
+         break;
+       }
+
       /* If the register length is larger than the number of bytes
          remaining to copy, then only copy the appropriate bytes.  */
       if (reg_len > len)
(



-------------- next part --------------
A non-text attachment was scrubbed...
Name: bad-bt.tar.bz2
Type: application/octet-stream
Size: 2546 bytes
Desc: not available
URL: <http://sourceware.org/pipermail/gdb-patches/attachments/20120824/a04d0ab5/attachment.obj>


More information about the Gdb-patches mailing list