]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commit
Windows gdbserver: Fix scheduler-locking
authorPedro Alves <pedro@palves.net>
Thu, 11 May 2023 11:15:36 +0000 (12:15 +0100)
committerPedro Alves <pedro@palves.net>
Mon, 9 Jun 2025 17:09:14 +0000 (18:09 +0100)
commit3be9bd318d2b104c159ab497cbcf4fc34258d500
tree7c5c13db27f701d99df5f9a0d132b761e487d61b
parent783d36fa6443caaaa0c53ec6776aca51f72506ea
Windows gdbserver: Fix scheduler-locking

This rewrites win32_process_target::resume such that scheduler-locking
is implemented properly.

It also uses the new get_last_debug_event_ptid function to avoid
considering passing a signal to the wrong thread, like done for the
native side in a previous patch.

Note this code/comment being removed:

 -    /* Yes, we're ignoring resume_info[0].thread.  It'd be tricky to make
 -       the Windows resume code do the right thing for thread switching.  */
 -    tid = windows_process.current_event.dwThreadId;

This meant that scheduler-locking currently is broken badly unless you
stay in the thread that last reported an event.  If you switch to a
different thread from the one that last reported an event and step,
you get a spurious SIGTRAP in the thread that last reported a stop,
not the one that you tried to step:

 (gdb) t 1
 [Switching to thread 1 (Thread 3908)]
 #0  0x00007fffc768d6e4 in ntdll!ZwDelayExecution () from target:C:/Windows/SYSTEM32/ntdll.dll
 (gdb) set scheduler-locking on
 (gdb) set disassemble-next-line on
 (gdb) frame
 #0  0x00007fffc768d6e4 in ntdll!ZwDelayExecution () from target:C:/Windows/SYSTEM32/ntdll.dll
 => 0x00007fffc768d6e4 <ntdll!ZwDelayExecution+20>:       c3                      ret
 (gdb) si

 Thread 3 received signal SIGTRAP, Trace/breakpoint trap.
 [Switching to Thread 2660]
 0x00007fffc4e4e92e in KERNELBASE!EncodeRemotePointer () from target:C:/Windows/System32/KernelBase.dll
 => 0x00007fffc4e4e92e <KERNELBASE!EncodeRemotePointer+8254>:    eb 78                   jmp    0x7fffc4e4e9a8 <KERNELBASE!EncodeRemotePointer+8376>
 (gdb)

Note how we switched to thread 1, stepped, and GDBserver still stepped
thread 3...  This is fixed by this patch.  We now get:

  (gdb) info threads
    Id   Target Id         Frame
    1    Thread 920        0x00007ffe0372d6e4 in ntdll!ZwDelayExecution () from target:C:/Windows/SYSTEM32/ntdll.dll
    2    Thread 8528       0x00007ffe03730ad4 in ntdll!ZwWaitForWorkViaWorkerFactory () from target:C:/Windows/SYSTEM32/ntdll.dll
    3    Thread 3128       0x00007ffe03730ad4 in ntdll!ZwWaitForWorkViaWorkerFactory () from target:C:/Windows/SYSTEM32/ntdll.dll
  * 4    Thread 7164       0x00007ffe0102e929 in KERNELBASE!EncodeRemotePointer () from target:C:/Windows/System32/KernelBase.dll
    5    Thread 8348       0x00007ffe0372d6e4 in ntdll!ZwDelayExecution () from target:C:/Windows/SYSTEM32/ntdll.dll
    6    Thread 2064       0x00007ffe0372d6e4 in ntdll!ZwDelayExecution () from target:C:/Windows/SYSTEM32/ntdll.dll
  (gdb) t 1
  [Switching to thread 1 (Thread 920)]
  #0  0x00007ffe0372d6e4 in ntdll!ZwDelayExecution () from target:C:/Windows/SYSTEM32/ntdll.dll
  (gdb) set scheduler-locking on
  (gdb) si
  0x00007ffe0372d6e4 in ntdll!ZwDelayExecution () from target:C:/Windows/SYSTEM32/ntdll.dll
  (gdb) si
  0x00007ffe00f9b44e in SleepEx () from target:C:/Windows/System32/KernelBase.dll
  (gdb) si
  0x00007ffe00f9b453 in SleepEx () from target:C:/Windows/System32/KernelBase.dll

I.e., we kept stepping the right thread, thread 1.

Note we stopped again at 0x00007ffe0372d6e4 the first time (same PC
the thread already was at before the first stepi) because the thread
had been stopped at a syscall, so that's normal:

 (gdb) disassemble
 Dump of assembler code for function ntdll!ZwDelayExecution:
    0x00007ffe0372d6d0 <+0>:     mov    %rcx,%r10
    0x00007ffe0372d6d3 <+3>:     mov    $0x34,%eax
    0x00007ffe0372d6d8 <+8>:     testb  $0x1,0x7ffe0308
    0x00007ffe0372d6e0 <+16>:    jne    0x7ffe0372d6e5 <ntdll!ZwDelayExecution+21>
    0x00007ffe0372d6e2 <+18>:    syscall
 => 0x00007ffe0372d6e4 <+20>:    ret

Change-Id: I44f4fe4cb98592517569c6716b9d189f42db25a0
gdbserver/win32-low.cc