Commit Message
Some of the tests in inherit.exp make invalid assumptions about vtable
pointers in printed values.
I find that these tests pass on most targets, but fail on a few targets,
including mips-sde.
The reason is that the "_vptr" entries in C++ types do not point to the
head of the vtable, but point to the address following the last entry in
the table, which mean that when GDB prints the symbol associated with
the address, it actually prints the name of the value that follows the
table in memory.
Historically, it appears to have been fairly predictable what symbol
would follow the vtable, and remains so on most targets, but this is no
longer true in general (or perhaps never was). In mips-sde, in
particular, the "VTT for *" symbols are placed in a completely different
section, so cannot follow the vtable. The alignment and padding appears
to have varied slightly, and the order of vtable and typeinfo sections
appears to have varied also (or maybe the test was never right?)
The attached patch adds new expect patterns that don't require any
specific symbol at all, since they're basically meaningless.
OK to commit?
Andrew
Comments
Andrew Stubbs <ams@codesourcery.com> writes:
Hi Andrew,
> Some of the tests in inherit.exp make invalid assumptions about vtable
> pointers in printed values.
>
> I find that these tests pass on most targets, but fail on a few
> targets, including mips-sde.
I think there are some fails in gdb.cp/virtbase.exp of this kind. Did
you see them on mips? They fail on aarch64 (and nios2 IIRC).
>
> The reason is that the "_vptr" entries in C++ types do not point to
> the head of the vtable, but point to the address following the last
> entry in the table, which mean that when GDB prints the symbol
I think you are right. IIUC, negative index is used to identify the
vptr, but I am not very sure, still need some time to understand c++ stuff.
> associated with the address, it actually prints the name of the value
> that follows the table in memory.
>
> Historically, it appears to have been fairly predictable what symbol
> would follow the vtable, and remains so on most targets, but this is
> no longer true in general (or perhaps never was). In mips-sde, in
> particular, the "VTT for *" symbols are placed in a completely
> different section, so cannot follow the vtable. The alignment and
> padding appears to have varied slightly, and the order of vtable and
> typeinfo sections appears to have varied also (or maybe the test was
> never right?)
>
> The attached patch adds new expect patterns that don't require any
> specific symbol at all, since they're basically meaningless.
I probably need several days to investigate VTT, vptr table and etc.
Ping us if you don't get response from me in one week.
On 06/10/15 15:43, Yao Qi wrote:
> I think there are some fails in gdb.cp/virtbase.exp of this kind. Did
> you see them on mips? They fail on aarch64 (and nios2 IIRC).
I now have the full results ... yes, I see similar failures in virtbase.exp:
The pattern is "_vptr.Middle = $hex,"
and the output is "_vptr.Middle = 0x8001ab84 <VTT for ph::Derived>,"
> I probably need several days to investigate VTT, vptr table and etc.
> Ping us if you don't get response from me in one week.
I don't really understand why the code is the way it is, but the GDB
testsuite's expectations definitely seem unrealistic.
Did you make any progress?
Andrew
Andrew Stubbs <ams@codesourcery.com> writes:
> The reason is that the "_vptr" entries in C++ types do not point to
> the head of the vtable, but point to the address following the last
> entry in the table, which mean that when GDB prints the symbol
> associated with the address, it actually prints the name of the value
> that follows the table in memory.
Yes, gcc option -fdump-class-hierarchy is quite useful in this case,
Class vE
size=72 align=8
base size=16 base align=8
vE (0x0x7ff4b6000c98) 0
vptridx=0u vptr=((& vE::vtable for vE) + 48u)
vD (0x0x7ff4b61970e0) 16 virtual
subvttidx=32u vptridx=8u vbaseoffset=-24 vptr=((& vE::vtable for vE) + 88u)
vB (0x0x7ff4b6000d00) 32 virtual
subvttidx=56u vptridx=16u vbaseoffset=-32 vptr=((& vE::vtable for vE) + 112u)
vA (0x0x7ff4b618d060) 48 virtual
vbaseoffset=-40
vC (0x0x7ff4b6000d68) 56 virtual
subvttidx=64u vptridx=24u vbaseoffset=-48 vptr=((& vE::vtable for vE) + 136u) <-- [1]
vA (0x0x7ff4b618d060) alternative-path
Vtable for vE
vE::vtable for vE: 17u entries
0 56u
8 48u
16 32u
24 16u
32 (int (*)(...))0
40 (int (*)(...))(& typeinfo for vE)
48 40u
56 32u
64 16u
72 (int (*)(...))-16
80 (int (*)(...))(& typeinfo for vE)
88 16u
96 (int (*)(...))-32
104 (int (*)(...))(& typeinfo for vE)
112 18446744073709551608u
120 (int (*)(...))-56
128 (int (*)(...))(& typeinfo for vE)
As we can see vptr in [1] points to 136 bytes after vE::vtable (because
vptr is accessed as an array by negative index), but vE::vtable is only
128 bytes big, so anything can be there.
>
> Index: gdb/testsuite/gdb.cp/inherit.exp
> ===================================================================
> --- gdb/testsuite/gdb.cp/inherit.exp (revision 455195)
> +++ gdb/testsuite/gdb.cp/inherit.exp (working copy)
> @@ -524,6 +524,11 @@
> # gcc HEAD 2004-07-31 -gstabs+
> pass $name
> }
> + -re "$vhn = \{<vA> = \{va = 3, vx = 4\}, $re_vbptr_3 = ${hex}( <\[^>]*>)?, vb = 5, vx = 6\}$nl$gdb_prompt $" {
> + # gcc HEAD 2015?+
> + # the vptr is set to the address *after* the vtable, so the symbol shown is unpredictable
This line is too long, multiple instances of this problem. Otherwise,
that patch is OK. We can also garbage collect some patterns, but this
change can be done in follow-up patch.
Do you plan to fix fails in virtbase.exp too?
2015-10-02 Andrew Stubbs <ams@codesourcery.com>
gdb/testsuite/
* gdb.cp/inherit.exp (print g_vB, print g_vC, print g_vD,
print g_vE): Add new pass patterns.
===================================================================
@@ -524,6 +524,11 @@
# gcc HEAD 2004-07-31 -gstabs+
pass $name
}
+ -re "$vhn = \{<vA> = \{va = 3, vx = 4\}, $re_vbptr_3 = ${hex}( <\[^>]*>)?, vb = 5, vx = 6\}$nl$gdb_prompt $" {
+ # gcc HEAD 2015?+
+ # the vptr is set to the address *after* the vtable, so the symbol shown is unpredictable
+ pass "$name (symbols ignored)"
+ }
}
# Print all members of g_vC.
@@ -552,6 +557,11 @@
# gcc HEAD 2004-07-31 -gstabs+
pass $name
}
+ -re "$vhn = \{<vA> = \{va = 7, vx = 8\}, $re_vbptr_3 = ${hex}( <\[^>]*>)?, vc = 9, vx = 10\}$nl$gdb_prompt $" {
+ # gcc HEAD 2015?+
+ # the vptr is set to the address *after* the vtable, so the symbol shown is unpredictable
+ pass "$name (symbols ignored)"
+ }
}
}
@@ -623,6 +633,11 @@
# gcc 3.3.2 -gstabs+
pass "$name"
}
+ -re "$vhn = \{<vB> = \{<vA> = \{va = 19, vx = 20\}, $re_vbptr_3_vB = ${hex}( <\[^>]*>)?, vb = 21, vx = 22\}, <vC> = \{$re_vbptr_3_vC = ${hex}( <\[^>]*>)?, vc = 23, vx = 24\}, $re_vbptr_3_vD = ${hex}( <\[^>]*>)?, vd = 25, vx = 26\}$nl$gdb_prompt $" {
+ # gcc HEAD 2015?+
+ # the vptr is set to the address *after* the vtable, so the symbol shown is unpredictable
+ pass "$name (symbols ignored)"
+ }
}
# Print all members of g_vE.
@@ -650,6 +665,11 @@
# gcc HEAD 2004-07-31 -gstabs+
pass $name
}
+ -re "$vhn = \{<vD> = \{<vB> = \{<vA> = \{va = 0, vx = 0\}, $re_vbptr_3_vB = ${hex}( <\[^>]*>)?, vb = 0, vx = 0\}, <vC> = \{$re_vbptr_3_vC = ${hex}( <\[^>]*>)?, vc = 0, vx = 0\}, $re_vbptr_3_vD = ${hex}( <\[^>]*>)?, vd = 0, vx = 0\}, $re_vbptr_3_vE = ${hex}( <\[^>]*>)?, ve = 27, vx = 28\}$nl$gdb_prompt $" {
+ # gcc HEAD 2015?+
+ # the vptr is set to the address *after* the vtable, so the symbol shown is unpredictable
+ pass "$name (symbols ignored)"
+ }
}
}