[v2,03/11] Adjust gdb.base/exitsignal.exp for MinGW, separate program names

Message ID 20260525191829.984105-4-pedro@palves.net
State New
Headers
Series Fix a few Cygwin/MinGW problems |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gdb_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_gdb_check--master-arm success Test passed
linaro-tcwg-bot/tcwg_gdb_check--master-aarch64 success Test passed

Commit Message

Pedro Alves May 25, 2026, 7:18 p.m. UTC
  Currently, gdb.base/exitsignal.exp on MinGW skips half the tests, like
so:

 # of expected passes            13
 # of untested testcases         1

... because the testcase actually compiles two programs, but the
second program is compiled using the same executable name as the
first, at a time when gdb still has the first executable open,
resulting in:

 .../x86_64-w64-mingw32/bin/ld.exe: cannot open output file C:/.../gdb.base/exitsignal/exitsignal.exe: Permission denied

The use of standard_testfile in the middle of a testcase is a bit
surprising.  Fix this by moving the second compilation to the top, and
give each executable its own name.

Move the bulk of test code to two procedures, one for testing exiting
with signal, another for testing normal exit.

With this, gdb.base/exitsignal.exp passes cleanly on
x86_64-w64-mingw32.

Change-Id: I9a1af298b0e4f62f38b5c4b14787d7e40a2b5e2c
commit-id: e496754c
---
 gdb/testsuite/gdb.base/exitsignal.exp | 201 ++++++++++++++------------
 1 file changed, 112 insertions(+), 89 deletions(-)
  

Comments

Thiago Jung Bauermann May 27, 2026, 9:59 p.m. UTC | #1
I have just one nit, with two instances in this patch and another
instance in another patch.

Pedro Alves <pedro@palves.net> writes:

