[2/2] gdb: Fix testsuite issue in gdb.arch/amd64-disp-step-avx.exp

Message ID 963bfa7c7483c4c907f4a63e9588b243845c8acd.1521722330.git.andrew.burgess@embecosm.com
State New
Headers show
Series
  • Test fix in gdb.arch/* tests
Related show

Commit Message

Andrew Burgess March 22, 2018, 12:57 p.m.
This test starts up and confirms that $xmm0 has the value 0, it then
modifies $xmm0 (in the inferior) and confirms that the new value can
be read (in GDB).

On some machines I was noticing that this test would occasionally
fail, and on investigation I believe that the reason for this is that
the test is linked as a dynamically linked executable and makes use of
the system libraries during startup.  The reason that this causes
problems is that both the runtime linker and the startup code run
before main can, and do (on at least some platforms) make use of the
XMM registers.

In this commit I modify the test program slightly to allow it to be
linked statically, without using the startup libraries.  Now by the
time GDB reaches the symbol main then we have only executed one 'nop'
instruction, and the XMM registers will all have the value 0.  I've
extended the existing check in the test script to cover $xmm0 through
to $xmm15 (originally only $xmm0 was checked).

The test program is still linked against libc in order that we can
call the exit function, however, we now call _exit rather than exit in
order to avoid all of the usual cleanup that exit does.  This clean up
tries to tear down things that are usually setup during the startup
code, but now this isn't called calling exit will just result in a
crash.

gdb/testsuite/ChangeLog:

	* gdb.arch/amd64-disp-step-avx.S: Add '_start' label.
	(done): Call '_exit' not 'exit' to avoid atexit handlers.
	* gdb.arch/amd64-disp-step-avx.exp: Pass -static, and
	-nostartfiles when compiling the test.  Confirm that all registers
	xmm0 to xmm15 are initially 0.
---
 gdb/testsuite/ChangeLog                        |  8 ++++++++
 gdb/testsuite/gdb.arch/amd64-disp-step-avx.S   |  8 +++++---
 gdb/testsuite/gdb.arch/amd64-disp-step-avx.exp | 12 ++++++++----
 3 files changed, 21 insertions(+), 7 deletions(-)

-- 
2.14.3

Comments

Pedro Alves March 22, 2018, 1:44 p.m. | #1
Hi Andrew,

Sounds fine to me in principle.  A couple comments below.

On 03/22/2018 12:57 PM, Andrew Burgess wrote:

> @@ -103,8 +105,10 @@ proc disp_step_func { func } {

>  with_test_prefix "vex2" {

>      # This case writes to the 'xmm0' register.  Confirm the register's

>      # value is what we believe it is before the AVX instruction runs.

> -    gdb_test "p /x \$xmm0.uint128" " = 0x0" \

> -	"xmm0 has expected value before"

> +    for {set i 0 } { $i < 16 } { incr i } {

> +	gdb_test "p /x \$xmm${i}.uint128" " = 0x0" \

> +	    "xmm${i} has expected value before"

> +    }


This leaves a slight disconnect between the comment and the
code.  I.e., someone reading the comment may wonder why
we check more than xmm0?

Also, should we test xmm1-15 are still 0 after, too, for
completeness?

>  

>      disp_step_func "test_rip_vex2"

>  

> 


Thanks,
Pedro Alves
Andrew Burgess March 22, 2018, 11:01 p.m. | #2
* Pedro Alves <palves@redhat.com> [2018-03-22 13:44:51 +0000]:

> Hi Andrew,

> 

> Sounds fine to me in principle.  A couple comments below.

> 

> On 03/22/2018 12:57 PM, Andrew Burgess wrote:

> 

> > @@ -103,8 +105,10 @@ proc disp_step_func { func } {

> >  with_test_prefix "vex2" {

> >      # This case writes to the 'xmm0' register.  Confirm the register's

> >      # value is what we believe it is before the AVX instruction runs.

> > -    gdb_test "p /x \$xmm0.uint128" " = 0x0" \

> > -	"xmm0 has expected value before"

> > +    for {set i 0 } { $i < 16 } { incr i } {

> > +	gdb_test "p /x \$xmm${i}.uint128" " = 0x0" \

> > +	    "xmm${i} has expected value before"

> > +    }

> 

> This leaves a slight disconnect between the comment and the

> code.  I.e., someone reading the comment may wonder why

> we check more than xmm0?

> 

> Also, should we test xmm1-15 are still 0 after, too, for

> completeness?

> 

> >  

> >      disp_step_func "test_rip_vex2"

> >  


Thanks for the review.

I've updated the patch inline with your feedback, the comment has
been expanded to better match what we actually do, and we now confirm
that xmm1 -> xmm15 are still 0 after the test instruction.

Checked on x86-64 GNU/Linux and buildbot.

Thanks,
Andrew

---

gdb: Fix testsuite issue in gdb.arch/amd64-disp-step-avx.exp

This test starts up and confirms that $xmm0 has the value 0, it then
modifies $xmm0 (in the inferior) and confirms that the new value can
be read (in GDB).

On some machines I was noticing that this test would occasionally
fail, and on investigation I believe that the reason for this is that
the test is linked as a dynamically linked executable and makes use of
the system libraries during startup.  The reason that this causes
problems is that both the runtime linker and the startup code run
before main can, and do (on at least some platforms) make use of the
XMM registers.

In this commit I modify the test program slightly to allow it to be
linked statically, without using the startup libraries.  Now by the
time GDB reaches the symbol main we have only executed one 'nop'
instruction, and the XMM registers should all have the value 0.  I've
extended the test script to confirm that $xmm0 to $xmm15 are all
initially 0, and I also check that at the point after $xmm0 has been
modified, all the other XMM registers ($xmm1 to $xmm15) are still 0.

The test program is still linked against libc in order that we can
call the exit function, however, we now call _exit rather than exit in
order to avoid all of the usual cleanup that exit does.  This clean up
tries to tear down things that are usually setup during the startup
code, but now this isn't called calling exit will just result in a
crash.

gdb/testsuite/ChangeLog:

	* gdb.arch/amd64-disp-step-avx.S: Add '_start' label.
	(done): Call '_exit' not 'exit' to avoid atexit handlers.
	* gdb.arch/amd64-disp-step-avx.exp: Pass -static, and
	-nostartfiles when compiling the test.  Confirm that all registers
	xmm0 to xmm15 are initially 0, and that xmm1 to xmm15 are 0 after.
---
 gdb/testsuite/ChangeLog                        |  8 ++++++++
 gdb/testsuite/gdb.arch/amd64-disp-step-avx.S   |  8 +++++---
 gdb/testsuite/gdb.arch/amd64-disp-step-avx.exp | 24 +++++++++++++++++++-----
 3 files changed, 32 insertions(+), 8 deletions(-)

diff --git a/gdb/testsuite/gdb.arch/amd64-disp-step-avx.S b/gdb/testsuite/gdb.arch/amd64-disp-step-avx.S
index b56a552f6e6..1c06ceebab3 100644
--- a/gdb/testsuite/gdb.arch/amd64-disp-step-avx.S
+++ b/gdb/testsuite/gdb.arch/amd64-disp-step-avx.S
@@ -20,9 +20,11 @@
 
 	.text
 
-	.global main
-main:
+	.global _start,main
+_start:
 	nop
+main:
+        nop
 
 /***********************************************/
 
