Fix inherit.exp tests

Message ID 560E4718.80707@codesourcery.com
State Superseded
Headers

Commit Message

Andrew Stubbs Oct. 2, 2015, 8:58 a.m. UTC
  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

Yao Qi Oct. 6, 2015, 2:43 p.m. UTC | #1
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.
  
Andrew Stubbs Oct. 9, 2015, 10:26 a.m. UTC | #2
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
  
Yao Qi Oct. 13, 2015, 4:21 p.m. UTC | #3
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?
  

Patch

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.

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
+	    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)"
+	}
     }
 }