diff mbox

[testsuite] Fix paginate-*.exp race for "read1"

Message ID 20140722173635.GA9532@host2.jankratochvil.net
State New
Headers show

Commit Message

Jan Kratochvil July 22, 2014, 5:36 p.m. UTC
Hi Pedro,

these testcase have racy results:
	gdb.base/double-prompt-target-event-error.exp
	gdb.base/paginate-after-ctrl-c-running.exp
	gdb.base/paginate-bg-execution.exp
	gdb.base/paginate-execution-startup.exp
	gdb.base/paginate-inferior-exit.exp

reproducible with "read1" from:
	reproducer for races of expect incomplete reads
	http://sourceware.org/bugzilla/show_bug.cgi?id=12649

# Prevent gdb_test_multiple considering an error -re "<return>" match.
# For unknown reason -notransfer -re "<return>" { exp_continue } does not
# prevent it.

Tested on Fedora 20 x86_64 and Fedora Rawhide x86_64 that -notransfer does not
work there:
	expect-5.45-10.fc20.x86_64
	expect-5.45-16.fc21.x86_64

Sure if someone gets -notransfer working this patch could be dropped.


Jan
gdb/testsuite/
2014-07-22  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* gdb.base/double-prompt-target-event-error.exp: Use
	gdb_test_pagination.
	* gdb.base/paginate-after-ctrl-c-running.exp: Likewise.
	* gdb.base/paginate-bg-execution.exp: Likewise.
	* gdb.base/paginate-execution-startup.exp: Likewise.
	* gdb.base/paginate-inferior-exit.exp: Likewise.
	* lib/gdb.exp (pagination_prompt): Remove.
	(gdb_test_pagination): New.
diff mbox

Patch

