[v2,2/5] gdb/testsuite: refactor gdb.threads/detach-step-over.exp

Message ID 20221121171213.1414366-3-simon.marchi@polymtl.ca
State Committed
Commit acc175a6b3bf6dfefde88fac78e34ac0625343c6
Headers
Series Fix some commit_resumed_state assertion failures (PR 28275) |

Commit Message

Simon Marchi Nov. 21, 2022, 5:12 p.m. UTC
  From: Andrew Burgess <aburgess@redhat.com>

Factor out some bits of gdb.threads/detach-step-over.exp to procs in
preparation to adding some new variations of the test.  Rename the
existing "test" proc and make it use proc_with_prefix.

Co-Authored-By: Simon Marchi <simon.marchi@efficios.com>
Change-Id: Ib4412545c81c8556029e0f7bfa9dd48d7a9f3189
---
 .../gdb.threads/detach-step-over.exp          | 238 ++++++++++--------
 1 file changed, 138 insertions(+), 100 deletions(-)
  

Comments

Andrew Burgess Nov. 28, 2022, 12:05 p.m. UTC | #1
Simon Marchi <simon.marchi@polymtl.ca> writes:

> From: Andrew Burgess <aburgess@redhat.com>
>
> Factor out some bits of gdb.threads/detach-step-over.exp to procs in
> preparation to adding some new variations of the test.  Rename the
> existing "test" proc and make it use proc_with_prefix.
>
> Co-Authored-By: Simon Marchi <simon.marchi@efficios.com>
> Change-Id: Ib4412545c81c8556029e0f7bfa9dd48d7a9f3189

LGTM.  I guess if we're both happy then this is OK to go in without
anyone other review.

Thanks,
Andrew

