]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commit
Fix gdb.threads/multiple-successive-infcall.exp on Windows (depends on schedlock)
authorPedro Alves <pedro@palves.net>
Fri, 3 May 2024 17:24:22 +0000 (18:24 +0100)
committerPedro Alves <pedro@palves.net>
Mon, 9 Jun 2025 17:49:19 +0000 (18:49 +0100)
commit07f0471f447bc48b83e7e8f323e57d7c68a54949
tree67227e669ee61d9984df9184c01570e9ba121352
parenta6b80313a21590ea5568ce7f3883d99d5f10286c
Fix gdb.threads/multiple-successive-infcall.exp on Windows (depends on schedlock)

Running gdb.threads/multiple-successive-infcall.exp on Cygwin results
in a series of cascading timeouts.  There are two problems:

 #1 - Cygwin starts a few threads for its own use.  When you reach
      "main" with "(gdb) start", info threads will already show more
      than one thread.  The testcase spawns four threads with
      pthread_create, and it assumes that they get GDB thread ids 2
      through 5.  That is incorrect for Cygwin.

E.g.:

 (gdb) info threads
   Id   Target Id                                                      Frame
   1    Thread 4104.0x1e60 "multiple-successive-infcall"               0x00007fff3c44dbb4 in ntdll!ZwWaitForMultipleObjects () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
   2    Thread 4104.0x2490                                             0x00007fff3c450ad4 in ntdll!ZwWaitForWorkViaWorkerFactory ()
    from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
   3    Thread 4104.0x2bdc                                             0x00007fff3c450ad4 in ntdll!ZwWaitForWorkViaWorkerFactory ()
    from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
   4    Thread 4104.0x1714 "sig"                                       0x00007fff3c44d124 in ntdll!ZwReadFile () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
   5    Thread 4104.0x211c "multiple-successive-infcall"               0x00007fff3c44dbb4 in ntdll!ZwWaitForMultipleObjects () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
   6    Thread 4104.0x2070 "multiple-successive-infcall"               0x00007fff3c44dbb4 in ntdll!ZwWaitForMultipleObjects () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
   7    Thread 4104.0x1d3c "multiple-successive-infcall"               0x00007fff3c44dbb4 in ntdll!ZwWaitForMultipleObjects () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
 * 8    Thread 4104.0xa54 "multiple-successive-infcall"                thread_function (args=0x10040704c <thread_ids+12>)
     at /cygdrive/c/Users/alves/rocm/gdb/src/gdb/testsuite/gdb.threads/multiple-successive-infcall.c:75

 #2 - The test enables scheduler locking and switches to each thread
      in turn, and then does an infcall.  On Windows, system calls
      aren't interruptible like on Windows.  There's no concept of
      EINTR and syscall restart.  So if a thread is in a syscall,
      actually running kernel code, then an infcall will only complete
      once the syscall returns.  If the syscall is blocked waiting for
      another thread to unblock it, then the infcall never completes.
      You can pause it with Ctrl-C, but you'll see that the thread
      hasn't executed any userspace instruction.

      For example:

       (gdb) t 8
       [Switching to thread 8 (Thread 4104.0xa54)]
       #0  0x00007fff3c44dbb4 in ntdll!ZwWaitForMultipleObjects () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
       (gdb) p get_value ()
       * hang *

       * press ctrl-c *

       Thread 8 "multiple-successive-infcall" stopped.
       get_value () at /cygdrive/c/Users/alves/rocm/gdb/src/gdb/testsuite/gdb.threads/multiple-successive-infcall.c:38
       38      get_value ()
       The program being debugged was signaled while in a function called from GDB.
       GDB remains in the frame where the signal was received.
       To change this behavior use "set unwindonsignal on".
       Evaluation of the expression containing the function
       (get_value) will be abandoned.
       When the function is done executing, GDB will silently stop.
       (gdb) bt
       #0  get_value () at /cygdrive/c/Users/alves/rocm/gdb/src/gdb/testsuite/gdb.threads/multiple-successive-infcall.c:38
       #1  <function called from gdb>
       #2  0x00007fff3c44dbb4 in ntdll!ZwWaitForMultipleObjects () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
       #3  0x00007fff39cd1b40 in WaitForMultipleObjectsEx () from /cygdrive/c/Windows/System32/KERNELBASE.dll
       ...
       (gdb) si
       * hang *

    This results in failures like these:

       call get_value()
       FAIL: gdb.threads/multiple-successive-infcall.exp: thread=4: call inferior function (timeout)

This commit thus tweaks the testcase to make it work on Cygwin too.
First, it makes the .exp file figure out which threads are the ones
created by the testcase.  The current testcase also tries the infcall
on the main thread.  It's simpler to not worry about the main thread
being blocked in a syscall.  So we just no longer test the syscall
through that thread.  It is not important for the original motivation
for the testcase.

With this, the testcase now passes cleanly on Cygwin:

  === gdb Summary ===

  # of expected passes            15

Change-Id: I5f69bafe6cecb83f18fb22ba7ee2368229fc4f9f
gdb/testsuite/gdb.threads/multiple-successive-infcall.c
gdb/testsuite/gdb.threads/multiple-successive-infcall.exp