diff --git a/gdb/testsuite/gdb.base/double-prompt-target-event-error.exp b/gdb/testsuite/gdb.base/double-prompt-target-event-error.exp
index 5571cdf..803e256 100644
--- a/gdb/testsuite/gdb.base/double-prompt-target-event-error.exp
+++ b/gdb/testsuite/gdb.base/double-prompt-target-event-error.exp
@@ -28,7 +28,7 @@  if {[prepare_for_testing "failed to prepare" $testfile $srcfile debug] == -1} {
 
 proc cancel_pagination_in_target_event { command } {
     global binfile srcfile
-    global gdb_prompt pagination_prompt
+    global gdb_prompt
 
     set testline [gdb_get_line_number "after sleep"]
 
@@ -60,25 +60,23 @@  proc cancel_pagination_in_target_event { command } {
 
 	# Wait for pagination prompt after the "Continuing" line,
 	# indicating the program was running and then stopped.
+	global saw_continuing
 	set saw_continuing 0
 	set test "continue to pagination"
-	gdb_test_multiple "$command" $test {
-	    -re "$pagination_prompt$" {
-		if {$saw_continuing} {
-		    pass $test
-		} else {
-		    send_gdb "\n"
-		    exp_continue
-		}
+	gdb_test_pagination $command $test {
+	    global saw_continuing
+	    if {$saw_continuing} {
+		pass $test
+	    } else {
+		send_gdb "\n"
+		exp_continue
 	    }
+	} {
 	    -re "Continuing" {
+		global saw_continuing
 		set saw_continuing 1
 		exp_continue
 	    }
-	    -notransfer -re "<return>" {
-		# Otherwise gdb_test_multiple considers this an error.
-		exp_continue
-	    }
 	}
 
 	# We're now stopped in a pagination query while handling a
@@ -88,15 +86,20 @@  proc cancel_pagination_in_target_event { command } {
 	send_gdb "\003p 1\n"
 
 	set test "no double prompt"
-	gdb_test_multiple "" $test {
-	    -re "$gdb_prompt.*$gdb_prompt.*$gdb_prompt $" {
-		fail $test
-	    }
-	    -re "$gdb_prompt .* = 1\r\n$gdb_prompt $" {
+	global saw_prompt
+	set saw_prompt 0
+	gdb_test_pagination "" $test {
+	    exp_continue
+	} {
+	    -re " = 1\r\n$gdb_prompt $" {
 		pass $test
 	    }
-	    -notransfer -re "<return>" {
-		# Otherwise gdb_test_multiple considers this an error.
+	    -re "\r\n$gdb_prompt " {
+		global saw_prompt
+		if { $saw_prompt != 0 } {
+		    fail $test
+		}
+		set saw_prompt 1
 		exp_continue
 	    }
 	}
diff --git a/gdb/testsuite/gdb.base/paginate-after-ctrl-c-running.exp b/gdb/testsuite/gdb.base/paginate-after-ctrl-c-running.exp
index 0ed8c92..3323fe7 100644
--- a/gdb/testsuite/gdb.base/paginate-after-ctrl-c-running.exp
+++ b/gdb/testsuite/gdb.base/paginate-after-ctrl-c-running.exp
@@ -24,7 +24,6 @@  if {[build_executable "failed to prepare" $testfile $srcfile debug] == -1} {
 
 proc test_ctrlc_while_target_running_paginates {} {
     global binfile srcfile
-    global gdb_prompt pagination_prompt
 
     set testline [gdb_get_line_number "after sleep"]
 
@@ -61,19 +60,13 @@  proc test_ctrlc_while_target_running_paginates {} {
 	# the user can respond to the pagination query.
 	set test "got prompt"
 	set saw_pagination_prompt 0
-	gdb_test_multiple "" $test {
-	    -re "$pagination_prompt$" {
-		set saw_pagination_prompt 1
-		send_gdb "\n"
-		exp_continue
-	    }
+	gdb_test_pagination "" $test {
+	    send_gdb "\n"
+	    exp_continue
+	} {
 	    -re "$gdb_prompt $" {
 		gdb_assert $saw_pagination_prompt $test
 	    }
-	    -notransfer -re "<return>" {
-		# Otherwise gdb_test_multiple considers this an error.
-		exp_continue
-	    }
 	}
 
 	# Confirm GDB can still process input.
diff --git a/gdb/testsuite/gdb.base/paginate-bg-execution.exp b/gdb/testsuite/gdb.base/paginate-bg-execution.exp
index dcff8ad..3ba46a3 100644
--- a/gdb/testsuite/gdb.base/paginate-bg-execution.exp
+++ b/gdb/testsuite/gdb.base/paginate-bg-execution.exp
@@ -27,7 +27,6 @@  if {[build_executable "failed to prepare" $testfile $srcfile debug] == -1} {
 
 proc test_bg_execution_pagination_return {} {
     global binfile
-    global pagination_prompt
 
     with_test_prefix "paginate" {
 	clean_restart $binfile
@@ -43,21 +42,12 @@  proc test_bg_execution_pagination_return {} {
 
 	gdb_test "continue&" "Continuing\."
 
-	set test "pagination handled, breakpoint hit"
-	set saw_pagination_prompt 0
-	gdb_test_multiple "" $test {
-	    -re "$pagination_prompt$" {
-		set saw_pagination_prompt 1
-		send_gdb "\n"
-		exp_continue
-	    }
-	    -notransfer -re "<return>" {
-		# Otherwise gdb_test_multiple considers this an
-		# error.
-		exp_continue
-	    }
+	gdb_test_pagination "" "pagination handled, breakpoint hit" {
+	    send_gdb "\n"
+	    exp_continue
+	} {
 	    -re "after sleep\[^\r\n\]+\r\n$" {
-		gdb_assert $saw_pagination_prompt $test
+		gdb_assert { $saw_pagination_prompt == 3 } $test
 	    }
 	}
 
@@ -75,7 +65,7 @@  proc test_bg_execution_pagination_return {} {
 
 proc test_bg_execution_pagination_cancel { how } {
     global binfile
-    global gdb_prompt pagination_prompt
+    global gdb_prompt
 
     with_test_prefix "cancel with $how" {
 	clean_restart $binfile
@@ -92,14 +82,8 @@  proc test_bg_execution_pagination_cancel { how } {
 	gdb_test "continue&" "Continuing\."
 
 	set test "continue& paginates"
-	gdb_test_multiple "" $test {
-	    -re "$pagination_prompt$" {
-		pass $test
-	    }
-	    -notransfer -re "<return>" {
-		# Otherwise gdb_test_multiple considers this an error.
-		exp_continue
-	    }
+	gdb_test_pagination "" $test {
+	    pass $test
 	}
 
 	set test "cancel pagination"
diff --git a/gdb/testsuite/gdb.base/paginate-execution-startup.exp b/gdb/testsuite/gdb.base/paginate-execution-startup.exp
index dc713ec..4dc2376 100644
--- a/gdb/testsuite/gdb.base/paginate-execution-startup.exp
+++ b/gdb/testsuite/gdb.base/paginate-execution-startup.exp
@@ -76,7 +76,6 @@  proc probe_can_run_cmdline  {} {
 proc test_fg_execution_pagination_return {} {
     global file_arg
     global saved_gdbflags GDBFLAGS
-    global gdb_prompt pagination_prompt
 
     set GDBFLAGS $saved_gdbflags
     append GDBFLAGS " -ex \"set height 2\""
@@ -92,10 +91,9 @@  proc test_fg_execution_pagination_return {} {
 	    fail $test
 	    return $res
 	}
-	gdb_test_multiple "" $test {
-	    -re "$pagination_prompt$" {
-		pass $test
-	    }
+	gdb_test_pagination "" $test {
+	    pass $test
+	} {
 	    -re "$gdb_prompt $" {
 		fail $test
 	    }
@@ -103,20 +101,13 @@  proc test_fg_execution_pagination_return {} {
 
 	send_gdb "\n"
 
-	set saw_pagination_prompt 0
 	set test "send \\n to GDB"
-	gdb_test_multiple "" $test {
-	    -re "$pagination_prompt$" {
-		set saw_pagination_prompt 1
-		send_gdb "\n"
-		exp_continue
-	    }
-	    -notransfer -re "<return>" {
-		# Otherwise gdb_test_multiple considers this an error.
-		exp_continue
-	    }
+	gdb_test_pagination "" $test {
+	    send_gdb "\n"
+	    exp_continue
+	} {
 	    -re "$gdb_prompt $" {
-		gdb_assert $saw_pagination_prompt $test
+		gdb_assert { $saw_pagination_prompt == 3 } $test
 	    }
 	}
 
@@ -133,7 +124,7 @@  proc test_fg_execution_pagination_return {} {
 proc test_fg_execution_pagination_cancel { how } {
     global file_arg
     global saved_gdbflags GDBFLAGS
-    global gdb_prompt pagination_prompt
+    global gdb_prompt
 
     set GDBFLAGS $saved_gdbflags
 
@@ -150,14 +141,8 @@  proc test_fg_execution_pagination_cancel { how } {
 	    fail $test
 	    return $res
 	}
-	gdb_test_multiple "" $test {
-	    -re "$pagination_prompt$" {
-		pass $test
-	    }
-	    -notransfer -re "<return>" {
-		# Otherwise gdb_test_multiple considers this an error.
-		exp_continue
-	    }
+	gdb_test_pagination "" $test {
+	    pass $test
 	}
 
 	set test "cancel pagination"
diff --git a/gdb/testsuite/gdb.base/paginate-inferior-exit.exp b/gdb/testsuite/gdb.base/paginate-inferior-exit.exp
index 0e37be9..d43a245 100644
--- a/gdb/testsuite/gdb.base/paginate-inferior-exit.exp
+++ b/gdb/testsuite/gdb.base/paginate-inferior-exit.exp
@@ -26,7 +26,7 @@  if {[build_executable "failed to prepare" $testfile $srcfile debug] == -1} {
 #
 proc test_paginate_inferior_exited {} {
     global binfile
-    global gdb_prompt pagination_prompt
+    global gdb_prompt
     global inferior_exited_re
 
     with_test_prefix "paginate" {
@@ -45,23 +45,18 @@  proc test_paginate_inferior_exited {} {
 	# Wait for the "Starting program" line, indicating the program
 	# is running.
 	set saw_starting 0
-	gdb_test_multiple "continue" $test {
-	    -re "$pagination_prompt" {
-		if {$saw_starting} {
-		    pass $test
-		} else {
-		    send_gdb "\n"
-		    exp_continue
-		}
+	gdb_test_pagination "continue" $test {
+	    if {$saw_starting} {
+		pass $test
+	    } else {
+		send_gdb "\n"
+		exp_continue
 	    }
+	} {
 	    -re "Continuing" {
 		set saw_starting 1
 		exp_continue
 	    }
-	    -notransfer -re "<return>" {
-		# Otherwise gdb_test_multiple considers this an error.
-		exp_continue
-	    }
 	}
 
 	# We're now stopped in a pagination output while handling a
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index 7a00efb..d953a50 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -70,9 +70,6 @@  if ![info exists gdb_prompt] then {
     set gdb_prompt "\[(\]gdb\[)\]"
 }
 
-# A regexp that matches the pagination prompt.
-set pagination_prompt "---Type <return> to continue, or q <return> to quit---"
-
 # The variable fullname_syntax_POSIX is a regexp which matches a POSIX 
 # absolute path ie. /foo/ 
 set fullname_syntax_POSIX {/[^\n]*/}
@@ -4846,5 +4843,46 @@  proc capture_command_output { command prefix } {
     return $output_string
 }
 
+# Prevent gdb_test_multiple considering an error -re "<return>" match.
+# For unknown reason -notransfer -re "<return>" { exp_continue } does not
+# prevent it.
+
+proc gdb_test_pagination { command test { code_prompt3 {} } { code_append {} } } {
+    global pagination_prompt1 pagination_prompt2 pagination_prompt3
+    global gdb_prompt
+
+    # A regexp that matches the pagination prompt.
+    set pagination_prompt1 "---Type <return"
+    set pagination_prompt2 "> to continue, or q <return"
+    set pagination_prompt3 "> to quit---"
+
+    append code_append {
+	-re "${pagination_prompt1}" {
+	    if { $saw_pagination_prompt != 0 && $saw_pagination_prompt != 3 } {
+		fail "$test (1)"
+	    }
+	    set saw_pagination_prompt 1
+	    exp_continue
+	}
+	-re "${pagination_prompt2}" {
+	    if { $saw_pagination_prompt != 1 } {
+		fail "$test (2)"
+	    }
+	    set saw_pagination_prompt 2
+	    exp_continue
+	}
+	-re "${pagination_prompt3}$" {
+	    if { $saw_pagination_prompt != 2 } {
+		fail "$test (3)"
+	    }
+	    set saw_pagination_prompt 3
+	    eval $code_prompt3
+	}
+    }
+
+    set saw_pagination_prompt 0
+    gdb_test_multiple $command $test $code_append
+}
+
 # Always load compatibility stuff.
 load_lib future.exp