From ec0a52e16206a31867fdcc5535c42baca7bf8967 Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Mon, 14 Feb 2011 11:33:24 +0000 Subject: [PATCH] gdb/testsuite/ * 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. gdb/ * 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. --- gdb/ChangeLog | 7 ++++ gdb/c-valprint.c | 50 +++++++++++++------------ gdb/testsuite/ChangeLog | 8 ++++ gdb/testsuite/gdb.trace/unavailable.cc | 7 ++++ gdb/testsuite/gdb.trace/unavailable.exp | 12 +++++- gdb/value.c | 13 +++++++ gdb/value.h | 4 ++ 7 files changed, 77 insertions(+), 24 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index a127078b79..d690e5090c 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,10 @@ +2011-02-14 Pedro Alves + + * 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 * valops.c (value_repeat): Use read_value_memory instead of diff --git a/gdb/c-valprint.c b/gdb/c-valprint.c index 138aca6d97..8e4f932674 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 a9a19c9cad..d2b877b669 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2011-02-14 Pedro Alves + + * 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 * gdb.trace/unavailable.exp (gdb_collect_globals_test): Test that diff --git a/gdb/testsuite/gdb.trace/unavailable.cc b/gdb/testsuite/gdb.trace/unavailable.cc index d25837df21..718e0f7b35 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 18e1043175..aa87cfb09a 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" " = \\{ = \\{member = \\}, \\}" gdb_test "print (small_struct) \$" " = \\{member = \\}" + 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 \\*\\) " + + 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 806101910d..236b42f12a 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 4dec28e0f2..b5e77fdab8 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. */ -- 2.34.1