[5/5] Adjust gdb.python/py-events.exp for Cygwin/MinGW

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

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_gdb_build--master-arm 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 22, 2026, 12:16 a.m. UTC
  This commit fixes several issues in gdb.python/py-events.exp for
Cygwin and MinGW.  With these fixed, the testcase passes cleanly on
Cygwin.  I haven't tested on MinGW, but at least the test should be
able to compile & run there now.

1) - GDB prints Windows thread IDs in hex:

 (gdb) thread
 [Current thread is 1 (Thread 9528.0xa9c)]

The corrent code assume decimal, so we only (incorrectly) extract the
"0" after the dot.

2) - Thread and process ID number spaces are different.

The current code assumes that the extract thread is is the same number
as the extracted process id, which is not true on Windows.

3) - there is no "info proc" command on Windows

The testcase is using "info proc" to extract the inferior's process
it.  But "info proc" does not exist on all targets, including Windows.
Switch to using "inferior" instead.

4) - The testcase uses fork, and relies on "set detach-on-fork off"

There is fork on Cygwin, but GDB can't follow forks there, so
"detach-on-fork off" has no effect.  And also, there is no fork on
native Windows, which makes the testcase unusable on MinGW currently.

I don't see any reason the testcase needs to use fork or multiple
inferiors:

 - To test the clear_objfiles event, test a more directed "file"
   command instead of testing that following a fork emits it.

 - There's a test that quits gdb while some inferiors are being
   debugged, and it test that GDB emits gdb.ExitedEvent with no
   'exit_code' attribute.  Quitting while an inferior is being
   debugged makes GDB kill the inferior.  So what that is really being
   tested is that killing an inferior emits such an event.  So write
   such an explicit test.

Also tested on x86_64-unknown-linux-gnu.

Change-Id: I21ee8af7b52653c6fdff9b4c1596cdde3cfe751a
commit-id: de2bf164
---
 gdb/testsuite/gdb.python/py-events.c   |  3 --
 gdb/testsuite/gdb.python/py-events.exp | 73 ++++++++++++++------------
 2 files changed, 40 insertions(+), 36 deletions(-)
  

Comments

Eli Zaretskii May 22, 2026, 7:18 a.m. UTC | #1
> From: Pedro Alves <pedro@palves.net>
> Date: Fri, 22 May 2026 01:16:26 +0100
> 
> This commit fixes several issues in gdb.python/py-events.exp for
> Cygwin and MinGW.  With these fixed, the testcase passes cleanly on
> Cygwin.  I haven't tested on MinGW, but at least the test should be
> able to compile & run there now.
> 
> 1) - GDB prints Windows thread IDs in hex:
> 
>  (gdb) thread
>  [Current thread is 1 (Thread 9528.0xa9c)]
> 
> The corrent code assume decimal, so we only (incorrectly) extract the
> "0" after the dot.
> 
> 2) - Thread and process ID number spaces are different.
> 
> The current code assumes that the extract thread is is the same number
                                                   ^^
Typo: should be "ID".

> as the extracted process id, which is not true on Windows.
> 
> 3) - there is no "info proc" command on Windows
> 
> The testcase is using "info proc" to extract the inferior's process
> it.  But "info proc" does not exist on all targets, including Windows.
  ^^
Same here.

Thanks.

(I don't add the reviewed-by signature, because I cannot review the
expect code.)
  

Patch

diff --git a/gdb/testsuite/gdb.python/py-events.c b/gdb/testsuite/gdb.python/py-events.c
index b1910f75ed9..6a0b407042a 100644
--- a/gdb/testsuite/gdb.python/py-events.c
+++ b/gdb/testsuite/gdb.python/py-events.c
@@ -15,12 +15,9 @@ 
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see  <http://www.gnu.org/licenses/>.  */
 
-#include <unistd.h>
-
 extern void do_nothing (void);
 
 int second(){
-  fork() ;
   return 12;
 }
 
diff --git a/gdb/testsuite/gdb.python/py-events.exp b/gdb/testsuite/gdb.python/py-events.exp
index 16a290c31c2..5a40ee4ac97 100644
--- a/gdb/testsuite/gdb.python/py-events.exp
+++ b/gdb/testsuite/gdb.python/py-events.exp
@@ -45,8 +45,6 @@  gdb_breakpoint "main" {temporary}
 
 gdb_test "run" ".*event type: new_objfile.*new objfile name.*" "new objfile notification"
 
-gdb_test_no_output "set detach-on-fork off" ""
-
 gdb_test "test-events" "Event testers registered."
 
 gdb_breakpoint "first"
@@ -76,17 +74,23 @@  delete_breakpoints
 # Test inferior call events
 
 set process_id "invalid"
