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.
This commit is contained in:
parent
24e6bceefb
commit
ec0a52e162
|
@ -1,3 +1,10 @@
|
|||
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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
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
|
||||
|
|
|
@ -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. */
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
13
gdb/value.c
13
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)
|
||||
{
|
||||
|
|
|
@ -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. */
|
||||
|
||||
|
|
Loading…
Reference in New Issue