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]

[unavailable values part 1, 08/17] unavailable integer internalvars


the bad:

 (gdb) x /10x &foo2            
 0x6010a0 <foo2>:        <unavailable>   <unavailable>   <unavailable>   <unavailable>
 0x6010b0 <foo2+16>:     0xaaaaaaaa      <unavailable>   <unavailable>   <unavailable>
 0x6010c0 <foo2+32>:     <unavailable>   <unavailable>
 value is not available
 (gdb)

The "value is not available" part shouldn't be there.

the good:

 (gdb) x /10x &foo2            
 0x6010a0 <foo2>:        <unavailable>   <unavailable>   <unavailable>   <unavailable>
 0x6010b0 <foo2+16>:     0xaaaaaaaa      <unavailable>   <unavailable>   <unavailable>
 0x6010c0 <foo2+32>:     <unavailable>   <unavailable>
 (gdb)

Trying again, gdb-under-gdb:

 (gdb) i
 (top-gdb) b error
 Breakpoint 6 at 0x464093: file ../../src/gdb/utils.c, line 983.
 (top-gdb) c
 Continuing.
 (gdb) x /10x &foo2
 0x6010a0 <foo2>:        <unavailable>   <unavailable>   <unavailable>   <unavailable>
 0x6010b0 <foo2+16>:     0xaaaaaaaa      <unavailable>   <unavailable>   <unavailable>
 0x6010c0 <foo2+32>:     <unavailable>   <unavailable>

 Breakpoint 6, error (string=0x7ec29c "value is not available") at ../../src/gdb/utils.c:983
 983       va_start (args, string);
 (top-gdb) bt 7
 #0  error (string=0x7ec29c "value is not available") at ../../src/gdb/utils.c:983
 #1  0x00000000005473b8 in require_available (value=0xf07610) at ../../src/gdb/value.c:676
 #2  0x0000000000547500 in value_contents (value=0xf07610) at ../../src/gdb/value.c:732
 #3  0x0000000000549027 in value_as_long (val=0xf07610) at ../../src/gdb/value.c:1843
 #4  0x000000000054887f in set_internalvar (var=0xf076e0, val=0xf07610) at ../../src/gdb/value.c:1566
 #5  0x00000000005653be in x_command (exp=0xbb3217 "", from_tty=1) at ../../src/gdb/printcmd.c:1461
 #6  0x00000000004e6c61 in do_cfunc (c=0xc0c560, args=0xbb3212 "/10x ", from_tty=1)
     at ../../src/gdb/cli/cli-decode.c:67
 (More stack frames follow...)

x_command does:

  /* Set a couple of internal variables if appropriate. */
  if (last_examine_value)
    {
      /* Make last address examined available to the user as $_.  Use
         the correct pointer type.  */
      struct type *pointer_type
	= lookup_pointer_type (value_type (last_examine_value));
      set_internalvar (lookup_internalvar ("_"),
		       value_from_pointer (pointer_type,
					   last_examine_address));

      /* Make contents of last address examined available to the user
	 as $__.  If the last value has not been fetched from memory
	 then don't fetch it now; instead mark it by voiding the $__
	 variable.  */
      if (value_lazy (last_examine_value))
	clear_internalvar (lookup_internalvar ("__"));
      else
	set_internalvar (lookup_internalvar ("__"), last_examine_value);
    }


but, the last examined value (last_examine_value) is <unavailable>.
last_examine_value is integer, and so set_internalval does:

    case TYPE_CODE_INT:
      new_kind = INTERNALVAR_INTEGER;
      new_data.integer.type = value_type (val);
      new_data.integer.val = value_as_long (val);
      break;

and value_as_long can't work with <unavailable> values.

So the solution is to let set_internalval store integer
values as INTERNALVAR_VALUE (which preserves unavailableness),
and teach get_internalvar_integer to look into
INTERNALVAR_VALUE values, if they're integer.

INTERNALVAR_INTEGER is still necessary for the case of
convenience variables that are host/gdb integers, not
associated with an inferior value at all.  Those have a
NULL type, and are set with set_internalvar_integer, as
for example, the $bpnum last-breakpoint-created-number
convenience variable:

 breakpoint.c:  set_internalvar_integer (lookup_internalvar ("bpnum"), num);

-- 
Pedro Alves

2011-02-07  Pedro Alves  <pedro@codesourcery.com>

	gdb/
	* value.c (get_internalvar_integer): Also return the int value of
	TYPE_CODE_INT INTERNALVAR_VALUE values.
	(set_internalvar): Don't special case TYPE_CODE_INT.

---
 gdb/value.c |   23 +++++++++++++----------
 1 file changed, 13 insertions(+), 10 deletions(-)

Index: src/gdb/value.c
===================================================================
--- src.orig/gdb/value.c	2011-01-31 19:57:59.424645004 +0000
+++ src/gdb/value.c	2011-01-31 19:58:02.114645000 +0000
@@ -1536,15 +1536,24 @@ value_of_internalvar (struct gdbarch *gd
 int
 get_internalvar_integer (struct internalvar *var, LONGEST *result)
 {
-  switch (var->kind)
+  if (var->kind == INTERNALVAR_INTEGER)
     {
-    case INTERNALVAR_INTEGER:
       *result = var->u.integer.val;
       return 1;
+    }
 
-    default:
-      return 0;
+  if (var->kind == INTERNALVAR_VALUE)
+    {
+      struct type *type = check_typedef (value_type (var->u.value));
+
+      if (TYPE_CODE (type) == TYPE_CODE_INT)
+	{
+	  *result = value_as_long (var->u.value);
+	  return 1;
+	}
     }
+
+  return 0;
 }
 
 static int
@@ -1611,12 +1620,6 @@ set_internalvar (struct internalvar *var
       /* Copies created here are never canonical.  */
       break;
 
-    case TYPE_CODE_INT:
-      new_kind = INTERNALVAR_INTEGER;
-      new_data.integer.type = value_type (val);
-      new_data.integer.val = value_as_long (val);
-      break;
-
     default:
       new_kind = INTERNALVAR_VALUE;
       new_data.value = value_copy (val);


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