aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog7
-rw-r--r--gdb/c-valprint.c50
-rw-r--r--gdb/testsuite/ChangeLog8
-rw-r--r--gdb/testsuite/gdb.trace/unavailable.cc7
-rw-r--r--gdb/testsuite/gdb.trace/unavailable.exp12
-rw-r--r--gdb/value.c13
-rw-r--r--gdb/value.h4
7 files changed, 77 insertions, 24 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index a127078..d690e50 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,12 @@
2011-02-14 Pedro Alves <pedro@codesourcery.com>
+ * value.h (value_entirely_available): Declare.
+ * value.c (value_entirely_available): New function.
+ * c-valprint.c (c_value_print): Don't try fetching the pointer's
+ real type if the pointer is unavailable.
+
+2011-02-14 Pedro Alves <pedro@codesourcery.com>
+
* valops.c (value_repeat): Use read_value_memory instead of
read_memory.
diff --git a/gdb/c-valprint.c b/gdb/c-valprint.c
index 138aca6..8e4f932 100644
--- a/gdb/c-valprint.c
+++ b/gdb/c-valprint.c
@@ -686,29 +686,33 @@ c_value_print (struct value *val, struct ui_file *stream,
}
/* Pointer to class, check real type of object. */
fprintf_filtered (stream, "(");
- real_type = value_rtti_target_type (val, &full,
- &top, &using_enc);
- if (real_type)
- {
- /* RTTI entry found. */
- if (TYPE_CODE (type) == TYPE_CODE_PTR)
- {
- /* Create a pointer type pointing to the real
- type. */
- type = lookup_pointer_type (real_type);
- }
- else
- {
- /* Create a reference type referencing the real
- type. */
- type = lookup_reference_type (real_type);
- }
- /* JYG: Need to adjust pointer value. */
- val = value_from_pointer (type, value_as_address (val) - top);
-
- /* Note: When we look up RTTI entries, we don't get any
- information on const or volatile attributes. */
- }
+
+ if (value_entirely_available (val))
+ {
+ real_type = value_rtti_target_type (val, &full, &top, &using_enc);
+ if (real_type)
+ {
+ /* RTTI entry found. */
+ if (TYPE_CODE (type) == TYPE_CODE_PTR)
+ {
+ /* Create a pointer type pointing to the real
+ type. */
+ type = lookup_pointer_type (real_type);
+ }
+ else
+ {
+ /* Create a reference type referencing the real
+ type. */
+ type = lookup_reference_type (real_type);
+ }
+ /* Need to adjust pointer value. */
+ val = value_from_pointer (type, value_as_address (val) - top);
+
+ /* Note: When we look up RTTI entries, we don't get
+ any information on const or volatile
+ attributes. */
+ }
+ }
type_print (type, "", stream, -1);
fprintf_filtered (stream, ") ");
val_type = type;
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index a9a19c9..d2b877b 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,5 +1,13 @@
2011-02-14 Pedro Alves <pedro@codesourcery.com>
+ * gdb.trace/unavailable.cc (struct Virtual): New.
+ (virtualp): New global pointer.
+ * gdb.trace/unavailable.exp (gdb_collect_globals_test): Test
+ printing a pointer to an object whose type has a vtable, with
+ print object on.
+
+2011-02-14 Pedro Alves <pedro@codesourcery.com>
+
* gdb.trace/unavailable.exp (gdb_collect_globals_test): Test that
value repeat handles unavailableness.
diff --git a/gdb/testsuite/gdb.trace/unavailable.cc b/gdb/testsuite/gdb.trace/unavailable.cc
index d25837d..718e0f7 100644
--- a/gdb/testsuite/gdb.trace/unavailable.cc
+++ b/gdb/testsuite/gdb.trace/unavailable.cc
@@ -114,6 +114,13 @@ struct StructA StructB::static_struct_a;
StructRef g_structref(0x12345678);
StructRef *g_structref_p = &g_structref;
+struct Virtual {
+ int z;
+
+ virtual ~Virtual() {}
+};
+
+Virtual *virtualp;
/* Test functions. */
diff --git a/gdb/testsuite/gdb.trace/unavailable.exp b/gdb/testsuite/gdb.trace/unavailable.exp
index 18e1043..aa87cfb 100644
--- a/gdb/testsuite/gdb.trace/unavailable.exp
+++ b/gdb/testsuite/gdb.trace/unavailable.exp
@@ -103,7 +103,7 @@ proc gdb_collect_globals_test { } {
"collect g_string_partial\[1\]" "^$" \
"collect g_string_partial\[2\]" "^$" \
\
- "collect g_structref_p" "^$" \
+ "collect g_structref_p" "^$"
# Begin the test.
run_trace_experiment globals_test_func
@@ -242,6 +242,16 @@ proc gdb_collect_globals_test { } {
gdb_test "print g_smallstruct_b" " = \\{<small_struct> = \\{member = <unavailable>\\}, <No data fields>\\}"
gdb_test "print (small_struct) \$" " = \\{member = <unavailable>\\}"
+ gdb_test_no_output "set print object on"
+
+ # With print object on, printing a pointer may need to fetch the
+ # pointed-to object, to check its run-time type. Make sure that
+ # fails gracefully and transparently when the pointer itself is
+ # unavailable.
+ gdb_test "print virtualp" " = \\(Virtual \\*\\) <unavailable>"
+
+ gdb_test_no_output "set print object off"
+
gdb_test "tfind none" \
"#0 end .*" \
"cease trace debugging"
diff --git a/gdb/value.c b/gdb/value.c
index 8061019..236b42f 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -331,6 +331,19 @@ value_bytes_available (const struct value *value, int offset, int length)
return !ranges_contain (value->unavailable, offset, length);
}
+int
+value_entirely_available (struct value *value)
+{
+ /* We can only tell whether the whole value is available when we try
+ to read it. */
+ if (value->lazy)
+ value_fetch_lazy (value);
+
+ if (VEC_empty (range_s, value->unavailable))
+ return 1;
+ return 0;
+}
+
void
mark_value_bytes_unavailable (struct value *value, int offset, int length)
{
diff --git a/gdb/value.h b/gdb/value.h
index 4dec28e..b5e77fd 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -368,6 +368,10 @@ extern int value_bits_synthetic_pointer (const struct value *value,
extern int value_bytes_available (const struct value *value,
int offset, int length);
+/* Like value_bytes_available, but return false if any byte in the
+ whole object is unavailable. */
+extern int value_entirely_available (struct value *value);
+
/* Mark VALUE's content bytes starting at OFFSET and extending for
LENGTH bytes as unavailable. */