+set thread_id "invalid"
 gdb_test_multiple "thread" "get current thread" {
     -re -wrap "process ($decimal).*" {
 	set process_id $expect_out(1,string)
+	set thread_id $process_id
 	pass $gdb_test_name
     }
     -re -wrap "Thread $hex \\(LWP ($decimal)\\).*" {
 	set process_id $expect_out(1,string)
+	set thread_id $process_id
 	pass $gdb_test_name
     }
-    -re -wrap "Thread $decimal\.($decimal).*" {
+    -re -wrap "Thread ($decimal)\.($hex|$decimal).*" {
 	set process_id $expect_out(1,string)
+	set thread_id $expect_out(2,string)
+	# Convert from hex to decimal.
+	set thread_id [expr {$thread_id}]
 	pass $gdb_test_name
     }
 }
@@ -99,9 +103,9 @@  gdb_test_multiple "print do_nothing" "get address of do_nothing" {
 }
 
 set expected [list "event type: pre-call"]
-lappend expected "ptid: \\($process_id, $process_id, 0\\)" "address: $addr"
+lappend expected "ptid: \\($process_id, $thread_id, 0\\)" "address: $addr"
 lappend expected "event type: post-call"
-lappend expected "ptid: \\($process_id, $process_id, 0\\)" "address: $addr"
+lappend expected "ptid: \\($process_id, $thread_id, 0\\)" "address: $addr"
 gdb_test_sequence "call do_nothing()" "" $expected
 
 # Test register changed event
@@ -202,7 +206,7 @@  gdb_test_no_output "delete $second_breakpoint"
 #test exited event.
 proc get_process_id {test} {
     global gdb_prompt
-    gdb_test_multiple "info proc" $test {
+    gdb_test_multiple "inferior" $test {
 	-re "process (\\d+).*$gdb_prompt $" {
 	    set process_id $expect_out(1,string)
 	    pass $gdb_test_name
@@ -211,24 +215,13 @@  proc get_process_id {test} {
     return ${process_id}
 }
 
-set process_id [get_process_id "get inferior 1 process id"]
+set process_id [get_process_id "get inferior process id"]
 gdb_test "continue" ".*event type: continue.*
-.*clear_objfiles\[\r\n\]*progspace: .*py-events.*
 .*event type: exit.*
 .*exit code: 12.*
 .*exit inf: 1.*
 .*exit pid: $process_id.*
-dir ok: True.*" "Inferior 1 terminated."
-
-gdb_test "inferior 2" ".*Switching to inferior 2.*"
-set process_id [get_process_id "get inferior 2 process id"]
-gdb_test "continue" ".*event type: continue.*
-.*event type: exit.*
-.*exit code: 12.*
-.*exit inf: 2.*
-.*exit pid: $process_id.*
-dir ok: True.*" "Inferior 2 terminated."
-
+dir ok: True.*" "inferior terminated"
 
 # Test before_prompt event.
 gdb_test_multiline "define new user command" \
@@ -280,29 +273,30 @@  with_test_prefix "inferior continue exit" {
     gdb_test "print \$_foo" "= 2" "check foo after start continue"
 }
 
-# Check that when GDB exits, we see gdb.ExitedEvent objects with no
-# 'exit_code' attribute, and that a gdb.GdbExitingEvent is emitted.
-with_test_prefix "gdb exiting: normal" {
+# Check that when GDB kills an inferior, we see gdb.ExitedEvent
+# objects with no 'exit_code' attribute.
+with_test_prefix "kill inferior" {
+    if {![runto_main]} {
+	return
+    }
     gdb_test "test-exiting-event normal" "GDB exiting event registered\\."
 
+    gdb_test "with confirm off -- kill" \
+	"event type: exit\r\nexit code: not-present\r\nexit inf: $decimal\r\nexit pid: $decimal\r\ndir ok: False\r\n.*" \
+	"exit code not present"
+}
+
+# Check that when GDB exits, we see that a gdb.GdbExitingEvent is
+# emitted.
+with_test_prefix "gdb exiting: normal" {
     set saw_exiting_event 0
-    set saw_inferior_exit 0
-    gdb_test_multiple "quit" "" {
-	-re "Quit anyway\\? \\(y or n\\) $" {
-	    send_gdb "y\n"
-	    exp_continue
-	}
+    gdb_test_multiple "with confirm off -- quit" "quit" {
 	-re "event type: gdb-exiting\r\nexit code: $decimal" {
 	    incr saw_exiting_event
 	    exp_continue
 	}
-	-re "event type: exit\r\nexit code: not-present\r\nexit inf: $decimal\r\nexit pid: $decimal\r\ndir ok: False\r\n" {
-	    incr saw_inferior_exit
-	    exp_continue
-	}
 	eof {
 	    gdb_assert { $saw_exiting_event == 1 }
-	    gdb_assert { $saw_inferior_exit == 2 }
 	    pass $gdb_test_name
 	}
     }
@@ -348,3 +342,16 @@  with_test_prefix "gdb exiting: error" {
 	}
     }
 }
+
+# Test clear_objfiles event.
+
+with_test_prefix "clear_objfiles" {
+    clean_restart ${testfile}
+
+    gdb_test_no_output "source ${pyfile}" "load python file"
+    gdb_test "test-objfile-events" "Object file events registered."
+
+    gdb_test "with confirm off -- file" \
+	"event type: clear_objfiles\r\nprogspace: None\r\n.*" \
+	"file cleared"
+}