Re: Don't error out when variable not available

Daniel Jacobowitz
2005-02-28T17:20:42Z

On Wed, Jan 05, 2005 at 08:14:19PM +0100, Andreas Schwab wrote:
> There is really no reason to call error in loclist_read_variable when we
> can return VALUE_OPTIMIZED_OUT, like we already to in
> dwarf2_evaluate_loc_desc. Fixing that problem is orthogonal to the
> general problem of not catching errors. That print_frame_args needs to
> check for VALUE_OPTIMIZED_OUT is only because it calls val_print directly
> without going through value_print. It already has to take care of NULL
> value even though value_print would handle that as well. Sooner or later
> it would probably have been required to add this case anyway.

Yes, this is true. However, I'd rather not add it at the call sites of
val_print. Instead, I've created a nicer interface to val_print which
shares sanity-checking code with value_print. Most of the places
currently calling val_print can call this instead; a TODO item is to
make all uses of val_print pass the value around.

I went looking at the original location list support. The error() call
in question was simply a goof on my part; I had forgotten about
the VALUE_OPTIMIZED_OUT bits a couple of functions down.

I've checked in this patch instead. Tested by the GDB testsuite on
i686-pc-linux-gnu (no changes); the GDB testsute on arm-eabi using ARM
RVDS (some improvements); and by hand using GCC 3.4 and optimization
(definite improvement).

--
Daniel Jacobowitz
CodeSourcery, LLC

2005-02-28 Daniel Jacobowitz <dan@codesourcery.com>

* dwarf2loc.c (loclist_read_variable): Set optimized_out
instead of reporting an error.
* valprint.c (value_check_printable): New function.
(common_val_print): New function. Use value_check_printable.
(value_print): Use value_check_printable.
* value.h (common_val_print): Add prototype.

* c-valprint.c (c_val_print): Use common_val_print.
* cp-valprint.c (cp_print_value_fields): Likewise.
(cp_print_hpacc_virtual_table_entries): Likewise.
* f-valprint.c (f_val_print): Likewise.
* jv-valprint.c (java_value_print, java_print_value_fields):
Likewise.
* scm-valprint.c (scm_value_print): Likewise.
* stack.c (print_frame_args): Likewise.
* varobj.c (c_value_of_variable): Likewise.
* p-valprint.c (pascal_val_print, pascal_value_print): Likewise.
(pascal_object_print_value_fields): Likewise. Update call to
pascal_object_print_static_field.
(pascal_object_print_static_field): Remove TYPE argument. Use
common_val_print.

