diff options
-rw-r--r-- | gdb/ChangeLog | 7 | ||||
-rw-r--r-- | gdb/c-valprint.c | 50 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 8 | ||||
-rw-r--r-- | gdb/testsuite/gdb.trace/unavailable.cc | 7 | ||||
-rw-r--r-- | gdb/testsuite/gdb.trace/unavailable.exp | 12 | ||||
-rw-r--r-- | gdb/value.c | 13 | ||||
-rw-r--r-- | gdb/value.h | 4 |
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. */ |