> diff --git a/gdb/testsuite/gdb.base/exitsignal.exp b/gdb/testsuite/gdb.base/exitsignal.exp
> index 341197cf0c8..4f4c53e37cb 100644
> --- a/gdb/testsuite/gdb.base/exitsignal.exp
> +++ b/gdb/testsuite/gdb.base/exitsignal.exp
> @@ -23,103 +23,126 @@
>  
>  require {!target_info exists gdb,nosignals}
>  
> -standard_testfile segv.c
> +set testfile "exitsignal"
>  
> -if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } {
> -    return
> -}
> +set exec1 "segv"
> +set srcfile1 ${exec1}.c
> +set binfile1 [standard_output_file ${exec1}]
>  
> -# Run to main.  But, before, change cwd to get the core into the
> -# output directory.
> -set_inferior_cwd_to_output_dir
> +set exec2 "normal"
> +set srcfile2 ${exec2}.c
> +set binfile2 [standard_output_file ${exec2}]
>  
> -if { ![runto_main] } {
> -    return
> +if { [build_executable "failed to build $exec1" ${exec1} "${srcfile1}" \
> +	  {debug}] == -1 } {
> +    return -1

The current style for testcases is to not return any value from
top-level.

>  }
>  
> -# Get the inferior's PID for later.
> -set pid [get_inferior_pid]
> -
> -# Print $_exitsignal.  It should be void now, because nothing
> -# happened.
> -gdb_test "print \$_exitsignal" " = void" \
> -    "\$_exitsignal is void before running"
> -
> -# Just to guarantee, making sure that $_exitcode is also void.
> -gdb_test "print \$_exitcode" " = void" \
> -    "\$_exitcode is void before running"
> -
> -# Trigger SIGSEGV.
> -gdb_test "continue" "(Thread .*|Program) received signal SIGSEGV.*" \
> -    "trigger SIGSEGV"
> -
> -if {[istarget "*-*-mingw*"]} {
> -    # We're debugging a pure Win32 program with no SEH handler.  The
> -    # previous continue caught the first-chance exception.  Now we
> -    # catch the second-chance.
> -    gdb_test "continue" "Thread .* received signal SIGSEGV.*" \
> -	"trigger SIGSEGV, second-chance"
> -} elseif {[istarget "*-*-cygwin*"]} {
> -    # Cygwin calls DebugBreak before it lets the process exit.
> -    gdb_test "continue" "Thread .* received signal SIGTRAP.*" \
> -	"trigger try_to_debug SIGTRAP"
> +if { [build_executable "failed to build $exec2" ${exec2} "${srcfile2}" \
> +	  {debug}] == -1} {
> +    return -1

The current style for testcases is to not return any value from
top-level.
  
Pedro Alves June 12, 2026, 2 p.m. UTC | #2
On 2026-05-27 22:59, Thiago Jung Bauermann wrote:
> I have just one nit, with two instances in this patch and another
> instance in another patch.
> 

Thank you Thiago.  I fixed those, and merged the series.

(I also looked for any other hit, there was none.)
  

Patch

diff --git a/gdb/testsuite/gdb.base/exitsignal.exp b/gdb/testsuite/gdb.base/exitsignal.exp
index 341197cf0c8..4f4c53e37cb 100644
--- a/gdb/testsuite/gdb.base/exitsignal.exp
+++ b/gdb/testsuite/gdb.base/exitsignal.exp
@@ -23,103 +23,126 @@ 
 
 require {!target_info exists gdb,nosignals}
 
-standard_testfile segv.c
+set testfile "exitsignal"
 
-if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } {
-    return
-}
+set exec1 "segv"
+set srcfile1 ${exec1}.c
+set binfile1 [standard_output_file ${exec1}]
 
-# Run to main.  But, before, change cwd to get the core into the
-# output directory.
-set_inferior_cwd_to_output_dir
+set exec2 "normal"
+set srcfile2 ${exec2}.c
+set binfile2 [standard_output_file ${exec2}]
 
-if { ![runto_main] } {
-    return
+if { [build_executable "failed to build $exec1" ${exec1} "${srcfile1}" \
+	  {debug}] == -1 } {
+    return -1
 }
 
-# Get the inferior's PID for later.
-set pid [get_inferior_pid]
-
-# Print $_exitsignal.  It should be void now, because nothing
-# happened.
-gdb_test "print \$_exitsignal" " = void" \
-    "\$_exitsignal is void before running"
-
-# Just to guarantee, making sure that $_exitcode is also void.
-gdb_test "print \$_exitcode" " = void" \
-    "\$_exitcode is void before running"
-
-# Trigger SIGSEGV.
-gdb_test "continue" "(Thread .*|Program) received signal SIGSEGV.*" \
-    "trigger SIGSEGV"
-
-if {[istarget "*-*-mingw*"]} {
-    # We're debugging a pure Win32 program with no SEH handler.  The
-    # previous continue caught the first-chance exception.  Now we
-    # catch the second-chance.
-    gdb_test "continue" "Thread .* received signal SIGSEGV.*" \
-	"trigger SIGSEGV, second-chance"
-} elseif {[istarget "*-*-cygwin*"]} {
-    # Cygwin calls DebugBreak before it lets the process exit.
-    gdb_test "continue" "Thread .* received signal SIGTRAP.*" \
-	"trigger try_to_debug SIGTRAP"
+if { [build_executable "failed to build $exec2" ${exec2} "${srcfile2}" \
+	  {debug}] == -1} {
+    return -1
 }
 
-# Continue until the end.
-gdb_test "continue" "Program terminated with signal SIGSEGV.*" \
-    "program terminated with SIGSEGV"
-
-# We don't need the core file, remove it.
-remove_core $pid
-
-# Now, print $_exitsignal again.  It should be 11 (SIGSEGV).
-gdb_test "print \$_exitsignal" " = 11" \
-    "\$_exitsignal is 11 (SIGSEGV) after SIGSEGV."
-
-# And $_exitcode should still be void, since the inferior died because
-# of a signal, and did not return.
-gdb_test "print \$_exitcode" " = void" \
-    "\$_exitcode is still void after SIGSEGV"
-
-# Re-run to main, i.e., restart the executable.
-rerun_to_main
-
-# Print the $_exitsignal again.  Even in this normal scenario, it
-# should still contain the signal triggered in the other run.
-gdb_test "print \$_exitsignal" " = 11" \
-    "\$_exitsignal is 11 (SIGSEGV) after restarting the inferior"
-
-# And, again, print $_exitcode.
-gdb_test "print \$_exitcode" " = void" \
-    "\$_exitcode is still void after restarting the inferior"
-
-# Now we test the behavior of $_exit{code,signal} during a normal
-# inferior execution.
-standard_testfile normal.c
-
-if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } {
-    return
+proc test_signal {} {
+    clean_restart $::exec1
+
+    # Run to main.  But, before, change cwd to get the core into the
+    # output directory.
+    set_inferior_cwd_to_output_dir
+
+    if { ![runto_main] } {
+	return
+    }
+
+    # Get the inferior's PID for later.
+    set pid [get_inferior_pid]
+
+    # Print $_exitsignal.  It should be void now, because nothing
+    # happened.
+    gdb_test "print \$_exitsignal" " = void" \
+	"\$_exitsignal is void before running"
+
+    # Just to guarantee, making sure that $_exitcode is also void.
+    gdb_test "print \$_exitcode" " = void" \
+	"\$_exitcode is void before running"
+
+    # Trigger SIGSEGV.
+    gdb_test "continue" "(Thread .*|Program) received signal SIGSEGV.*" \
+	"trigger SIGSEGV"
+
+    if {[istarget "*-*-mingw*"]} {
+	# We're debugging a pure Win32 program with no SEH handler.  The
+	# previous continue caught the first-chance exception.  Now we
+	# catch the second-chance one.
+	gdb_test "continue" "Thread .* received signal SIGSEGV.*" \
+	    "trigger SIGSEGV, second-chance"
+    } elseif {[istarget "*-*-cygwin*"]} {
+	# Cygwin calls DebugBreak before it lets the process exit.
+	gdb_test "continue" "Thread .* received signal SIGTRAP.*" \
+	    "trigger try_to_debug SIGTRAP"
+    }
+
+    # Continue until the end.
+    gdb_test "continue" "Program terminated with signal SIGSEGV.*" \
+	"program terminated with SIGSEGV"
+
+    # We don't need the core file, remove it.
+    remove_core $pid
+
+    # Now, print $_exitsignal again.  It should be 11 (SIGSEGV).
+    gdb_test "print \$_exitsignal" " = 11" \
+	"\$_exitsignal is 11 (SIGSEGV) after SIGSEGV."
+
+    # And $_exitcode should still be void, since the inferior died
+    # because of a signal, and did not return.
+    gdb_test "print \$_exitcode" " = void" \
+	"\$_exitcode is still void after SIGSEGV"
+
+    # Re-run to main, i.e., restart the executable.
+    rerun_to_main
+
+    # Print the $_exitsignal again.  Even in this normal scenario, it
+    # should still contain the signal triggered in the other run.
+    gdb_test "print \$_exitsignal" " = 11" \
+	"\$_exitsignal is 11 (SIGSEGV) after restarting the inferior"
+
+    # And, again, print $_exitcode.
+    gdb_test "print \$_exitcode" " = void" \
+	"\$_exitcode is still void after restarting the inferior"
 }
 
-# Checking $_exitsignal and $_exitcode, both should be void before the
-# inferior is executed.
-gdb_test "print \$_exitsignal" " = void" \
-    "\$_exitsignal is void before normal inferior is executed"
-gdb_test "print \$_exitcode" " = void" \
-    "\$_exitcode is void before normal inferior is executed"
-
-# Run the inferior until the end.
-if { ![runto_main] } {
-    return
+# Test the behavior of $_exit{code,signal} during a normal inferior
+# execution.
+proc test_normal {} {
+    clean_restart $::exec2
+
+    # Check $_exitsignal and $_exitcode, both should be void before
+    # the inferior is executed.
+    gdb_test "print \$_exitsignal" " = void" \
+	"\$_exitsignal is void before normal inferior is executed"
+    gdb_test "print \$_exitcode" " = void" \
+	"\$_exitcode is void before normal inferior is executed"
+
+    # Run the inferior until the end.
+    if { ![runto_main] } {
+	return
+    }
+
+    gdb_continue_to_end
+
+    # Check $_exitcode.  It should be 0.
+    gdb_test "print \$_exitcode" " = 0" \
+	"\$_exitcode is zero after normal inferior is executed"
+
+    # Check $_exitsignal.  It should still be void, since the inferior
+    # has not received any signal.
+    gdb_test "print \$_exitsignal" " = void" \
+	"\$_exitsignal is still void after normal inferior is executed"
 }
 
-gdb_continue_to_end
-
-# Checking $_exitcode.  It should be 0.
-gdb_test "print \$_exitcode" " = 0" \
-    "\$_exitcode is zero after normal inferior is executed"
-
-# Checking $_exitsignal.  It should still be void, since the inferior
-# has not received any signal.
-gdb_test "print \$_exitsignal" " = void" \
-    "\$_exitsignal is still void after normal inferior is executed"
+with_test_prefix "signal" {
+    test_signal
+}
+with_test_prefix "normal" {
+    test_normal
+}