Index: c-valprint.c
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/gdb/c-valprint.c,v
retrieving revision 1.34
diff -u -p -r1.34 c-valprint.c
--- c-valprint.c 14 Feb 2005 14:37:37 -0000 1.34
+++ c-valprint.c 27 Feb 2005 15:51:32 -0000
@@ -233,9 +233,8 @@ c_val_print (struct type *type, const bf
wtype = TYPE_TARGET_TYPE (type);
}
vt_val = value_at (wtype, vt_address);
- val_print (value_type (vt_val), value_contents (vt_val), 0,
- VALUE_ADDRESS (vt_val), stream, format,
- deref_ref, recurse + 1, pretty);
+ common_val_print (vt_val, stream, format,
+ deref_ref, recurse + 1, pretty);
if (pretty)
{
fprintf_filtered (stream, "\n");
@@ -283,15 +282,8 @@ c_val_print (struct type *type, const bf
(TYPE_TARGET_TYPE (type),
unpack_pointer (lookup_pointer_type (builtin_type_void),
valaddr + embedded_offset));
- val_print (value_type (deref_val),
- value_contents (deref_val),
- 0,
- VALUE_ADDRESS (deref_val),
- stream,
- format,
- deref_ref,
- recurse,
- pretty);
+ common_val_print (deref_val, stream, format, deref_ref,
+ recurse, pretty);
}
else
fputs_filtered ("???", stream);
Index: cp-valprint.c
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/gdb/cp-valprint.c,v
retrieving revision 1.40
diff -u -p -r1.40 cp-valprint.c
--- cp-valprint.c 24 Feb 2005 13:51:31 -0000 1.40
+++ cp-valprint.c 27 Feb 2005 15:54:29 -0000
@@ -389,8 +389,7 @@ cp_print_value_fields (struct type *type
(TYPE_FIELD_TYPE (type, i),
unpack_field_as_long (type, valaddr + offset, i));

- val_print (TYPE_FIELD_TYPE (type, i), value_contents (v),
- 0, 0, stream, format, 0, recurse + 1, pretty);
+ common_val_print (v, stream, format, 0, recurse + 1, pretty);
}
}
else
@@ -454,8 +453,7 @@ cp_print_value_fields (struct type *type
v = value_from_pointer (lookup_pointer_type (builtin_type_unsigned_long),
*(unsigned long *) (valaddr + offset));

- val_print (value_type (v), value_contents (v), 0, 0,
- stream, format, 0, recurse + 1, pretty);
+ common_val_print (v, stream, format, 0, recurse + 1, pretty);
fields_seen = 1;

if (vtblprint)
@@ -822,8 +820,7 @@ cp_print_hpacc_virtual_table_entries (st
deprecated_set_value_type (vf, value_type (v));

/* print out the entry */
- val_print (value_type (vf), value_contents (vf), 0, 0,
- stream, format, 0, recurse + 1, pretty);
+ common_val_print (vf, stream, format, 0, recurse + 1, pretty);
field_physname
= TYPE_FN_FIELD_PHYSNAME (TYPE_FN_FIELDLIST1 (type, fn), oi);
/* pai: (temp) FIXME Maybe this should be DMGL_ANSI */
Index: dwarf2loc.c
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/gdb/dwarf2loc.c,v
retrieving revision 1.21
diff -u -p -r1.21 dwarf2loc.c
--- dwarf2loc.c 11 Feb 2005 04:05:46 -0000 1.21
+++ dwarf2loc.c 27 Feb 2005 02:21:47 -0000
@@ -512,9 +512,14 @@ loclist_read_variable (struct symbol *sy
data = find_location_expression (dlbaton, &size,
frame ? get_frame_pc (frame) : 0);
if (data == NULL)
- error (_("Variable \"%s\" is not available."), SYMBOL_NATURAL_NAME (symbol));
-
- val = dwarf2_evaluate_loc_desc (symbol, frame, data, size, dlbaton->objfile);
+ {
+ val = allocate_value (SYMBOL_TYPE (symbol));
+ VALUE_LVAL (val) = not_lval;
+ set_value_optimized_out (val, 1);
+ }
+ else
+ val = dwarf2_evaluate_loc_desc (symbol, frame, data, size,
+ dlbaton->objfile);

return val;
}
Index: f-valprint.c
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/gdb/f-valprint.c,v
retrieving revision 1.28
diff -u -p -r1.28 f-valprint.c
--- f-valprint.c 15 Feb 2005 15:49:09 -0000 1.28
+++ f-valprint.c 27 Feb 2005 15:55:02 -0000
@@ -440,15 +440,8 @@ f_val_print (struct type *type, const bf
(TYPE_TARGET_TYPE (type),
unpack_pointer (lookup_pointer_type (builtin_type_void),
valaddr + embedded_offset));
- val_print (value_type (deref_val),
- value_contents (deref_val),
- 0,
- VALUE_ADDRESS (deref_val),
- stream,
- format,
- deref_ref,
- recurse,
- pretty);
+ common_val_print (deref_val, stream, format, deref_ref, recurse,
+ pretty);
}
else
fputs_filtered ("???", stream);
Index: jv-valprint.c
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/gdb/jv-valprint.c,v
retrieving revision 1.23
diff -u -p -r1.23 jv-valprint.c
--- jv-valprint.c 8 Feb 2005 02:29:17 -0000 1.23
+++ jv-valprint.c 27 Feb 2005 15:58:40 -0000
@@ -182,8 +182,7 @@ java_value_print (struct value *val, str
else
fprintf_filtered (stream, "%d..%d: ", i, i + reps - 1);

- val_print (value_type (v), value_contents (v), 0, 0,
- stream, format, 2, 1, pretty);
+ common_val_print (v, stream, format, 2, 1, pretty);

things_printed++;
i += reps;
@@ -235,8 +234,7 @@ java_value_print (struct value *val, str
return 0;
}

- return (val_print (type, value_contents (val), 0, address,
- stream, format, 1, 0, pretty));
+ return common_val_print (val, stream, format, 1, 0, pretty);
}

/* TYPE, VALADDR, ADDRESS, STREAM, RECURSE, and PRETTY have the
@@ -384,8 +382,7 @@ java_print_value_fields (struct type *ty
v = value_from_longest (TYPE_FIELD_TYPE (type, i),
unpack_field_as_long (type, valaddr, i));

- val_print (TYPE_FIELD_TYPE (type, i), value_contents (v), 0,
- 0, stream, format, 0, recurse + 1, pretty);
+ common_val_print (v, stream, format, 0, recurse + 1, pretty);
}
}
else
@@ -404,9 +401,8 @@ java_print_value_fields (struct type *ty
struct type *t = check_typedef (value_type (v));
if (TYPE_CODE (t) == TYPE_CODE_STRUCT)
v = value_addr (v);
- val_print (value_type (v),
- value_contents (v), 0, VALUE_ADDRESS (v),
- stream, format, 0, recurse + 1, pretty);
+ common_val_print (v, stream, format, 0, recurse + 1,
+ pretty);
}
}
else if (TYPE_FIELD_TYPE (type, i) == NULL)
Index: p-valprint.c
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/gdb/p-valprint.c,v
retrieving revision 1.37
diff -u -p -r1.37 p-valprint.c
--- p-valprint.c 24 Feb 2005 13:51:34 -0000 1.37
+++ p-valprint.c 27 Feb 2005 16:02:06 -0000
@@ -240,9 +240,8 @@ pascal_val_print (struct type *type, con
wtype = TYPE_TARGET_TYPE (type);
}
vt_val = value_at (wtype, vt_address);
- val_print (value_type (vt_val), value_contents (vt_val), 0,
- VALUE_ADDRESS (vt_val), stream, format,
- deref_ref, recurse + 1, pretty);
+ common_val_print (vt_val, stream, format, deref_ref,
+ recurse + 1, pretty);
if (pretty)
{
fprintf_filtered (stream, "\n");
@@ -292,10 +291,8 @@ pascal_val_print (struct type *type, con
(TYPE_TARGET_TYPE (type),
unpack_pointer (lookup_pointer_type (builtin_type_void),
valaddr + embedded_offset));
- val_print (value_type (deref_val),
- value_contents (deref_val), 0,
- VALUE_ADDRESS (deref_val), stream, format,
- deref_ref, recurse + 1, pretty);
+ common_val_print (deref_val, stream, format, deref_ref,
+ recurse + 1, pretty);
}
else
fputs_filtered ("???", stream);
@@ -566,9 +563,7 @@ pascal_value_print (struct value *val, s
fprintf_filtered (stream, ") ");
}
}
- return val_print (type, value_contents (val), value_embedded_offset (val),
- VALUE_ADDRESS (val) + value_offset (val),
- stream, format, 1, 0, pretty);
+ return common_val_print (val, stream, format, 1, 0, pretty);
}

@@ -591,7 +586,7 @@ show_pascal_static_field_print (struct u
static struct obstack dont_print_vb_obstack;
static struct obstack dont_print_statmem_obstack;

-static void pascal_object_print_static_field (struct type *, struct value *,
+static void pascal_object_print_static_field (struct value *,
struct ui_file *, int, int,
enum val_prettyprint);

@@ -854,8 +849,7 @@ pascal_object_print_value_fields (struct
v = value_from_longest (TYPE_FIELD_TYPE (type, i),
unpack_field_as_long (type, valaddr, i));

- val_print (TYPE_FIELD_TYPE (type, i), value_contents (v), 0, 0,
- stream, format, 0, recurse + 1, pretty);
+ common_val_print (v, stream, format, 0, recurse + 1, pretty);
}
}
else
@@ -874,9 +868,8 @@ pascal_object_print_value_fields (struct
if (v == NULL)
fputs_filtered ("<optimized out>", stream);
else
- pascal_object_print_static_field (TYPE_FIELD_TYPE (type, i), v,
- stream, format, recurse + 1,
- pretty);
+ pascal_object_print_static_field (v, stream, format,
+ recurse + 1, pretty);
}
else
{
@@ -1017,14 +1010,16 @@ pascal_object_print_value (struct type *
static member classes in an obstack and refuse to print them more
than once.

- VAL contains the value to print, TYPE, STREAM, RECURSE, and PRETTY
+ VAL contains the value to print, STREAM, RECURSE, and PRETTY
have the same meanings as in c_val_print. */

static void
-pascal_object_print_static_field (struct type *type, struct value *val,
+pascal_object_print_static_field (struct value *val,
struct ui_file *stream, int format,
int recurse, enum val_prettyprint pretty)
{
+ struct type *type = value_type (val);
+
if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
{
CORE_ADDR *first_dont_print;
@@ -1053,8 +1048,7 @@ pascal_object_print_static_field (struct
stream, format, recurse, pretty, NULL, 1);
return;
}
- val_print (type, value_contents (val), 0, VALUE_ADDRESS (val),
- stream, format, 0, recurse, pretty);
+ common_val_print (val, stream, format, 0, recurse, pretty);
}

void
Index: scm-valprint.c
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/gdb/scm-valprint.c,v
retrieving revision 1.9
diff -u -p -r1.9 scm-valprint.c
--- scm-valprint.c 7 Feb 2005 00:09:55 -0000 1.9
+++ scm-valprint.c 27 Feb 2005 15:24:00 -0000
@@ -391,6 +391,5 @@ int
scm_value_print (struct value *val, struct ui_file *stream, int format,
enum val_prettyprint pretty)
{
- return (val_print (value_type (val), value_contents (val), 0,
- VALUE_ADDRESS (val), stream, format, 1, 0, pretty));
+ return (common_val_print (val, stream, format, 1, 0, pretty));
}
Index: stack.c
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/gdb/stack.c,v
retrieving revision 1.129
diff -u -p -r1.129 stack.c
--- stack.c 15 Feb 2005 15:49:20 -0000 1.129
+++ stack.c 27 Feb 2005 02:21:47 -0000
@@ -354,9 +354,7 @@ print_frame_args (struct symbol *func, s

if (val)
{
- val_print (value_type (val), value_contents (val), 0,
- VALUE_ADDRESS (val),
- stb->stream, 0, 0, 2, Val_no_prettyprint);
+ common_val_print (val, stb->stream, 0, 0, 2, Val_no_prettyprint);
ui_out_field_stream (uiout, "value", stb);
}
else
Index: valprint.c
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/gdb/valprint.c,v
retrieving revision 1.51
diff -u -p -r1.51 valprint.c
--- valprint.c 24 Feb 2005 13:51:35 -0000 1.51
+++ valprint.c 27 Feb 2005 02:22:32 -0000
@@ -217,25 +217,66 @@ val_print (struct type *type, const bfd_
stream, format, deref_ref, recurse, pretty));
}

-/* Print the value VAL in C-ish syntax on stream STREAM.
- FORMAT is a format-letter, or 0 for print in natural format of data type.
- If the object printed is a string pointer, returns
- the number of string bytes printed. */
+/* Check whether the value VAL is printable. Return 1 if it is;
+ return 0 and print an appropriate error message to STREAM if it
+ is not. */

-int
-value_print (struct value *val, struct ui_file *stream, int format,
- enum val_prettyprint pretty)
+static int
+value_check_printable (struct value *val, struct ui_file *stream)
{
if (val == 0)
{
- printf_filtered (_(" "));
+ fprintf_filtered (stream, _(" "));
return 0;
}
+
if (value_optimized_out (val))
{
- printf_filtered (_("<value optimized out>"));
+ fprintf_filtered (stream, _("<value optimized out>"));
return 0;
}
+
+ return 1;
+}
+
+/* Print the value VAL onto stream STREAM according to FORMAT (a
+ letter, or 0 for natural format using TYPE).
+
+ If DEREF_REF is nonzero, then dereference references, otherwise just print
+ them like pointers.
+
+ The PRETTY parameter controls prettyprinting.
+
+ If the data are a string pointer, returns the number of string characters
+ printed.
+
+ This is a preferable interface to val_print, above, because it uses
+ GDB's value mechanism. */
+
+int
+common_val_print (struct value *val, struct ui_file *stream, int format,
+ int deref_ref, int recurse, enum val_prettyprint pretty)
+{
+ if (!value_check_printable (val, stream))
+ return 0;
+
+ return val_print (value_type (val), value_contents_all (val),
+ value_embedded_offset (val), VALUE_ADDRESS (val),
+ stream, format, deref_ref, recurse, pretty);
+}
+
+/* Print the value VAL in C-ish syntax on stream STREAM.
+ FORMAT is a format-letter, or 0 for print in natural format of data type.
+ If the object printed is a string pointer, returns
+ the number of string bytes printed. */
+
+int
+value_print (struct value *val, struct ui_file *stream, int format,
+ enum val_prettyprint pretty)
+{
+ if (!value_check_printable (val, stream))
+ return 0;
+
return LA_VALUE_PRINT (val, stream, format, pretty);
}

Index: value.h
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/gdb/value.h,v
retrieving revision 1.83
diff -u -p -r1.83 value.h
--- value.h 20 Feb 2005 01:19:24 -0000 1.83
+++ value.h 27 Feb 2005 02:21:47 -0000
@@ -479,6 +479,11 @@ extern int val_print (struct type *type,
int deref_ref, int recurse,
enum val_prettyprint pretty);

+extern int common_val_print (struct value *val,
+ struct ui_file *stream, int format,
+ int deref_ref, int recurse,
+ enum val_prettyprint pretty);
+
extern int val_print_string (CORE_ADDR addr, int len, int width,
struct ui_file *stream);

Index: varobj.c
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/gdb/varobj.c,v
retrieving revision 1.51
diff -u -p -r1.51 varobj.c
--- varobj.c 24 Feb 2005 13:51:35 -0000 1.51
+++ varobj.c 27 Feb 2005 15:49:38 -0000
@@ -2080,10 +2080,8 @@ c_value_of_variable (struct varobj *var)

if (value_lazy (var->value))
gdb_value_fetch_lazy (var->value);
- val_print (value_type (var->value),
- value_contents_raw (var->value), 0,
- VALUE_ADDRESS (var->value), stb,
- format_code[(int) var->format], 1, 0, 0);
+ common_val_print (var->value, stb,
+ format_code[(int) var->format], 1, 0, 0);
thevalue = ui_file_xstrdup (stb, &dummy);
do_cleanups (old_chain);
return thevalue;