@@ -59,7 +61,7 @@ ro_var:
 
 done:
 	mov $0,%rdi
-	call exit
+	call _exit
 	hlt
 
 /* RIP-relative data for VEX3 test above.  */
diff --git a/gdb/testsuite/gdb.arch/amd64-disp-step-avx.exp b/gdb/testsuite/gdb.arch/amd64-disp-step-avx.exp
index 1f85fa77c1a..fe6eb6729be 100644
--- a/gdb/testsuite/gdb.arch/amd64-disp-step-avx.exp
+++ b/gdb/testsuite/gdb.arch/amd64-disp-step-avx.exp
@@ -25,7 +25,10 @@ if { ![istarget x86_64-*-* ] || ![is_lp64_target] } {
 
 standard_testfile .S
 
-if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } {
+set options [list debug \
+		 additional_flags=-static \
+		 additional_flags=-nostartfiles]
+if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} $options] } {
     return -1
 }
 
@@ -100,10 +103,15 @@ proc disp_step_func { func } {
 
 # Test a VEX2-encoded RIP-relative instruction.
 with_test_prefix "vex2" {
-    # This case writes to the 'xmm0' register.  Confirm the register's
-    # value is what we believe it is before the AVX instruction runs.
-    gdb_test "p /x \$xmm0.uint128" " = 0x0" \
-	"xmm0 has expected value before"
+    # This test writes to the 'xmm0' register.  As the test is
+    # statically linked, we know that the XMM registers should all
+    # have the default value of 0 at this point in time.  We're about
+    # to run an AVX instruction that will modify $xmm0, but lets first
+    # confirm that all XMM registers are 0.
+    for {set i 0 } { $i < 16 } { incr i } {
+	gdb_test "p /x \$xmm${i}.uint128" " = 0x0" \
+	    "xmm${i} has expected value before"
+    }
 
     disp_step_func "test_rip_vex2"
 
@@ -111,6 +119,12 @@ with_test_prefix "vex2" {
     # modified xmm0.
     gdb_test "p /x \$xmm0.uint128" " = 0x1122334455667788" \
 	"xmm0 has expected value after"
+
+    # And all of the other XMM register should still be 0.
+    for {set i 1 } { $i < 16 } { incr i } {
+	gdb_test "p /x \$xmm${i}.uint128" " = 0x0" \
+	    "xmm${i} has expected value after"
+    }
 }
 
 # Test a VEX3-encoded RIP-relative instruction.
-- 
2.14.3
Pedro Alves March 23, 2018, 10:13 a.m. | #3
On 03/22/2018 11:01 PM, Andrew Burgess wrote:

> Thanks for the review.

> 

> I've updated the patch inline with your feedback, the comment has

> been expanded to better match what we actually do, and we now confirm

> that xmm1 -> xmm15 are still 0 after the test instruction.

> 

> Checked on x86-64 GNU/Linux and buildbot.


Perfect, OK.

Thanks,
Pedro Alves

Patch

diff --git a/gdb/testsuite/gdb.arch/amd64-disp-step-avx.S b/gdb/testsuite/gdb.arch/amd64-disp-step-avx.S
index b56a552f6e6..1c06ceebab3 100644
--- a/gdb/testsuite/gdb.arch/amd64-disp-step-avx.S
+++ b/gdb/testsuite/gdb.arch/amd64-disp-step-avx.S
@@ -20,9 +20,11 @@ 
 
 	.text
 
-	.global main
-main:
+	.global _start,main
+_start:
 	nop
+main:
+        nop
 
 /***********************************************/
 
@@ -59,7 +61,7 @@  ro_var:
 
 done:
 	mov $0,%rdi
-	call exit
+	call _exit
 	hlt
 
 /* RIP-relative data for VEX3 test above.  */
diff --git a/gdb/testsuite/gdb.arch/amd64-disp-step-avx.exp b/gdb/testsuite/gdb.arch/amd64-disp-step-avx.exp
index 362ed7b7b3a..d25f9692360 100644
--- a/gdb/testsuite/gdb.arch/amd64-disp-step-avx.exp
+++ b/gdb/testsuite/gdb.arch/amd64-disp-step-avx.exp
@@ -25,8 +25,10 @@  if { ![istarget x86_64-*-* ] || ![is_lp64_target] } {
 
 standard_testfile .S
 
-if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} \
-	  [list debug]] } {
+set options [list debug \
+		 additional_flags=-static \
+		 additional_flags=-nostartfiles]
+if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} $options] } {
     return -1
 }
 
@@ -103,8 +105,10 @@  proc disp_step_func { func } {
 with_test_prefix "vex2" {
     # This case writes to the 'xmm0' register.  Confirm the register's
     # value is what we believe it is before the AVX instruction runs.
-    gdb_test "p /x \$xmm0.uint128" " = 0x0" \
-	"xmm0 has expected value before"
+    for {set i 0 } { $i < 16 } { incr i } {
+	gdb_test "p /x \$xmm${i}.uint128" " = 0x0" \
+	    "xmm${i} has expected value before"
+    }
 
     disp_step_func "test_rip_vex2"