> ---
>  .../gdb.threads/detach-step-over.exp          | 238 ++++++++++--------
>  1 file changed, 138 insertions(+), 100 deletions(-)
>
> diff --git a/gdb/testsuite/gdb.threads/detach-step-over.exp b/gdb/testsuite/gdb.threads/detach-step-over.exp
> index 917be2ef3782..ad9b08f549ea 100644
> --- a/gdb/testsuite/gdb.threads/detach-step-over.exp
> +++ b/gdb/testsuite/gdb.threads/detach-step-over.exp
> @@ -56,11 +56,11 @@ standard_testfile
>  
>  set bp_lineno [gdb_get_line_number "Set breakpoint here"]
>  
> -# The test proper.  See description above.
> -proc test {condition_eval target_non_stop non_stop displaced} {
> -    # Number of threads started by the program.
> -    set n_threads 10
> +# Number of threads started by the program.
> +set n_threads 10
>  
> +# Start GDB, configuring various settings according to the arguments.
> +proc start_gdb_for_test {condition_eval target_non_stop non_stop displaced} {
>      save_vars { ::GDBFLAGS } {
>  	append ::GDBFLAGS " -ex \"maint set target-non-stop $target_non_stop\""
>  	append ::GDBFLAGS " -ex \"set non-stop $non_stop\""
> @@ -69,10 +69,137 @@ proc test {condition_eval target_non_stop non_stop displaced} {
>  	clean_restart $::binfile
>      }
>  
> +    gdb_test_no_output "set breakpoint condition-evaluation $condition_eval"
> +}
> +
> +# Use the 'attach' command to attach to process with pid TESTPID.  Return true
> +# if we believe GDB has attached and we are back at the GDB prompt, otherwise,
> +# return false.
> +proc attach_to {testpid} {
> +    with_timeout_factor 2 {
> +	set attached 0
> +	set saw_attaching 0
> +	gdb_test_multiple "attach $testpid" "attach" {
> +	    -re "Attaching to program.*process $testpid\r\n" {
> +		set saw_attaching 1
> +		exp_continue
> +	    }
> +	    -re "new threads in iteration" {
> +		# Seen when "set debug libthread_db" is on.
> +		exp_continue
> +	    }
> +	    -re "Reading symbols from|Expanding full symbols from" {
> +		# Prevent -readnow timeout.
> +		exp_continue
> +	    }
> +	    -re "is a zombie - the process has already terminated.*$::gdb_prompt " {
> +		fail $gdb_test_name
> +	    }
> +	    -re "Unable to attach: .*$::gdb_prompt " {
> +		fail $gdb_test_name
> +	    }
> +	    -re "\r\n$::gdb_prompt " {
> +		if { $saw_attaching } {
> +		    set attached 1
> +		    pass $gdb_test_name
> +		} else {
> +		    fail $gdb_test_name
> +		}
> +	    }
> +	}
> +    }
> +
> +    return $attached
> +}
> +
> +# After attaching to a multi-threaded inferior in non-stop mode, we expect to
> +# see a stop message from each thread.  This proc waits for all of these stop
> +# messages.  TID_RE is a regexp used to match the thread-id of the stopped
> +# thread.
> +#
> +# Return true if we saw a stop from each of the expected threads (based on the
> +# global N_THREADS value), otherwise, return false.
> +proc check_stops_after_non_stop_attach {tid_re} {
> +    set any "\[^\r\n\]*"
> +
> +    # In non-stop, we will see one stop per thread after the prompt.
> +    set stops 0
> +    set test "seen all stops"
> +    for {set thread 1} { $thread <= $::n_threads } { incr thread } {
> +	if {[gdb_test_multiple "" $test {
> +	    -re "Thread ${tid_re} ${any} stopped" {
> +		incr stops
> +	    }
> +	}] != 0} {
> +	    break
> +	}
> +    }
> +
> +    # If we haven't seen all stops, then the
> +    # gdb_test_multiple in the loop above will have
> +    # already issued a FAIL.
> +    if {$stops != $::n_threads} {
> +	return false
> +    }
> +    pass $test
> +    return true
> +}
> +
> +# Prepare for a single test iteration.  TESTPID is the pid of the process GDB
> +# will be attached too.  NON_STOP indicates if GDB is configured in non-stop
> +# mode or not.  ATTEMPT is the current attempt number, and ATTEMPTS is the
> +# maximum number of attempts we plan to run.  TID_RE is a string used to match
> +# against a thread-id in GDB's stop messages.
> +#
> +# Return true if everything is prepared correctly, otherwise return false.
> +proc prepare_test_iter {testpid non_stop attempt attempts tid_re} {
> +    if {![attach_to $testpid]} {
> +	return false
> +    }
> +
> +    if {$non_stop} {
> +	if {![check_stops_after_non_stop_attach $tid_re]} {
> +	    return false
> +	}
> +    }
> +
> +    gdb_test "break ${::srcfile}:${::bp_lineno} if 0" "Breakpoint.*" \
> +	"break LOC if 0"
> +
> +    if {$attempt < $attempts} {
> +	# Kick the time out timer for another round.
> +	gdb_test "print again = 1" " = 1" "reset timer in the inferior"
> +	# Show the time we had left in the logs, in case
> +	# something goes wrong.
> +	gdb_test "print seconds_left" " = .*"
> +    }
> +
> +    if {$non_stop} {
> +	set cont_cmd "continue -a &"
> +    } else {
> +	set cont_cmd "continue &"
> +    }
> +
> +    set cont_cmd_re [string_to_regexp $cont_cmd]
> +    gdb_test_multiple $cont_cmd "" {
> +	-re "^$cont_cmd_re\r\nContinuing\.\r\n$::gdb_prompt " {
> +	    pass $gdb_test_name
> +	}
> +    }
> +
> +    # Wait a bit, to give time for the threads to hit the
> +    # breakpoint.
> +    sleep 1
> +
> +    return true
> +}
> +
> +# The test proper.  See the description at the top of the file.
> +proc_with_prefix test_detach_command {condition_eval target_non_stop non_stop displaced} {
>      set test_spawn_id [spawn_wait_for_attach $::binfile]
>      set testpid [spawn_id_get_pid $test_spawn_id]
>  
> -    set any "\[^\r\n\]*"
> +    start_gdb_for_test $condition_eval $target_non_stop $non_stop $displaced
>  
>      gdb_test "add-inferior" "Added inferior 2.*"
>      gdb_test "inferior 2" "Switching to .*"
> @@ -84,8 +211,6 @@ proc test {condition_eval target_non_stop non_stop displaced} {
>  	return
>      }
>  
> -    gdb_test_no_output "set breakpoint condition-evaluation $condition_eval"
> -
>      # Get the PID of the test process.
>      set pid_inf2 ""
>      gdb_test_multiple "p mypid" "get pid of inferior 2" {
> @@ -100,101 +225,12 @@ proc test {condition_eval target_non_stop non_stop displaced} {
>  	with_test_prefix "iter $attempt" {
>  	    gdb_test "inferior 1" "Switching to .*"
>  
> -	    with_timeout_factor 2 {
> -		set attached 0
> -		set saw_attaching 0
> -		set eperm 0
> -		set test "attach"
> -		gdb_test_multiple "attach $testpid" $test {
> -		    -re "Attaching to program.*process $testpid\r\n" {
> -			set saw_attaching 1
> -			exp_continue
> -		    }
> -		    -re "new threads in iteration" {
> -			# Seen when "set debug libthread_db" is on.
> -			exp_continue
> -		    }
> -		    -re "Reading symbols from|Expanding full symbols from" {
> -			# Prevent -readnow timeout.
> -			exp_continue
> -		    }
> -		    -re "is a zombie - the process has already terminated.*$::gdb_prompt " {
> -			fail $gdb_test_name
> -		    }
> -		    -re "Unable to attach: .*$::gdb_prompt " {
> -			fail $gdb_test_name
> -		    }
> -		    -re "\r\n$::gdb_prompt " {
> -			if { $saw_attaching } {
> -			    set attached 1
> -			    pass $test
> -			} else {
> -			    fail $test
> -			}
> -		    }
> -		}
> -	    }
> -
> -	    if {!$attached} {
> +	    if {![prepare_test_iter $testpid $non_stop \
> +		      $attempt $attempts "$::decimal\.$::decimal"]} {
>  		kill_wait_spawned_process $test_spawn_id
>  		return
>  	    }
>  
> -	    if {$non_stop} {
> -		# In non-stop, we will see one stop per thread after
> -		# the prompt.
> -		set stops 0
> -		set tid_re "$::decimal\.$::decimal"
> -		set test "seen all stops"
> -		for {set thread 1} { $thread <= $n_threads } { incr thread } {
> -		    if {[gdb_test_multiple "" $test {
> -			-re "Thread ${tid_re} ${any} stopped" {
> -			    incr stops
> -			}
> -		    }] != 0} {
> -			break
> -		    }
> -		}
> -
> -		# If we haven't seen all stops, then the
> -		# gdb_test_multiple in the loop above will have
> -		# already issued a FAIL.
> -		if {$stops != $n_threads} {
> -		    kill_wait_spawned_process $test_spawn_id
> -		    return
> -		}
> -		pass $test
> -	    }
> -
> -	    # Set threads stepping over a breakpoint continuously.
> -	    gdb_test "break $::srcfile:$::bp_lineno if 0" "Breakpoint.*" \
> -		"break LOC if 0"
> -
> -	    if {$attempt < $attempts} {
> -		# Kick the time out timer for another round.
> -		gdb_test "print again = 1" " = 1" "reset timer in the inferior"
> -		# Show the time we had left in the logs, in case
> -		# something goes wrong.
> -		gdb_test "print seconds_left" " = .*"
> -	    }
> -
> -	    if {$non_stop} {
> -		set cont_cmd "continue -a &"
> -	    } else {
> -		set cont_cmd "continue &"
> -	    }
> -
> -	    set cont_cmd_re [string_to_regexp $cont_cmd]
> -	    gdb_test_multiple $cont_cmd "" {
> -		-re "^$cont_cmd_re\r\nContinuing\.\r\n$::gdb_prompt " {
> -		    pass $gdb_test_name
> -		}
> -	    }
> -
> -	    # Wait a bit, to give time for the threads to hit the
> -	    # breakpoint.
> -	    sleep 1
> -
>  	    set running_count 0
>  	    set interrupted 0
>  	    gdb_test_multiple "info threads" "all threads running" {
> @@ -219,7 +255,8 @@ proc test {condition_eval target_non_stop non_stop displaced} {
>  		    }
>  		}
>  		-re "$::gdb_prompt $" {
> -		    gdb_assert {$running_count == ($n_threads + 1) * 2} $gdb_test_name
> +		    gdb_assert {$running_count == ($::n_threads + 1) * 2} \
> +			$gdb_test_name
>  		}
>  	    }
>  
> @@ -292,7 +329,8 @@ foreach_with_prefix breakpoint-condition-evaluation {"host" "target"} {
>  	    }
>  
>  	    foreach_with_prefix displaced {"off" "auto"} {
> -		test ${breakpoint-condition-evaluation} ${target-non-stop} ${non-stop} ${displaced}
> +		test_detach_command ${breakpoint-condition-evaluation} \
> +		    ${target-non-stop} ${non-stop} ${displaced}
>  	    }
>  	}
>      }
> -- 
> 2.38.1
  

Patch

diff --git a/gdb/testsuite/gdb.threads/detach-step-over.exp b/gdb/testsuite/gdb.threads/detach-step-over.exp
index 917be2ef3782..ad9b08f549ea 100644
--- a/gdb/testsuite/gdb.threads/detach-step-over.exp
+++ b/gdb/testsuite/gdb.threads/detach-step-over.exp
@@ -56,11 +56,11 @@  standard_testfile
 
 set bp_lineno [gdb_get_line_number "Set breakpoint here"]
 
-# The test proper.  See description above.
-proc test {condition_eval target_non_stop non_stop displaced} {
-    # Number of threads started by the program.
-    set n_threads 10
+# Number of threads started by the program.
+set n_threads 10
 
+# Start GDB, configuring various settings according to the arguments.
+proc start_gdb_for_test {condition_eval target_non_stop non_stop displaced} {
     save_vars { ::GDBFLAGS } {
 	append ::GDBFLAGS " -ex \"maint set target-non-stop $target_non_stop\""
 	append ::GDBFLAGS " -ex \"set non-stop $non_stop\""
@@ -69,10 +69,137 @@  proc test {condition_eval target_non_stop non_stop displaced} {
 	clean_restart $::binfile
     }
 
+    gdb_test_no_output "set breakpoint condition-evaluation $condition_eval"
+}
+
+# Use the 'attach' command to attach to process with pid TESTPID.  Return true
+# if we believe GDB has attached and we are back at the GDB prompt, otherwise,
+# return false.
+proc attach_to {testpid} {
+    with_timeout_factor 2 {
+	set attached 0
+	set saw_attaching 0
+	gdb_test_multiple "attach $testpid" "attach" {
+	    -re "Attaching to program.*process $testpid\r\n" {
+		set saw_attaching 1
+		exp_continue
+	    }
+	    -re "new threads in iteration" {
+		# Seen when "set debug libthread_db" is on.
+		exp_continue
+	    }
+	    -re "Reading symbols from|Expanding full symbols from" {
+		# Prevent -readnow timeout.
+		exp_continue
+	    }
+	    -re "is a zombie - the process has already terminated.*$::gdb_prompt " {
+		fail $gdb_test_name
+	    }
+	    -re "Unable to attach: .*$::gdb_prompt " {
+		fail $gdb_test_name
+	    }
+	    -re "\r\n$::gdb_prompt " {
+		if { $saw_attaching } {
+		    set attached 1
+		    pass $gdb_test_name
+		} else {
+		    fail $gdb_test_name
+		}
+	    }
+	}
+    }
+
+    return $attached
+}
+
+# After attaching to a multi-threaded inferior in non-stop mode, we expect to
+# see a stop message from each thread.  This proc waits for all of these stop
+# messages.  TID_RE is a regexp used to match the thread-id of the stopped
+# thread.
+#
+# Return true if we saw a stop from each of the expected threads (based on the
+# global N_THREADS value), otherwise, return false.
+proc check_stops_after_non_stop_attach {tid_re} {
+    set any "\[^\r\n\]*"
+
+    # In non-stop, we will see one stop per thread after the prompt.
+    set stops 0
+    set test "seen all stops"
+    for {set thread 1} { $thread <= $::n_threads } { incr thread } {
+	if {[gdb_test_multiple "" $test {
+	    -re "Thread ${tid_re} ${any} stopped" {
+		incr stops
+	    }
+	}] != 0} {
+	    break
+	}
+    }
+
+    # If we haven't seen all stops, then the
+    # gdb_test_multiple in the loop above will have
+    # already issued a FAIL.
+    if {$stops != $::n_threads} {
+	return false
+    }
+    pass $test
+    return true
+}
+
+# Prepare for a single test iteration.  TESTPID is the pid of the process GDB
+# will be attached too.  NON_STOP indicates if GDB is configured in non-stop
+# mode or not.  ATTEMPT is the current attempt number, and ATTEMPTS is the
+# maximum number of attempts we plan to run.  TID_RE is a string used to match
+# against a thread-id in GDB's stop messages.
+#
+# Return true if everything is prepared correctly, otherwise return false.
+proc prepare_test_iter {testpid non_stop attempt attempts tid_re} {
+    if {![attach_to $testpid]} {
+	return false
+    }
+
+    if {$non_stop} {
+	if {![check_stops_after_non_stop_attach $tid_re]} {
+	    return false
+	}
+    }
+
+    gdb_test "break ${::srcfile}:${::bp_lineno} if 0" "Breakpoint.*" \
+	"break LOC if 0"
+
+    if {$attempt < $attempts} {
+	# Kick the time out timer for another round.
+	gdb_test "print again = 1" " = 1" "reset timer in the inferior"
+	# Show the time we had left in the logs, in case
+	# something goes wrong.
+	gdb_test "print seconds_left" " = .*"
+    }
+
+    if {$non_stop} {
+	set cont_cmd "continue -a &"
+    } else {
+	set cont_cmd "continue &"
+    }
+
+    set cont_cmd_re [string_to_regexp $cont_cmd]
+    gdb_test_multiple $cont_cmd "" {
+	-re "^$cont_cmd_re\r\nContinuing\.\r\n$::gdb_prompt " {
+	    pass $gdb_test_name
+	}
+    }
+
+    # Wait a bit, to give time for the threads to hit the
+    # breakpoint.
+    sleep 1
+
+    return true
+}
+
+# The test proper.  See the description at the top of the file.
+proc_with_prefix test_detach_command {condition_eval target_non_stop non_stop displaced} {
     set test_spawn_id [spawn_wait_for_attach $::binfile]
     set testpid [spawn_id_get_pid $test_spawn_id]
 
-    set any "\[^\r\n\]*"
+    start_gdb_for_test $condition_eval $target_non_stop $non_stop $displaced
 
     gdb_test "add-inferior" "Added inferior 2.*"
     gdb_test "inferior 2" "Switching to .*"
@@ -84,8 +211,6 @@  proc test {condition_eval target_non_stop non_stop displaced} {
 	return
     }
 
-    gdb_test_no_output "set breakpoint condition-evaluation $condition_eval"
-
     # Get the PID of the test process.
     set pid_inf2 ""
     gdb_test_multiple "p mypid" "get pid of inferior 2" {
@@ -100,101 +225,12 @@  proc test {condition_eval target_non_stop non_stop displaced} {
 	with_test_prefix "iter $attempt" {
 	    gdb_test "inferior 1" "Switching to .*"
 
-	    with_timeout_factor 2 {
-		set attached 0
-		set saw_attaching 0
-		set eperm 0
-		set test "attach"
-		gdb_test_multiple "attach $testpid" $test {
-		    -re "Attaching to program.*process $testpid\r\n" {
-			set saw_attaching 1
-			exp_continue
-		    }
-		    -re "new threads in iteration" {
-			# Seen when "set debug libthread_db" is on.
-			exp_continue
-		    }
-		    -re "Reading symbols from|Expanding full symbols from" {
-			# Prevent -readnow timeout.
-			exp_continue
-		    }
-		    -re "is a zombie - the process has already terminated.*$::gdb_prompt " {
-			fail $gdb_test_name
-		    }
-		    -re "Unable to attach: .*$::gdb_prompt " {
-			fail $gdb_test_name
-		    }
-		    -re "\r\n$::gdb_prompt " {
-			if { $saw_attaching } {
-			    set attached 1
-			    pass $test
-			} else {
-			    fail $test
-			}
-		    }
-		}
-	    }
-
-	    if {!$attached} {
+	    if {![prepare_test_iter $testpid $non_stop \
+		      $attempt $attempts "$::decimal\.$::decimal"]} {
 		kill_wait_spawned_process $test_spawn_id
 		return
 	    }
 
-	    if {$non_stop} {
-		# In non-stop, we will see one stop per thread after
-		# the prompt.
-		set stops 0
-		set tid_re "$::decimal\.$::decimal"
-		set test "seen all stops"
-		for {set thread 1} { $thread <= $n_threads } { incr thread } {
-		    if {[gdb_test_multiple "" $test {
-			-re "Thread ${tid_re} ${any} stopped" {
-			    incr stops
-			}
-		    }] != 0} {
-			break
-		    }
-		}
-
-		# If we haven't seen all stops, then the
-		# gdb_test_multiple in the loop above will have
-		# already issued a FAIL.
-		if {$stops != $n_threads} {
-		    kill_wait_spawned_process $test_spawn_id
-		    return
-		}
-		pass $test
-	    }
-
-	    # Set threads stepping over a breakpoint continuously.
-	    gdb_test "break $::srcfile:$::bp_lineno if 0" "Breakpoint.*" \
-		"break LOC if 0"
-
-	    if {$attempt < $attempts} {
-		# Kick the time out timer for another round.
-		gdb_test "print again = 1" " = 1" "reset timer in the inferior"
-		# Show the time we had left in the logs, in case
-		# something goes wrong.
-		gdb_test "print seconds_left" " = .*"
-	    }
-
-	    if {$non_stop} {
-		set cont_cmd "continue -a &"
-	    } else {
-		set cont_cmd "continue &"
-	    }
-
-	    set cont_cmd_re [string_to_regexp $cont_cmd]
-	    gdb_test_multiple $cont_cmd "" {
-		-re "^$cont_cmd_re\r\nContinuing\.\r\n$::gdb_prompt " {
-		    pass $gdb_test_name
-		}
-	    }
-
-	    # Wait a bit, to give time for the threads to hit the
-	    # breakpoint.
-	    sleep 1
-
 	    set running_count 0
 	    set interrupted 0
 	    gdb_test_multiple "info threads" "all threads running" {
@@ -219,7 +255,8 @@  proc test {condition_eval target_non_stop non_stop displaced} {
 		    }
 		}
 		-re "$::gdb_prompt $" {
-		    gdb_assert {$running_count == ($n_threads + 1) * 2} $gdb_test_name
+		    gdb_assert {$running_count == ($::n_threads + 1) * 2} \
+			$gdb_test_name
 		}
 	    }
 
@@ -292,7 +329,8 @@  foreach_with_prefix breakpoint-condition-evaluation {"host" "target"} {
 	    }
 
 	    foreach_with_prefix displaced {"off" "auto"} {
-		test ${breakpoint-condition-evaluation} ${target-non-stop} ${non-stop} ${displaced}
+		test_detach_command ${breakpoint-condition-evaluation} \
+		    ${target-non-stop} ${non-stop} ${displaced}
 	    }
 	}
     }