* [4/5] implement "info vtable"
@ 2012-02-28 21:48 Tom Tromey
2012-02-29 18:20 ` Eli Zaretskii
2012-03-01 14:52 ` Pedro Alves
0 siblings, 2 replies; 17+ messages in thread
From: Tom Tromey @ 2012-02-28 21:48 UTC (permalink / raw)
To: gdb-patches
This one needs a doc review, and of course commentary on the naming and
output.
This adds a new command, "info vtable". This command can be used to
inspect the virtual tables of an object.
E.g., from the test suite's virtfunc.cc:
(gdb) info vtable e
vtable for 'E' @ 0x401478 (subobject @ 0x602580):
[0]: 0x400d18 <E::f()>
[1]: 0x400d42 <E::vg()>
[2]: 0x400d8e <E::vv()>
vtable for 'D' @ 0x4014a8 (subobject @ 0x602590):
[0]: 0x400d3c <non-virtual thunk to E::vg()>
[1]: 0x400dc8 <D::vd()>
vtable for 'V' @ 0x4014f0 (subobject @ 0x6025b0):
[0]: 0x400df4 <VB::vvb()>
[1]: 0x400d84 <virtual thunk to E::vv()>
The implementation is somewhat complicated due to dealing with multiple
inheritance; plus the fact that the only way I could find to determine
the size of a vtable is to find the maximum of the indices of all
virtual functions.
Tom
* gnu-v3-abi.c (struct value_and_voffset): New.
(hash_value_and_voffset, eq_value_and_voffset)
(compare_value_and_voffset, compute_vtable_size)
(print_one_vtable, gnuv3_print_vtable): New functions.
(init_gnuv3_ops): Initialize 'print_vtable' field.
* cp-support.c (info_vtable_command): New function.
(_initialize_cp_support): Add "info vtable".
* cp-abi.h (cplus_print_vtable): Declare.
(struct cp_abi_ops) <print_vtable>: New field.
* cp-abi.c (cplus_print_vtable): New function.
* NEWS: Update.
gdb/testsuite
* gdb.cp/virtfunc.exp (make_one_vtable_result): New proc.
(test_info_vtable): Likewise.
(do_tests): Call test_info_vtable.
gdb/doc
* gdb.texinfo (Debugging C Plus Plus): Document "info vtable".
From 36f61ee5e765c8de26ac897e6e6e2c332ba5eb0f Mon Sep 17 00:00:00 2001
From: Tom Tromey <tromey@redhat.com>
Date: Mon, 27 Feb 2012 13:17:22 -0700
Subject: [PATCH 4/5] * gnu-v3-abi.c (struct value_and_voffset): New.
(hash_value_and_voffset, eq_value_and_voffset)
(compare_value_and_voffset, compute_vtable_size)
(print_one_vtable, gnuv3_print_vtable): New functions.
(init_gnuv3_ops): Initialize 'print_vtable' field.
* cp-support.c (info_vtable_command): New function.
(_initialize_cp_support): Add "info vtable". *
cp-abi.h (cplus_print_vtable): Declare. (struct
cp_abi_ops) <print_vtable>: New field. *
cp-abi.c (cplus_print_vtable): New function. * NEWS:
Update. gdb/testsuite * gdb.cp/virtfunc.exp
(make_one_vtable_result): New proc.
(test_info_vtable): Likewise. (do_tests): Call
test_info_vtable. gdb/doc * gdb.texinfo (Debugging
C Plus Plus): Document "info vtable".
---
gdb/NEWS | 3 +
gdb/cp-abi.c | 10 ++
gdb/cp-abi.h | 6 +
gdb/cp-support.c | 17 +++
gdb/doc/gdb.texinfo | 6 +
gdb/gnu-v3-abi.c | 241 +++++++++++++++++++++++++++++++++++++
gdb/testsuite/gdb.cp/virtfunc.exp | 42 +++++++
7 files changed, 325 insertions(+), 0 deletions(-)
diff --git a/gdb/NEWS b/gdb/NEWS
index 090a065..e9efc96 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -52,6 +52,9 @@
** "enable count" can be used to auto-disable a breakpoint after
several hits.
+ ** "info vtable" can be used to show the virtual method tables for
+ C++ and Java objects.
+
* New targets
Renesas RL78 rl78-*-elf
diff --git a/gdb/cp-abi.c b/gdb/cp-abi.c
index e949088..16b5356 100644
--- a/gdb/cp-abi.c
+++ b/gdb/cp-abi.c
@@ -169,6 +169,16 @@ cplus_method_ptr_to_value (struct value **this_p,
return (*current_cp_abi.method_ptr_to_value) (this_p, method_ptr);
}
+/* See cp-abi.h. */
+
+void
+cplus_print_vtable (struct value *value)
+{
+ if (current_cp_abi.print_vtable == NULL)
+ error (_("GDB cannot print the vtable on this target"));
+ return (*current_cp_abi.print_vtable) (value);
+}
+
int
cp_pass_by_reference (struct type *type)
{
diff --git a/gdb/cp-abi.h b/gdb/cp-abi.h
index 0f24e9a..8451450 100644
--- a/gdb/cp-abi.h
+++ b/gdb/cp-abi.h
@@ -173,6 +173,11 @@ struct value *cplus_method_ptr_to_value (struct value **this_p,
void cplus_make_method_ptr (struct type *type, gdb_byte *CONTENTS,
CORE_ADDR address, int is_virtual);
+/* Print the vtable for VALUE, if there is one. If there is no
+ vtable, print a message, but do not throw. */
+
+void cplus_print_vtable (struct value *value);
+
/* Determine if we are currently in a C++ thunk. If so, get the
address of the routine we are thunking to and continue to there
instead. */
@@ -213,6 +218,7 @@ struct cp_abi_ops
CORE_ADDR, int);
struct value * (*method_ptr_to_value) (struct value **,
struct value *);
+ void (*print_vtable) (struct value *);
CORE_ADDR (*skip_trampoline) (struct frame_info *, CORE_ADDR);
int (*pass_by_reference) (struct type *type);
};
diff --git a/gdb/cp-support.c b/gdb/cp-support.c
index 0620aa7..66b3244 100644
--- a/gdb/cp-support.c
+++ b/gdb/cp-support.c
@@ -34,6 +34,7 @@
#include "exceptions.h"
#include "expression.h"
#include "value.h"
+#include "cp-abi.h"
#include "safe-ctype.h"
@@ -1563,6 +1564,17 @@ cp_validate_operator (const char *input)
return 0;
}
+/* Implement "info vtable". */
+
+static void
+info_vtable_command (char *arg, int from_tty)
+{
+ struct value *value;
+
+ value = parse_and_eval (arg);
+ cplus_print_vtable (value);
+}
+
void
_initialize_cp_support (void)
{
@@ -1581,4 +1593,9 @@ _initialize_cp_support (void)
first_component_command,
_("Print the first class/namespace component of NAME."),
&maint_cplus_cmd_list);
+
+ add_info ("vtable", info_vtable_command,
+ _("Show the vtable for a C++ object.\n\
+Usage: info vtable EXPRESSION\n\
+Evaluate EXPRESSION and display the vtable for the resulting object."));
}
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 88dcec1..9eed27e 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -12786,6 +12786,12 @@ Print inheritance relationships as well as other information for type
@var{typename}.
@xref{Symbols, ,Examining the Symbol Table}.
+@item info vtable @var{expression}.
+The @code{info vtable} command can be used to display the virtual
+method tables of the object computed by @var{expression}. This shows
+one entry per virtual table; there may be multiple virtual tables when
+multiple inheritance is in use.
+
@cindex C@t{++} symbol display
@item set print demangle
@itemx show print demangle
diff --git a/gdb/gnu-v3-abi.c b/gdb/gnu-v3-abi.c
index f015af6..8710bde 100644
--- a/gdb/gnu-v3-abi.c
+++ b/gdb/gnu-v3-abi.c
@@ -26,6 +26,7 @@
#include "objfiles.h"
#include "valprint.h"
#include "c-lang.h"
+#include "exceptions.h"
#include "gdb_assert.h"
#include "gdb_string.h"
@@ -725,6 +726,245 @@ gnuv3_method_ptr_to_value (struct value **this_p, struct value *method_ptr)
return value_from_pointer (lookup_pointer_type (method_type), ptr_value);
}
+/* Objects of this type are stored in a hash table and a vector when
+ printing the vtables for a class. */
+
+struct value_and_voffset
+{
+ /* The value representing the object. */
+ struct value *value;
+
+ /* The maximum vtable offset we've found for any object at this
+ offset in the outermost object. */
+ int max_voffset;
+};
+
+typedef struct value_and_voffset *value_and_voffset_p;
+DEF_VEC_P (value_and_voffset_p);
+
+/* Hash function for value_and_voffset. */
+
+static hashval_t
+hash_value_and_voffset (const void *p)
+{
+ const struct value_and_voffset *o = p;
+
+ return value_address (o->value) + value_embedded_offset (o->value);
+}
+
+/* Equality function for value_and_voffset. */
+
+static int
+eq_value_and_voffset (const void *a, const void *b)
+{
+ const struct value_and_voffset *ova = a;
+ const struct value_and_voffset *ovb = b;
+
+ return (value_address (ova->value) + value_embedded_offset (ova->value)
+ == value_address (ovb->value) + value_embedded_offset (ovb->value));
+}
+
+/* qsort comparison function for value_and_voffset. */
+
+static int
+compare_value_and_voffset (const void *a, const void *b)
+{
+ const struct value_and_voffset * const *ova = a;
+ CORE_ADDR addra = (value_address ((*ova)->value)
+ + value_embedded_offset ((*ova)->value));
+ const struct value_and_voffset * const *ovb = b;
+ CORE_ADDR addrb = (value_address ((*ovb)->value)
+ + value_embedded_offset ((*ovb)->value));
+
+ if (addra < addrb)
+ return -1;
+ if (addra > addrb)
+ return 1;
+ return 0;
+}
+
+/* A helper function used when printing vtables. This determines the
+ key (most derived) sub-object at each address and also computes the
+ maximum vtable offset seen for the corresponding vtable. Updates
+ OFFSET_HASH and OFFSET_VEC with a new value_and_voffset object, if
+ needed. VALUE is the object to examine. */
+
+static void
+compute_vtable_size (htab_t offset_hash,
+ VEC (value_and_voffset_p) **offset_vec,
+ struct value *value)
+{
+ int i;
+ struct type *type = check_typedef (value_type (value));
+ void **slot;
+ struct value_and_voffset search_vo, *current_vo;
+ CORE_ADDR addr = value_address (value) + value_embedded_offset (value);
+
+ /* If the object is not dynamic, then we are done; as it cannot have
+ dynamic base types either. */
+ if (!gnuv3_dynamic_class (type))
+ return;
+
+ /* Update the hash and the vec, if needed. */
+ search_vo.value = value;
+ slot = htab_find_slot (offset_hash, &search_vo, INSERT);
+ if (*slot)
+ current_vo = *slot;
+ else
+ {
+ current_vo = XNEW (struct value_and_voffset);
+ current_vo->value = value;
+ current_vo->max_voffset = -1;
+ *slot = current_vo;
+ VEC_safe_push (value_and_voffset_p, *offset_vec, current_vo);
+ }
+
+ /* Update the value_and_voffset object with the highest vtable
+ offset from this class. */
+ for (i = 0; i < TYPE_NFN_FIELDS (type); ++i)
+ {
+ int j;
+ struct fn_field *fn = TYPE_FN_FIELDLIST1 (type, i);
+
+ for (j = 0; j < TYPE_FN_FIELDLIST_LENGTH (type, i); ++j)
+ {
+ if (TYPE_FN_FIELD_VIRTUAL_P (fn, j))
+ {
+ int voffset = TYPE_FN_FIELD_VOFFSET (fn, j);
+
+ if (voffset > current_vo->max_voffset)
+ current_vo->max_voffset = voffset;
+ }
+ }
+ }
+
+ /* Recurse into base classes. */
+ for (i = 0; i < TYPE_N_BASECLASSES (type); ++i)
+ compute_vtable_size (offset_hash, offset_vec, value_field (value, i));
+}
+
+/* Helper for gnuv3_print_vtable that prints a single vtable. */
+
+static void
+print_one_vtable (struct gdbarch *gdbarch, struct value *value,
+ int max_voffset,
+ struct value_print_options *opts)
+{
+ int i;
+ struct type *type = check_typedef (value_type (value));
+ struct value *vtable;
+ CORE_ADDR vt_addr;
+
+ vtable = gnuv3_get_vtable (gdbarch, type,
+ value_address (value)
+ + value_embedded_offset (value));
+ vt_addr = value_address (value_field (vtable,
+ vtable_field_virtual_functions));
+
+ printf_filtered (_("vtable for '%s' @ %s (subobject @ %s):\n"),
+ TYPE_SAFE_NAME (type),
+ paddress (gdbarch, vt_addr),
+ paddress (gdbarch, (value_address (value)
+ + value_embedded_offset (value))));
+
+ for (i = 0; i <= max_voffset; ++i)
+ {
+ struct value *vfn;
+ CORE_ADDR addr;
+ volatile struct gdb_exception ex;
+
+ printf_filtered ("[%d]: ", i);
+
+ vfn = value_subscript (value_field (vtable,
+ vtable_field_virtual_functions),
+ i);
+
+ if (gdbarch_vtable_function_descriptors (gdbarch))
+ vfn = value_addr (vfn);
+
+ TRY_CATCH (ex, RETURN_MASK_ERROR)
+ {
+ addr = value_as_address (vfn);
+ }
+ if (ex.reason < 0)
+ printf_filtered (_("<error: %s>"), ex.message);
+ else
+ print_function_pointer_address (gdbarch, addr, gdb_stdout,
+ opts->addressprint);
+ printf_filtered ("\n");
+ }
+}
+
+/* Implementation of the print_vtable method. */
+
+static void
+gnuv3_print_vtable (struct value *value)
+{
+ struct gdbarch *gdbarch;
+ struct type *type;
+ struct value *vtable;
+ struct value_print_options opts;
+ htab_t offset_hash;
+ struct cleanup *cleanup;
+ VEC (value_and_voffset_p) *result_vec;
+ struct value_and_voffset *iter;
+ int i, count;
+
+ value = coerce_ref (value);
+ type = check_typedef (value_type (value));
+ if (TYPE_CODE (type) == TYPE_CODE_PTR)
+ {
+ value = value_ind (value);
+ type = check_typedef (value_type (value));
+ }
+
+ get_user_print_options (&opts);
+
+ /* Respect 'set print object'. */
+ if (opts.objectprint)
+ {
+ value = value_full_object (value, NULL, 0, 0, 0);
+ type = check_typedef (value_type (value));
+ }
+
+ gdbarch = get_type_arch (type);
+ vtable = gnuv3_get_vtable (gdbarch, type,
+ value_as_address (value_addr (value)));
+
+ if (!vtable)
+ {
+ printf_filtered (_("This object does not have a vtable\n"));
+ return;
+ }
+
+ offset_hash = htab_create_alloc (1, hash_value_and_voffset,
+ eq_value_and_voffset,
+ xfree, xcalloc, xfree);
+ cleanup = make_cleanup_htab_delete (offset_hash);
+ make_cleanup (VEC_cleanup (value_and_voffset_p), &result_vec);
+
+ compute_vtable_size (offset_hash, &result_vec, value);
+
+ qsort (VEC_address (value_and_voffset_p, result_vec),
+ VEC_length (value_and_voffset_p, result_vec),
+ sizeof (value_and_voffset_p),
+ compare_value_and_voffset);
+
+ count = 0;
+ for (i = 0; VEC_iterate (value_and_voffset_p, result_vec, i, iter); ++i)
+ {
+ if (iter->max_voffset >= 0)
+ {
+ if (count > 0)
+ printf_filtered ("\n");
+ print_one_vtable (gdbarch, iter->value, iter->max_voffset, &opts);
+ ++count;
+ }
+ }
+
+ do_cleanups (cleanup);
+}
+
/* Determine if we are currently in a C++ thunk. If so, get the address
of the routine we are thunking to and continue to there instead. */
@@ -873,6 +1113,7 @@ init_gnuv3_ops (void)
gnu_v3_abi_ops.method_ptr_size = gnuv3_method_ptr_size;
gnu_v3_abi_ops.make_method_ptr = gnuv3_make_method_ptr;
gnu_v3_abi_ops.method_ptr_to_value = gnuv3_method_ptr_to_value;
+ gnu_v3_abi_ops.print_vtable = gnuv3_print_vtable;
gnu_v3_abi_ops.skip_trampoline = gnuv3_skip_trampoline;
gnu_v3_abi_ops.pass_by_reference = gnuv3_pass_by_reference;
}
diff --git a/gdb/testsuite/gdb.cp/virtfunc.exp b/gdb/testsuite/gdb.cp/virtfunc.exp
index dd41c6d..00dd89e 100644
--- a/gdb/testsuite/gdb.cp/virtfunc.exp
+++ b/gdb/testsuite/gdb.cp/virtfunc.exp
@@ -226,6 +226,47 @@ proc test_virtual_calls {} {
}
}
+# A helper proc that creates a regular expression matching a
+# particular vtable. NAME is the type name. Each element of ARGS is
+# the name of a function in the vtable.
+
+proc make_one_vtable_result {name args} {
+ global hex
+
+ set nls "\[\r\n\]+"
+
+ set result "vtable for '${name}' @ $hex .subobject @ $hex.:$nls"
+ set count 0
+ foreach func $args {
+ append result ".${count}.: $hex <$func..>${nls}"
+ incr count
+ }
+
+ return $result
+}
+
+# Test "info vtable".
+
+proc test_info_vtable {} {
+ global hex
+
+ set nls "\[\r\n\]+"
+
+ set vt_A [make_one_vtable_result A A::f]
+ set vt_B [make_one_vtable_result B B::f]
+ set vt_V [make_one_vtable_result V VB::vvb V::vv]
+ set vt_V2 [make_one_vtable_result V VB::vvb "virtual thunk to E::vv"]
+ set vt_D [make_one_vtable_result D D::vg D::vd]
+ set vt_D2 [make_one_vtable_result D "non-virtual thunk to E::vg" D::vd]
+ set vt_E [make_one_vtable_result E E::f E::vg E::vv]
+
+ gdb_test "info vtable a" "${vt_A}${vt_V}"
+ gdb_test "info vtable b" "${vt_B}${vt_V}"
+ gdb_test "info vtable c" "${vt_V}"
+ gdb_test "info vtable d" "${vt_D}${vt_V}"
+ gdb_test "info vtable e" "${vt_E}${vt_D2}${vt_V2}"
+}
+
proc do_tests {} {
global srcdir subdir binfile
global gdb_prompt
@@ -244,6 +285,7 @@ proc do_tests {} {
return
}
test_ptype_of_classes
+ test_info_vtable
gdb_breakpoint test_calls
gdb_test "continue" ".*Breakpoint .* test_calls.*" ""
--
1.7.7.6
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [4/5] implement "info vtable"
2012-02-28 21:48 [4/5] implement "info vtable" Tom Tromey
@ 2012-02-29 18:20 ` Eli Zaretskii
2012-03-01 14:52 ` Pedro Alves
1 sibling, 0 replies; 17+ messages in thread
From: Eli Zaretskii @ 2012-02-29 18:20 UTC (permalink / raw)
To: Tom Tromey; +Cc: gdb-patches
> From: Tom Tromey <tromey@redhat.com>
> Date: Tue, 28 Feb 2012 14:36:42 -0700
>
> This one needs a doc review, and of course commentary on the naming and
> output.
The documentation parts are fine, thanks.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [4/5] implement "info vtable"
2012-02-28 21:48 [4/5] implement "info vtable" Tom Tromey
2012-02-29 18:20 ` Eli Zaretskii
@ 2012-03-01 14:52 ` Pedro Alves
2012-03-01 17:36 ` Tom Tromey
2012-03-15 15:43 ` Tom Tromey
1 sibling, 2 replies; 17+ messages in thread
From: Pedro Alves @ 2012-03-01 14:52 UTC (permalink / raw)
To: Tom Tromey; +Cc: gdb-patches
On 02/28/2012 09:36 PM, Tom Tromey wrote:
> This one needs a doc review, and of course commentary on the naming and
> output.
>
> This adds a new command, "info vtable". This command can be used to
> inspect the virtual tables of an object.
My only gripe is that we end up with the vtable vs vtbl inconsistency (set print vtbl).
So
(gdb) apropos vtbl
and
(gdb) apropos vtable
will show different commands...
May be a good idea if the docs are augmented a bit to give an example,
and lightly explain the output.
IIUC, "info vtable POINTER" works. The tests only sees to try
"info vtable OBJ". Worth adding a test that tries through a pointer?
--
Pedro Alves
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [4/5] implement "info vtable"
2012-03-01 14:52 ` Pedro Alves
@ 2012-03-01 17:36 ` Tom Tromey
2012-03-01 20:18 ` Pedro Alves
2012-03-15 15:43 ` Tom Tromey
1 sibling, 1 reply; 17+ messages in thread
From: Tom Tromey @ 2012-03-01 17:36 UTC (permalink / raw)
To: Pedro Alves; +Cc: gdb-patches
>>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes:
Pedro> My only gripe is that we end up with the vtable vs vtbl inconsistency
Pedro> (set print vtbl).
Yeah. I was thinking of renaming 'set print vtbl' (keeping the old name
as an alias of course). WDYT? I think "vtable" is both clearer and
more commonly used.
Pedro> May be a good idea if the docs are augmented a bit to give an example,
Pedro> and lightly explain the output.
Ok.
Pedro> IIUC, "info vtable POINTER" works. The tests only sees to try
Pedro> "info vtable OBJ". Worth adding a test that tries through a pointer?
Will do.
Tom
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [4/5] implement "info vtable"
2012-03-01 17:36 ` Tom Tromey
@ 2012-03-01 20:18 ` Pedro Alves
0 siblings, 0 replies; 17+ messages in thread
From: Pedro Alves @ 2012-03-01 20:18 UTC (permalink / raw)
To: Tom Tromey; +Cc: Pedro Alves, gdb-patches
On 03/01/2012 05:36 PM, Tom Tromey wrote:
>>>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes:
>
> Pedro> My only gripe is that we end up with the vtable vs vtbl inconsistency
> Pedro> (set print vtbl).
>
> Yeah. I was thinking of renaming 'set print vtbl' (keeping the old name
> as an alias of course). WDYT? I think "vtable" is both clearer and
> more commonly used.
I have no problem with vtbl, but if you think vtable is clearer, fine with me.
> Pedro> May be a good idea if the docs are augmented a bit to give an example,
> Pedro> and lightly explain the output.
>
> Ok.
>
> Pedro> IIUC, "info vtable POINTER" works. The tests only sees to try
> Pedro> "info vtable OBJ". Worth adding a test that tries through a pointer?
>
> Will do.
Thanks. While at it, it might be worth it to add a test that
tries "info vtable" (no arg), "info vtable foo" with a foo object that doesn't
have a vtable, and perhaps also "info vtable some_scalar".
--
Pedro Alves
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [4/5] implement "info vtable"
2012-03-01 14:52 ` Pedro Alves
2012-03-01 17:36 ` Tom Tromey
@ 2012-03-15 15:43 ` Tom Tromey
2012-03-16 8:10 ` Crash regression [Re: [4/5] implement "info vtable"] Jan Kratochvil
2012-07-19 9:34 ` [4/5] implement "info vtable" Andreas Schwab
1 sibling, 2 replies; 17+ messages in thread
From: Tom Tromey @ 2012-03-15 15:43 UTC (permalink / raw)
To: Pedro Alves; +Cc: gdb-patches
Pedro> My only gripe is that we end up with the vtable vs vtbl inconsistency
In the end I chose to rename the new command to 'info vtbl', mostly out
of inertia.
Pedro> IIUC, "info vtable POINTER" works. The tests only sees to try
Pedro> "info vtable OBJ". Worth adding a test that tries through a pointer?
I did this.
Pedro> Thanks. While at it, it might be worth it to add a test that
Pedro> tries "info vtable" (no arg), "info vtable foo" with a foo object
Pedro> that doesn't have a vtable, and perhaps also "info vtable
Pedro> some_scalar".
This too.
Here's what I am checking in.
Tom
2012-03-15 Tom Tromey <tromey@redhat.com>
* gnu-v3-abi.c (struct value_and_voffset): New.
(hash_value_and_voffset, eq_value_and_voffset)
(compare_value_and_voffset, compute_vtable_size)
(print_one_vtable, gnuv3_print_vtable): New functions.
(init_gnuv3_ops): Initialize 'print_vtable' field.
* cp-support.c (info_vtbl_command): New function.
(_initialize_cp_support): Add "info vtbl".
* cp-abi.h (cplus_print_vtable): Declare.
(struct cp_abi_ops) <print_vtable>: New field.
* cp-abi.c (cplus_print_vtable): New function.
* NEWS: Update.
2012-03-15 Tom Tromey <tromey@redhat.com>
* gdb.texinfo (Debugging C Plus Plus): Document "info vtbl".
2012-03-15 Tom Tromey <tromey@redhat.com>
* gdb.cp/virtfunc.exp (make_one_vtable_result): New proc.
(test_info_vtbl): Likewise.
(do_tests): Call test_info_vtbl.
* gdb.cp/virtfunc.cc (va): New global.
Index: NEWS
===================================================================
RCS file: /cvs/src/src/gdb/NEWS,v
retrieving revision 1.497
diff -u -r1.497 NEWS
--- NEWS 13 Mar 2012 21:02:36 -0000 1.497
+++ NEWS 15 Mar 2012 15:41:16 -0000
@@ -70,6 +70,9 @@
** "enable count" can be used to auto-disable a breakpoint after
several hits.
+ ** "info vtable" can be used to show the virtual method tables for
+ C++ and Java objects.
+
* New targets
Renesas RL78 rl78-*-elf
Index: cp-abi.c
===================================================================
RCS file: /cvs/src/src/gdb/cp-abi.c,v
retrieving revision 1.34
diff -u -r1.34 cp-abi.c
--- cp-abi.c 6 Jan 2012 03:34:46 -0000 1.34
+++ cp-abi.c 15 Mar 2012 15:41:16 -0000
@@ -169,6 +169,16 @@
return (*current_cp_abi.method_ptr_to_value) (this_p, method_ptr);
}
+/* See cp-abi.h. */
+
+void
+cplus_print_vtable (struct value *value)
+{
+ if (current_cp_abi.print_vtable == NULL)
+ error (_("GDB cannot print the vtable on this target"));
+ return (*current_cp_abi.print_vtable) (value);
+}
+
int
cp_pass_by_reference (struct type *type)
{
Index: cp-abi.h
===================================================================
RCS file: /cvs/src/src/gdb/cp-abi.h,v
retrieving revision 1.23
diff -u -r1.23 cp-abi.h
--- cp-abi.h 4 Jan 2012 08:17:00 -0000 1.23
+++ cp-abi.h 15 Mar 2012 15:41:16 -0000
@@ -173,6 +173,11 @@
void cplus_make_method_ptr (struct type *type, gdb_byte *CONTENTS,
CORE_ADDR address, int is_virtual);
+/* Print the vtable for VALUE, if there is one. If there is no
+ vtable, print a message, but do not throw. */
+
+void cplus_print_vtable (struct value *value);
+
/* Determine if we are currently in a C++ thunk. If so, get the
address of the routine we are thunking to and continue to there
instead. */
@@ -213,6 +218,7 @@
CORE_ADDR, int);
struct value * (*method_ptr_to_value) (struct value **,
struct value *);
+ void (*print_vtable) (struct value *);
CORE_ADDR (*skip_trampoline) (struct frame_info *, CORE_ADDR);
int (*pass_by_reference) (struct type *type);
};
Index: cp-support.c
===================================================================
RCS file: /cvs/src/src/gdb/cp-support.c,v
retrieving revision 1.54
diff -u -r1.54 cp-support.c
--- cp-support.c 7 Feb 2012 04:48:18 -0000 1.54
+++ cp-support.c 15 Mar 2012 15:41:16 -0000
@@ -34,6 +34,7 @@
#include "exceptions.h"
#include "expression.h"
#include "value.h"
+#include "cp-abi.h"
#include "safe-ctype.h"
@@ -1563,6 +1564,17 @@
return 0;
}
+/* Implement "info vtable". */
+
+static void
+info_vtbl_command (char *arg, int from_tty)
+{
+ struct value *value;
+
+ value = parse_and_eval (arg);
+ cplus_print_vtable (value);
+}
+
void
_initialize_cp_support (void)
{
@@ -1581,4 +1593,10 @@
first_component_command,
_("Print the first class/namespace component of NAME."),
&maint_cplus_cmd_list);
+
+ add_info ("vtbl", info_vtbl_command,
+ _("Show the vtable for a C++ object.\n\
+Usage: info vtbl EXPRESSION\n\
+Evaluate EXPRESSION and display the virtual function table for the\n\
+resulting object."));
}
Index: gnu-v3-abi.c
===================================================================
RCS file: /cvs/src/src/gdb/gnu-v3-abi.c,v
retrieving revision 1.69
diff -u -r1.69 gnu-v3-abi.c
--- gnu-v3-abi.c 7 Feb 2012 04:48:21 -0000 1.69
+++ gnu-v3-abi.c 15 Mar 2012 15:41:16 -0000
@@ -26,6 +26,7 @@
#include "objfiles.h"
#include "valprint.h"
#include "c-lang.h"
+#include "exceptions.h"
#include "gdb_assert.h"
#include "gdb_string.h"
@@ -725,6 +726,245 @@
return value_from_pointer (lookup_pointer_type (method_type), ptr_value);
}
+/* Objects of this type are stored in a hash table and a vector when
+ printing the vtables for a class. */
+
+struct value_and_voffset
+{
+ /* The value representing the object. */
+ struct value *value;
+
+ /* The maximum vtable offset we've found for any object at this
+ offset in the outermost object. */
+ int max_voffset;
+};
+
+typedef struct value_and_voffset *value_and_voffset_p;
+DEF_VEC_P (value_and_voffset_p);
+
+/* Hash function for value_and_voffset. */
+
+static hashval_t
+hash_value_and_voffset (const void *p)
+{
+ const struct value_and_voffset *o = p;
+
+ return value_address (o->value) + value_embedded_offset (o->value);
+}
+
+/* Equality function for value_and_voffset. */
+
+static int
+eq_value_and_voffset (const void *a, const void *b)
+{
+ const struct value_and_voffset *ova = a;
+ const struct value_and_voffset *ovb = b;
+
+ return (value_address (ova->value) + value_embedded_offset (ova->value)
+ == value_address (ovb->value) + value_embedded_offset (ovb->value));
+}
+
+/* qsort comparison function for value_and_voffset. */
+
+static int
+compare_value_and_voffset (const void *a, const void *b)
+{
+ const struct value_and_voffset * const *ova = a;
+ CORE_ADDR addra = (value_address ((*ova)->value)
+ + value_embedded_offset ((*ova)->value));
+ const struct value_and_voffset * const *ovb = b;
+ CORE_ADDR addrb = (value_address ((*ovb)->value)
+ + value_embedded_offset ((*ovb)->value));
+
+ if (addra < addrb)
+ return -1;
+ if (addra > addrb)
+ return 1;
+ return 0;
+}
+
+/* A helper function used when printing vtables. This determines the
+ key (most derived) sub-object at each address and also computes the
+ maximum vtable offset seen for the corresponding vtable. Updates
+ OFFSET_HASH and OFFSET_VEC with a new value_and_voffset object, if
+ needed. VALUE is the object to examine. */
+
+static void
+compute_vtable_size (htab_t offset_hash,
+ VEC (value_and_voffset_p) **offset_vec,
+ struct value *value)
+{
+ int i;
+ struct type *type = check_typedef (value_type (value));
+ void **slot;
+ struct value_and_voffset search_vo, *current_vo;
+ CORE_ADDR addr = value_address (value) + value_embedded_offset (value);
+
+ /* If the object is not dynamic, then we are done; as it cannot have
+ dynamic base types either. */
+ if (!gnuv3_dynamic_class (type))
+ return;
+
+ /* Update the hash and the vec, if needed. */
+ search_vo.value = value;
+ slot = htab_find_slot (offset_hash, &search_vo, INSERT);
+ if (*slot)
+ current_vo = *slot;
+ else
+ {
+ current_vo = XNEW (struct value_and_voffset);
+ current_vo->value = value;
+ current_vo->max_voffset = -1;
+ *slot = current_vo;
+ VEC_safe_push (value_and_voffset_p, *offset_vec, current_vo);
+ }
+
+ /* Update the value_and_voffset object with the highest vtable
+ offset from this class. */
+ for (i = 0; i < TYPE_NFN_FIELDS (type); ++i)
+ {
+ int j;
+ struct fn_field *fn = TYPE_FN_FIELDLIST1 (type, i);
+
+ for (j = 0; j < TYPE_FN_FIELDLIST_LENGTH (type, i); ++j)
+ {
+ if (TYPE_FN_FIELD_VIRTUAL_P (fn, j))
+ {
+ int voffset = TYPE_FN_FIELD_VOFFSET (fn, j);
+
+ if (voffset > current_vo->max_voffset)
+ current_vo->max_voffset = voffset;
+ }
+ }
+ }
+
+ /* Recurse into base classes. */
+ for (i = 0; i < TYPE_N_BASECLASSES (type); ++i)
+ compute_vtable_size (offset_hash, offset_vec, value_field (value, i));
+}
+
+/* Helper for gnuv3_print_vtable that prints a single vtable. */
+
+static void
+print_one_vtable (struct gdbarch *gdbarch, struct value *value,
+ int max_voffset,
+ struct value_print_options *opts)
+{
+ int i;
+ struct type *type = check_typedef (value_type (value));
+ struct value *vtable;
+ CORE_ADDR vt_addr;
+
+ vtable = gnuv3_get_vtable (gdbarch, type,
+ value_address (value)
+ + value_embedded_offset (value));
+ vt_addr = value_address (value_field (vtable,
+ vtable_field_virtual_functions));
+
+ printf_filtered (_("vtable for '%s' @ %s (subobject @ %s):\n"),
+ TYPE_SAFE_NAME (type),
+ paddress (gdbarch, vt_addr),
+ paddress (gdbarch, (value_address (value)
+ + value_embedded_offset (value))));
+
+ for (i = 0; i <= max_voffset; ++i)
+ {
+ struct value *vfn;
+ CORE_ADDR addr;
+ volatile struct gdb_exception ex;
+
+ printf_filtered ("[%d]: ", i);
+
+ vfn = value_subscript (value_field (vtable,
+ vtable_field_virtual_functions),
+ i);
+
+ if (gdbarch_vtable_function_descriptors (gdbarch))
+ vfn = value_addr (vfn);
+
+ TRY_CATCH (ex, RETURN_MASK_ERROR)
+ {
+ addr = value_as_address (vfn);
+ }
+ if (ex.reason < 0)
+ printf_filtered (_("<error: %s>"), ex.message);
+ else
+ print_function_pointer_address (gdbarch, addr, gdb_stdout,
+ opts->addressprint);
+ printf_filtered ("\n");
+ }
+}
+
+/* Implementation of the print_vtable method. */
+
+static void
+gnuv3_print_vtable (struct value *value)
+{
+ struct gdbarch *gdbarch;
+ struct type *type;
+ struct value *vtable;
+ struct value_print_options opts;
+ htab_t offset_hash;
+ struct cleanup *cleanup;
+ VEC (value_and_voffset_p) *result_vec;
+ struct value_and_voffset *iter;
+ int i, count;
+
+ value = coerce_ref (value);
+ type = check_typedef (value_type (value));
+ if (TYPE_CODE (type) == TYPE_CODE_PTR)
+ {
+ value = value_ind (value);
+ type = check_typedef (value_type (value));
+ }
+
+ get_user_print_options (&opts);
+
+ /* Respect 'set print object'. */
+ if (opts.objectprint)
+ {
+ value = value_full_object (value, NULL, 0, 0, 0);
+ type = check_typedef (value_type (value));
+ }
+
+ gdbarch = get_type_arch (type);
+ vtable = gnuv3_get_vtable (gdbarch, type,
+ value_as_address (value_addr (value)));
+
+ if (!vtable)
+ {
+ printf_filtered (_("This object does not have a virtual function table\n"));
+ return;
+ }
+
+ offset_hash = htab_create_alloc (1, hash_value_and_voffset,
+ eq_value_and_voffset,
+ xfree, xcalloc, xfree);
+ cleanup = make_cleanup_htab_delete (offset_hash);
+ make_cleanup (VEC_cleanup (value_and_voffset_p), &result_vec);
+
+ compute_vtable_size (offset_hash, &result_vec, value);
+
+ qsort (VEC_address (value_and_voffset_p, result_vec),
+ VEC_length (value_and_voffset_p, result_vec),
+ sizeof (value_and_voffset_p),
+ compare_value_and_voffset);
+
+ count = 0;
+ for (i = 0; VEC_iterate (value_and_voffset_p, result_vec, i, iter); ++i)
+ {
+ if (iter->max_voffset >= 0)
+ {
+ if (count > 0)
+ printf_filtered ("\n");
+ print_one_vtable (gdbarch, iter->value, iter->max_voffset, &opts);
+ ++count;
+ }
+ }
+
+ do_cleanups (cleanup);
+}
+
/* Determine if we are currently in a C++ thunk. If so, get the address
of the routine we are thunking to and continue to there instead. */
@@ -873,6 +1113,7 @@
gnu_v3_abi_ops.method_ptr_size = gnuv3_method_ptr_size;
gnu_v3_abi_ops.make_method_ptr = gnuv3_make_method_ptr;
gnu_v3_abi_ops.method_ptr_to_value = gnuv3_method_ptr_to_value;
+ gnu_v3_abi_ops.print_vtable = gnuv3_print_vtable;
gnu_v3_abi_ops.skip_trampoline = gnuv3_skip_trampoline;
gnu_v3_abi_ops.pass_by_reference = gnuv3_pass_by_reference;
}
Index: doc/gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.932
diff -u -r1.932 gdb.texinfo
--- doc/gdb.texinfo 13 Mar 2012 21:02:36 -0000 1.932
+++ doc/gdb.texinfo 15 Mar 2012 15:41:21 -0000
@@ -12788,6 +12788,12 @@
@var{typename}.
@xref{Symbols, ,Examining the Symbol Table}.
+@item info vtbl @var{expression}.
+The @code{info vtbl} command can be used to display the virtual
+method tables of the object computed by @var{expression}. This shows
+one entry per virtual table; there may be multiple virtual tables when
+multiple inheritance is in use.
+
@cindex C@t{++} symbol display
@item set print demangle
@itemx show print demangle
Index: testsuite/gdb.cp/virtfunc.cc
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.cp/virtfunc.cc,v
retrieving revision 1.6
diff -u -r1.6 virtfunc.cc
--- testsuite/gdb.cp/virtfunc.cc 4 Jan 2012 08:17:47 -0000 1.6
+++ testsuite/gdb.cp/virtfunc.cc 15 Mar 2012 15:41:24 -0000
@@ -111,6 +111,7 @@
E e;
V v;
VB vb;
+VA va;
A* pAa = &a;
Index: testsuite/gdb.cp/virtfunc.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.cp/virtfunc.exp,v
retrieving revision 1.25
diff -u -r1.25 virtfunc.exp
--- testsuite/gdb.cp/virtfunc.exp 16 Jan 2012 16:21:45 -0000 1.25
+++ testsuite/gdb.cp/virtfunc.exp 15 Mar 2012 15:41:24 -0000
@@ -226,6 +226,54 @@
}
}
+# A helper proc that creates a regular expression matching a
+# particular vtable. NAME is the type name. Each element of ARGS is
+# the name of a function in the vtable.
+
+proc make_one_vtable_result {name args} {
+ global hex
+
+ set nls "\[\r\n\]+"
+
+ set result "vtable for '${name}' @ $hex .subobject @ $hex.:$nls"
+ set count 0
+ foreach func $args {
+ append result ".${count}.: $hex <$func..>${nls}"
+ incr count
+ }
+
+ return $result
+}
+
+# Test "info vtbl".
+
+proc test_info_vtbl {} {
+ global hex
+
+ set nls "\[\r\n\]+"
+
+ set vt_A [make_one_vtable_result A A::f]
+ set vt_B [make_one_vtable_result B B::f]
+ set vt_V [make_one_vtable_result V VB::vvb V::vv]
+ set vt_V2 [make_one_vtable_result V VB::vvb "virtual thunk to E::vv"]
+ set vt_D [make_one_vtable_result D D::vg D::vd]
+ set vt_D2 [make_one_vtable_result D "non-virtual thunk to E::vg" D::vd]
+ set vt_E [make_one_vtable_result E E::f E::vg E::vv]
+
+ gdb_test "info vtbl a" "${vt_A}${vt_V}"
+ gdb_test "info vtbl b" "${vt_B}${vt_V}"
+ gdb_test "info vtbl c" "${vt_V}"
+ gdb_test "info vtbl d" "${vt_D}${vt_V}"
+ gdb_test "info vtbl e" "${vt_E}${vt_D2}${vt_V2}"
+ gdb_test "info vtbl pEe" "${vt_E}${vt_D2}${vt_V2}"
+
+ gdb_test "info vtbl" "Argument required.*"
+ gdb_test "info vtbl va" \
+ "This object does not have a virtual function table.*"
+ gdb_test "info vtbl all_count" \
+ "This object does not have a virtual function table.*"
+}
+
proc do_tests {} {
global srcdir subdir binfile
global gdb_prompt
@@ -244,6 +292,7 @@
return
}
test_ptype_of_classes
+ test_info_vtbl
gdb_breakpoint test_calls
gdb_test "continue" ".*Breakpoint .* test_calls.*" ""
^ permalink raw reply [flat|nested] 17+ messages in thread
* Crash regression [Re: [4/5] implement "info vtable"]
2012-03-15 15:43 ` Tom Tromey
@ 2012-03-16 8:10 ` Jan Kratochvil
2012-03-19 18:13 ` Tom Tromey
2012-07-19 9:34 ` [4/5] implement "info vtable" Andreas Schwab
1 sibling, 1 reply; 17+ messages in thread
From: Jan Kratochvil @ 2012-03-16 8:10 UTC (permalink / raw)
To: Tom Tromey; +Cc: Pedro Alves, gdb-patches
On Thu, 15 Mar 2012 16:42:39 +0100, Tom Tromey wrote:
> Here's what I am checking in.
>
> Tom
>
> 2012-03-15 Tom Tromey <tromey@redhat.com>
>
> * gnu-v3-abi.c (struct value_and_voffset): New.
> (hash_value_and_voffset, eq_value_and_voffset)
> (compare_value_and_voffset, compute_vtable_size)
> (print_one_vtable, gnuv3_print_vtable): New functions.
> (init_gnuv3_ops): Initialize 'print_vtable' field.
> * cp-support.c (info_vtbl_command): New function.
> (_initialize_cp_support): Add "info vtbl".
> * cp-abi.h (cplus_print_vtable): Declare.
> (struct cp_abi_ops) <print_vtable>: New field.
> * cp-abi.c (cplus_print_vtable): New function.
> * NEWS: Update.
>
> 2012-03-15 Tom Tromey <tromey@redhat.com>
>
> * gdb.texinfo (Debugging C Plus Plus): Document "info vtbl".
>
> 2012-03-15 Tom Tromey <tromey@redhat.com>
>
> * gdb.cp/virtfunc.exp (make_one_vtable_result): New proc.
> (test_info_vtbl): Likewise.
> (do_tests): Call test_info_vtbl.
> * gdb.cp/virtfunc.cc (va): New global.
Crash regression for: gdb.cp/virtfunc.exp
Expecting due to -lmcheck.
Reproducible on x86_64-fedora16-linux-gnu.
de2f714807e42df981348b72164f60ea71b37543 is the first bad commit
commit de2f714807e42df981348b72164f60ea71b37543
Author: Tom Tromey <tromey@redhat.com>
Date: Thu Mar 15 15:43:05 2012 +0000
* gnu-v3-abi.c (struct value_and_voffset): New.
[...]
Regards,
Jan
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Crash regression [Re: [4/5] implement "info vtable"]
2012-03-16 8:10 ` Crash regression [Re: [4/5] implement "info vtable"] Jan Kratochvil
@ 2012-03-19 18:13 ` Tom Tromey
0 siblings, 0 replies; 17+ messages in thread
From: Tom Tromey @ 2012-03-19 18:13 UTC (permalink / raw)
To: Jan Kratochvil; +Cc: Pedro Alves, gdb-patches
>>>>> "Jan" == Jan Kratochvil <jan.kratochvil@redhat.com> writes:
Jan> Crash regression for: gdb.cp/virtfunc.exp
Jan> Expecting due to -lmcheck.
Jan> Reproducible on x86_64-fedora16-linux-gnu.
I'm checking in the appended.
I verified that this fixes it using valgrind.
Tom
2012-03-19 Tom Tromey <tromey@redhat.com>
* gnu-v3-abi.c (gnuv3_print_vtable): Initialize 'result_vec'.
diff --git a/gdb/gnu-v3-abi.c b/gdb/gnu-v3-abi.c
index 72ca2a1..1095c60 100644
--- a/gdb/gnu-v3-abi.c
+++ b/gdb/gnu-v3-abi.c
@@ -907,7 +907,7 @@ gnuv3_print_vtable (struct value *value)
struct value_print_options opts;
htab_t offset_hash;
struct cleanup *cleanup;
- VEC (value_and_voffset_p) *result_vec;
+ VEC (value_and_voffset_p) *result_vec = NULL;
struct value_and_voffset *iter;
int i, count;
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [4/5] implement "info vtable"
2012-03-15 15:43 ` Tom Tromey
2012-03-16 8:10 ` Crash regression [Re: [4/5] implement "info vtable"] Jan Kratochvil
@ 2012-07-19 9:34 ` Andreas Schwab
2012-07-19 17:01 ` Tom Tromey
1 sibling, 1 reply; 17+ messages in thread
From: Andreas Schwab @ 2012-07-19 9:34 UTC (permalink / raw)
To: Tom Tromey; +Cc: Pedro Alves, gdb-patches
Tom Tromey <tromey@redhat.com> writes:
> +# A helper proc that creates a regular expression matching a
> +# particular vtable. NAME is the type name. Each element of ARGS is
> +# the name of a function in the vtable.
> +
> +proc make_one_vtable_result {name args} {
> + global hex
> +
> + set nls "\[\r\n\]+"
> +
> + set result "vtable for '${name}' @ $hex .subobject @ $hex.:$nls"
> + set count 0
> + foreach func $args {
> + append result ".${count}.: $hex <$func..>${nls}"
> + incr count
> + }
> +
> + return $result
> +}
info vtbl a
vtable for 'A' @ 0x10013c28 (subobject @ 0x10014510):
[0]: @0x10014278: 0x10001b0c <A::f()>
vtable for 'V' @ 0x10013c50 (subobject @ 0x10014520):
[0]: @0x100143c8: 0x10001e14 <VB::vvb()>
[1]: @0x10014338: 0x10001c94 <V::vv()>
(gdb) FAIL: gdb.cp/virtfunc.exp: info vtbl a
Andreas.
--
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5
"And now for something completely different."
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [4/5] implement "info vtable"
2012-07-19 9:34 ` [4/5] implement "info vtable" Andreas Schwab
@ 2012-07-19 17:01 ` Tom Tromey
2012-07-20 8:33 ` Andreas Schwab
0 siblings, 1 reply; 17+ messages in thread
From: Tom Tromey @ 2012-07-19 17:01 UTC (permalink / raw)
To: Andreas Schwab; +Cc: Pedro Alves, gdb-patches
Andreas> [0]: @0x10014278: 0x10001b0c <A::f()>
Please try the appended.
Tom
b/gdb/testsuite/ChangeLog:
2012-07-19 Tom Tromey <tromey@redhat.com>
* gdb.cp/virtfunc.exp (make_one_vtable_result): Handle function
descriptor.
(test_info_vtbl): Remove unused globals.
diff --git a/gdb/testsuite/gdb.cp/virtfunc.exp b/gdb/testsuite/gdb.cp/virtfunc.exp
index 4621a74..bef71c8 100644
--- a/gdb/testsuite/gdb.cp/virtfunc.exp
+++ b/gdb/testsuite/gdb.cp/virtfunc.exp
@@ -235,7 +235,9 @@ proc make_one_vtable_result {name args} {
set result "vtable for '${name}' @ $hex .subobject @ $hex.:$nls"
set count 0
foreach func $args {
- append result ".${count}.: $hex <$func..>${nls}"
+ # The (@$hex: ) part is because we might see a descriptor
+ # instead.
+ append result ".${count}.: (@$hex: )?$hex <$func..>${nls}"
incr count
}
@@ -245,10 +247,6 @@ proc make_one_vtable_result {name args} {
# Test "info vtbl".
proc test_info_vtbl {} {
- global hex
-
- set nls "\[\r\n\]+"
-
set vt_A [make_one_vtable_result A A::f]
set vt_B [make_one_vtable_result B B::f]
set vt_V [make_one_vtable_result V VB::vvb V::vv]
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [4/5] implement "info vtable"
2012-07-19 17:01 ` Tom Tromey
@ 2012-07-20 8:33 ` Andreas Schwab
2012-07-20 14:24 ` Tom Tromey
0 siblings, 1 reply; 17+ messages in thread
From: Andreas Schwab @ 2012-07-20 8:33 UTC (permalink / raw)
To: Tom Tromey; +Cc: Pedro Alves, gdb-patches
I'm still seeing these failures:
info vtbl e.
vtable for 'E' @ 0x100138e8 (subobject @ 0x100145b0):.
[0]: @0x100142c0: 0x10001b90 <E::f()>.
[1]: @0x10014308: 0x10001c0c <E::vg()>.
[2]: @0x10014368: 0x10001ce8 <E::vv()>.
.
vtable for 'D' @ 0x10013918 (subobject @ 0x100145c0):.
[0]: @0x100142f0: 0x10001c04 <._ZThn16_N1E2vgEv>.
[1]: @0x10014398: 0x10001d8c <D::vd()>.
.
vtable for 'V' @ 0x10013960 (subobject @ 0x100145e0):.
[0]: @0x100143c8: 0x10001e14 <VB::vvb()>.
[1]: @0x10014350: 0x10001cd8 <._ZTv0_n32_N1E2vvEv>.
(gdb) FAIL: gdb.cp/virtfunc.exp: info vtbl e
info vtbl pEe.
vtable for 'E' @ 0x100138e8 (subobject @ 0x100145b0):.
[0]: @0x100142c0: 0x10001b90 <E::f()>.
[1]: @0x10014308: 0x10001c0c <E::vg()>.
[2]: @0x10014368: 0x10001ce8 <E::vv()>.
.
vtable for 'D' @ 0x10013918 (subobject @ 0x100145c0):.
[0]: @0x100142f0: 0x10001c04 <._ZThn16_N1E2vgEv>.
[1]: @0x10014398: 0x10001d8c <D::vd()>.
.
vtable for 'V' @ 0x10013960 (subobject @ 0x100145e0):.
[0]: @0x100143c8: 0x10001e14 <VB::vvb()>.
[1]: @0x10014350: 0x10001cd8 <._ZTv0_n32_N1E2vvEv>.
(gdb) FAIL: gdb.cp/virtfunc.exp: info vtbl pEe
step.
0x0000000010001c04 in ._ZThn16_N1E2vgEv () at ../../../gdb/gdb/testsuite/gdb.cp/virtfunc.cc:203.
203 int D::vg() {return 100+d;}.
(gdb) FAIL: gdb.cp/virtfunc.exp: step through thunk into E::vg
Andreas.
--
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5
"And now for something completely different."
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [4/5] implement "info vtable"
2012-07-20 8:33 ` Andreas Schwab
@ 2012-07-20 14:24 ` Tom Tromey
2012-07-20 14:29 ` Andreas Schwab
0 siblings, 1 reply; 17+ messages in thread
From: Tom Tromey @ 2012-07-20 14:24 UTC (permalink / raw)
To: Andreas Schwab; +Cc: Pedro Alves, gdb-patches
>>>>> "Andreas" == Andreas Schwab <schwab@linux-m68k.org> writes:
Andreas> I'm still seeing these failures:
Andreas> info vtbl e.
Andreas> vtable for 'E' @ 0x100138e8 (subobject @ 0x100145b0):.
Andreas> [0]: @0x100142c0: 0x10001b90 <E::f()>.
What did you do in order to get this output?
Tom
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [4/5] implement "info vtable"
2012-07-20 14:24 ` Tom Tromey
@ 2012-07-20 14:29 ` Andreas Schwab
2012-07-20 16:23 ` Tom Tromey
0 siblings, 1 reply; 17+ messages in thread
From: Andreas Schwab @ 2012-07-20 14:29 UTC (permalink / raw)
To: Tom Tromey; +Cc: Pedro Alves, gdb-patches
Tom Tromey <tromey@redhat.com> writes:
>>>>>> "Andreas" == Andreas Schwab <schwab@linux-m68k.org> writes:
>
> Andreas> I'm still seeing these failures:
> Andreas> info vtbl e.
> Andreas> vtable for 'E' @ 0x100138e8 (subobject @ 0x100145b0):.
> Andreas> [0]: @0x100142c0: 0x10001b90 <E::f()>.
>
> What did you do in order to get this output?
If you mean the trailing dots you should pretend they are absent.
Andreas.
--
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5
"And now for something completely different."
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [4/5] implement "info vtable"
2012-07-20 14:29 ` Andreas Schwab
@ 2012-07-20 16:23 ` Tom Tromey
2012-07-20 17:34 ` Andreas Schwab
0 siblings, 1 reply; 17+ messages in thread
From: Tom Tromey @ 2012-07-20 16:23 UTC (permalink / raw)
To: Andreas Schwab; +Cc: Pedro Alves, gdb-patches
>>>>> "Andreas" == Andreas Schwab <schwab@linux-m68k.org> writes:
Andreas> Tom Tromey <tromey@redhat.com> writes:
>>>>>>> "Andreas" == Andreas Schwab <schwab@linux-m68k.org> writes:
>>
Andreas> I'm still seeing these failures:
Andreas> info vtbl e.
Andreas> vtable for 'E' @ 0x100138e8 (subobject @ 0x100145b0):.
Andreas> [0]: @0x100142c0: 0x10001b90 <E::f()>.
Tom> What did you do in order to get this output?
Andreas> If you mean the trailing dots you should pretend they are absent.
I don't see descriptors here.
I'd like to reproduce the problem, if I can.
What platform are you on? What compiler did you use? Any special
flags? Etc.
thanks,
Tom
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [4/5] implement "info vtable"
2012-07-20 16:23 ` Tom Tromey
@ 2012-07-20 17:34 ` Andreas Schwab
2012-07-20 17:48 ` Tom Tromey
0 siblings, 1 reply; 17+ messages in thread
From: Andreas Schwab @ 2012-07-20 17:34 UTC (permalink / raw)
To: Tom Tromey; +Cc: Pedro Alves, gdb-patches
You are barking up the wrong tree. The failures are due to the missing
demangling of the thunk functions, caused by nonexisting debug
information.
Andreas.
--
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5
"And now for something completely different."
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [4/5] implement "info vtable"
2012-07-20 17:34 ` Andreas Schwab
@ 2012-07-20 17:48 ` Tom Tromey
2012-07-20 18:08 ` Andreas Schwab
0 siblings, 1 reply; 17+ messages in thread
From: Tom Tromey @ 2012-07-20 17:48 UTC (permalink / raw)
To: Andreas Schwab; +Cc: Pedro Alves, gdb-patches
Andreas> You are barking up the wrong tree. The failures are due to the missing
Andreas> demangling of the thunk functions, caused by nonexisting debug
Andreas> information.
How did that happen, then?
The tree I'm trying to bark up is getting a complete bug report from
you.
Tom
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [4/5] implement "info vtable"
2012-07-20 17:48 ` Tom Tromey
@ 2012-07-20 18:08 ` Andreas Schwab
0 siblings, 0 replies; 17+ messages in thread
From: Andreas Schwab @ 2012-07-20 18:08 UTC (permalink / raw)
To: Tom Tromey; +Cc: Pedro Alves, gdb-patches
Tom Tromey <tromey@redhat.com> writes:
> Andreas> You are barking up the wrong tree. The failures are due to the missing
> Andreas> demangling of the thunk functions, caused by nonexisting debug
> Andreas> information.
>
> How did that happen, then?
._ZThn16_N1E2vgEv is a valid mangled name.
Andreas.
--
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5
"And now for something completely different."
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2012-07-20 18:08 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-02-28 21:48 [4/5] implement "info vtable" Tom Tromey
2012-02-29 18:20 ` Eli Zaretskii
2012-03-01 14:52 ` Pedro Alves
2012-03-01 17:36 ` Tom Tromey
2012-03-01 20:18 ` Pedro Alves
2012-03-15 15:43 ` Tom Tromey
2012-03-16 8:10 ` Crash regression [Re: [4/5] implement "info vtable"] Jan Kratochvil
2012-03-19 18:13 ` Tom Tromey
2012-07-19 9:34 ` [4/5] implement "info vtable" Andreas Schwab
2012-07-19 17:01 ` Tom Tromey
2012-07-20 8:33 ` Andreas Schwab
2012-07-20 14:24 ` Tom Tromey
2012-07-20 14:29 ` Andreas Schwab
2012-07-20 16:23 ` Tom Tromey
2012-07-20 17:34 ` Andreas Schwab
2012-07-20 17:48 ` Tom Tromey
2012-07-20 18:08 ` Andreas Schwab
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox