]> git.ipfire.org Git - thirdparty/binutils-gdb.git/log
thirdparty/binutils-gdb.git
7 weeks agoAnnounce attach should be earlier (submit separately) users/palves/windows-non-stop-v2-plus
Pedro Alves [Wed, 3 Apr 2024 21:14:51 +0000 (22:14 +0100)] 
Announce attach should be earlier (submit separately)

If GDB ever hangs in the loop before the actual detach, it's nice to
say:

While working on the previous patch, I noticed:

 (gdb) detach
 [windows events] continue_one_thread: continuing 0x24c4, debug_registers_changed=0, ContextFlags=0xc810001f
 [windows events] continue_one_thread: trap flag for 0x24c4, trap=0
 [windows events] continue_one_thread: continuing 0x22dc, debug_registers_changed=0, ContextFlags=0xd010001f
 [windows events] continue_one_thread: trap flag for 0x22dc, trap=0
 [windows events] continue_one_thread: continuing 0x208c, debug_registers_changed=0, ContextFlags=0x0
 [windows events] continue_one_thread: continuing 0x264c, debug_registers_changed=0, ContextFlags=0x0
 [windows events] break_out_process_thread: got unrelated event, code 1
 [windows events] windows_continue: windows_continue -> continue_last_debug_event
 [windows events] continue_last_debug_event: ContinueDebugEvent (cpid=11400, ctid=0x24c4, DBG_CONTINUE)
 [windows events] break_out_process_thread: got CREATE_THREAD_DEBUG_EVENT for break thread
 [windows events] windows_continue: windows_continue -> continue_last_debug_event
 [windows events] continue_last_debug_event: ContinueDebugEvent (cpid=11400, ctid=0x19fc, DBG_CONTINUE)
 Detaching from program: /home/alves/rocm/gdb/build-cygwin-testsuite/outputs/gdb.base/watchpoint-hw-attach/watchpoint-hw-attach, process 11400
 [Inferior 1 (process 11400) detached]
 [windows events] close: inferior_ptid=0

Note the "Detaching from program" message only appears after we've
done a lot of things, including looping looking for an event.  If that
ever hangs, we never see the "Detaching" message.  That doesn't seem
very consistent.  This commit moves the target_announce_detach call
earlier, before we actually detach.

We now get:

 (gdb) detach
 Detaching from program: /home/alves/rocm/gdb/build-cygwin-testsuite/outputs/gdb.base/watchpoint-hw-attach/watchpoint-hw-attach, process 11544
 [windows events] continue_one_thread: continuing 0x3554, debug_registers_changed=0, ContextFlags=0xc810001f
 [windows events] continue_one_thread: trap flag for 0x3554, trap=0
 [windows events] continue_one_thread: continuing 0x4320, debug_registers_changed=0, ContextFlags=0xd010001f
 [windows events] continue_one_thread: trap flag for 0x4320, trap=0
 [windows events] continue_one_thread: continuing 0x3944, debug_registers_changed=0, ContextFlags=0xd010001f
 [windows events] continue_one_thread: trap flag for 0x3944, trap=0
 [windows events] continue_one_thread: continuing 0x1710, debug_registers_changed=0, ContextFlags=0x0
 [windows events] break_out_process_thread: got unrelated event, code 1
 [windows events] windows_continue: windows_continue -> continue_last_debug_event
 [windows events] continue_last_debug_event: ContinueDebugEvent (cpid=11544, ctid=0x3554, DBG_CONTINUE)
 [windows events] break_out_process_thread: got CREATE_THREAD_DEBUG_EVENT for break thread
 [windows events] windows_continue: windows_continue -> continue_last_debug_event
 [windows events] continue_last_debug_event: ContinueDebugEvent (cpid=11544, ctid=0x438c, DBG_CONTINUE)
 [Inferior 1 (process 11544) detached]
 [windows events] close: inferior_ptid=0

Change-Id: I5c3b90cd8cb8755480c2e2b6e23e34fb9043e47e

7 weeks agoremote target pid_to_string for gdb.server/ext-attach.exp (incomplete)
Pedro Alves [Mon, 17 Jul 2023 21:52:58 +0000 (22:52 +0100)] 
remote target pid_to_string for gdb.server/ext-attach.exp (incomplete)

Change-Id: I7c3e70dbb78ed0e112fff15356ba824199fa95d3

7 weeks agoAdjust gdb.threads/step-over-trips-on-watchpoint.exp for Cygwin (depends on schedlock)
Pedro Alves [Mon, 9 Jun 2025 17:27:17 +0000 (18:27 +0100)] 
Adjust gdb.threads/step-over-trips-on-watchpoint.exp for Cygwin (depends on schedlock)

Change-Id: Ief28e6ebf47abdcd2e71c5f2c70caf2d8753ef5e

7 weeks agoAdjust gdb.threads/schedlock.exp for Cygwin (depends on schedlock)
Pedro Alves [Fri, 30 Jun 2023 17:33:52 +0000 (18:33 +0100)] 
Adjust gdb.threads/schedlock.exp for Cygwin (depends on schedlock)

Change-Id: I574c702d370da6eaf92e82ce81efe1a44660b24f

7 weeks agoFix gdb.threads/multiple-successive-infcall.exp on Cygwin (hack)
Pedro Alves [Mon, 26 Jun 2023 18:19:04 +0000 (19:19 +0100)] 
Fix gdb.threads/multiple-successive-infcall.exp on Cygwin (hack)

Need to retest, maybe it fixed itself on Windows 11, or something,
meanwhile...

Change-Id: I62becd91b41dc2bede8c35c1b4f792ecbbd048dc

7 weeks agoSoftware watchpoints and threaded inferiors (WIP, submit independently)
Pedro Alves [Fri, 23 Jun 2023 14:31:38 +0000 (15:31 +0100)] 
Software watchpoints and threaded inferiors (WIP, submit independently)

Need to convince myself of the approach.

Change-Id: If649d30233ac1c2e57ea09cc8050e35f7a4bcf12

7 weeks agoFix gdb.threads/multiple-successive-infcall.exp on Windows (depends on schedlock)
Pedro Alves [Fri, 3 May 2024 17:24:22 +0000 (18:24 +0100)] 
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

7 weeks agoExtra "maint set show-debug-dregs" debug output (submit separately)
Pedro Alves [Wed, 14 Jun 2023 18:20:53 +0000 (19:20 +0100)] 
Extra "maint set show-debug-dregs" debug output (submit separately)

Change-Id: Iba98597f1ed858ce6ec40a449c520088e9c54031

7 weeks agogdb.threads/schedlock.exp: handle "stopped" too (WIP, to squash)
Pedro Alves [Thu, 8 Jun 2023 13:55:13 +0000 (14:55 +0100)] 
gdb.threads/schedlock.exp: handle "stopped" too (WIP, to squash)

Is there testsuite code handling SIGTRAP that we can clean up?

Change-Id: I6efa8ea3706c9d1f8dda2cc99a5c1f9ad54f26f2

7 weeks agoWindows all-stop, interrupt with "stopped" instead of SIGTRAP
Pedro Alves [Fri, 5 May 2023 14:51:31 +0000 (15:51 +0100)] 
Windows all-stop, interrupt with "stopped" instead of SIGTRAP

Before:

 (gdb) c&
 Continuing.
 ...
 (gdb) info threads
   Id   Target Id          Frame
 * 1    Thread 1180.0x1374 (running)
   2    Thread 1180.0xc3c  (running)
   3    Thread 1180.0x6ec  (running)
   5    Thread 1180.0x1378 (running)
 (gdb)
 ...
 [New Thread 1180.0xc70]
 [Thread 1180.0x1378 exited with code 0]
 [Thread 1180.0xc70 exited with code 0]
 [New Thread 1180.0xdc0]
 ...
 interrupt
 (gdb) [New Thread 1180.0x1010]

 Thread 8 received signal SIGTRAP, Trace/breakpoint trap.
 [Switching to Thread 1180.0x1010]
 0x00007ffa57490b71 in ntdll!DbgBreakPoint () from C:\Windows\SYSTEM32\ntdll.dll
 info threads
   Id   Target Id          Frame
   1    Thread 1180.0x1374 0x00007ffa5748d6e4 in ntdll!ZwDelayExecution () from C:\Windows\SYSTEM32\ntdll.dll
   2    Thread 1180.0xc3c  0x00007ffa57490ad4 in ntdll!ZwWaitForWorkViaWorkerFactory () from C:\Windows\SYSTEM32\ntdll.dll
   3    Thread 1180.0x6ec  0x00007ffa5748d6e4 in ntdll!ZwDelayExecution () from C:\Windows\SYSTEM32\ntdll.dll
   7    Thread 1180.0xdc0  0x00007ffa5748d6e4 in ntdll!ZwDelayExecution () from C:\Windows\SYSTEM32\ntdll.dll
 * 8    Thread 1180.0x1010 0x00007ffa57490b71 in ntdll!DbgBreakPoint () from C:\Windows\SYSTEM32\ntdll.dll
 (gdb)

After:

 (gdb) info threads
   Id   Target Id          Frame
 * 1    Thread 5912.0x394  (running)
   2    Thread 5912.0x608  (running)
   3    Thread 5912.0x1704 (running)
   10   Thread 5912.0x870  (running)
 (gdb)
 ...
 [Thread 5912.0x870 exited with code 0]
 ...
 (gdb) interrupt
 (gdb)
 Thread 1 stopped.
 0x00007ffa5748d6e4 in ntdll!ZwDelayExecution () from C:\Windows\SYSTEM32\ntdll.dll
 info threads
   Id   Target Id          Frame
 * 1    Thread 5912.0x394  0x00007ffa5748d6e4 in ntdll!ZwDelayExecution () from C:\Windows\SYSTEM32\ntdll.dll
   2    Thread 5912.0x608  0x00007ffa57490ad4 in ntdll!ZwWaitForWorkViaWorkerFactory () from C:\Windows\SYSTEM32\ntdll.dll
   3    Thread 5912.0x1704 0x00007ffa5748d6e4 in ntdll!ZwDelayExecution () from C:\Windows\SYSTEM32\ntdll.dll
   8    Thread 5912.0x1200 0x00007ffa5748d6e4 in ntdll!ZwDelayExecution () from C:\Windows\SYSTEM32\ntdll.dll
 (gdb)

Change-Id: I569fc69392ce9a070a2ebe1003388b7386412b14

7 weeks agogdb.threads/schedlock.exp: Expected SIGTRAP too (WIP)
Pedro Alves [Wed, 7 Jun 2023 13:53:00 +0000 (14:53 +0100)] 
gdb.threads/schedlock.exp: Expected SIGTRAP too (WIP)

The 'Windows all-stop, interrupt with "stopped" instead of SIGTRAP'
patch should make this unnecessary.

Change-Id: I06925ae317784e6babd57a8d1904945bb01d2b9d

7 weeks agoWindows GDB: Avoid hang second attach (gdb.base/attach.exp) (depends on non-stop...
Pedro Alves [Fri, 2 Jun 2023 22:08:49 +0000 (23:08 +0100)] 
Windows GDB: Avoid hang second attach (gdb.base/attach.exp) (depends on non-stop series)

[Before the non-stop series, there is no 'windows_process.process_id' field.]

gdb.base/attach.exp starts a second inferior and tries to attach the
second inferior to the same process that inferior 1 is already
debugging.  The point is to make sure that the backend errors out when
it tries to attach to a process that is already being debugged.

windows_nat_target::attach and windows_nat_target::create_inferior
both hang in this situation, because they call into do_synchronously,
which hangs because the 'process_thread' thread is blocked in
WaitForDebugEvent.

Until the Windows backend is taught to debug multiple processes, which
will require having one process_thread thread per inferior, detect the
situation and error out before GDB hangs.

Change-Id: I55b4438795439673c49fa55f55ddf0191f4f0ea8

7 weeks agoMake gdb.threads/watchthreads.exp fetch registers of all threads
Pedro Alves [Wed, 26 Jul 2023 14:32:18 +0000 (15:32 +0100)] 
Make gdb.threads/watchthreads.exp fetch registers of all threads

With this testcase change, on Cygwin, I see:

 Running /cygdrive/c/Users/alves/rocm/gdb/src/gdb/testsuite/gdb.threads/watchthreads.exp ...
 FAIL: gdb.threads/watchthreads.exp: threaded watch loop
 FAIL: gdb.threads/watchthreads.exp: combination of threaded watchpoints = 30

Change-Id: I927bfe1bb7fe8b5b0230d4afc64c4bb86e11261c

7 weeks agoSkip gdb.base/many-headers.exp on Cygwin (submit independently)
Pedro Alves [Fri, 23 Jun 2023 21:03:57 +0000 (22:03 +0100)] 
Skip gdb.base/many-headers.exp on Cygwin (submit independently)

When I first wrote this, I didn't have dumper.exe setup, so the
testcase would spend 10 minutes doing the mmap loop thing, and then it
wouldn't create a core dump anyhow.  But with dumper.exe around, the
testcase does generate the core dump, and it passes cleanly!  So just
skipping isn't right.  I'm inclined to just drop the patch.

I also wonder whether using native Win32 VirtualAlloc would be a lot
faster than Cygwin mmap...

Change-Id: I9ea3bc5c561115ee3997120556efc5faa7def080

7 weeks agoAdjust gdb.threads/multiple-step-overs.exp for Cygwin (depends on schedlock)
Pedro Alves [Fri, 30 Jun 2023 18:45:35 +0000 (19:45 +0100)] 
Adjust gdb.threads/multiple-step-overs.exp for Cygwin (depends on schedlock)

Change-Id: I739cfcbe48f1399504b9a038182d1b67dc6d6399

7 weeks agoConvert gdb.base/watchpoint-hw-attach.exp to spawn_wait_for_attach
Pedro Alves [Wed, 3 Apr 2024 21:34:47 +0000 (22:34 +0100)] 
Convert gdb.base/watchpoint-hw-attach.exp to spawn_wait_for_attach

On Cygwin, starting an inferior under GDB, and detaching it, quitting
GDB, and then closing the shell, like so:

  (gdb) start
  (gdb) detach
  (gdb) quit
  # close shell

... hangs the parent shell of GDB (not GDB!) until the inferior
process that was detached (and it still using the same terminal GDB
was using) exits too.

This leads to odd failures in gdb.base/watchpoint-hw-attach.exp like
so:

 detach
 Detaching from program: .../outputs/gdb.base/watchpoint-hw-attach/watchpoint-hw-attach, process 16580
 [Inferior 1 (process 16580) detached]
 (gdb) FAIL: gdb.base/watchpoint-hw-attach.exp: detach

Fix this by converting the testcase to spawn the inferior outside GDB,
with spawn_wait_for_attach.

With this patch, the testcase passes cleanly on Cygwin, for me.

Change-Id: I8e3884073a510d6fd2fff611e1d26fc808adc4fa

7 weeks agoAdjust gdb.base/memops-watchpoint.exp for Cygwin/Windows
Pedro Alves [Tue, 11 Feb 2025 14:43:39 +0000 (14:43 +0000)] 
Adjust gdb.base/memops-watchpoint.exp for Cygwin/Windows

When testing gdb.base/memops-watchpoint.exp on Cygwin, I see:

 ...
 continue
 Continuing.

 Thread 1 "memops-watchpoint" hit Hardware watchpoint 2: -location a[28]

 Old value = 104 'h'
 New value = 0 '\000'
 memset () at /usr/src/debug/cygwin-3.5.4-1/winsup/cygwin/x86_64/memset.S:68
 68              rep     stosq
 (gdb) FAIL: gdb.base/memops-watchpoint.exp: continue until memset watchpoint hits

Etc.

This fails on Windows because there all inferiors are multi-threaded
(because both Windows and the Cygwin runtime spawn helper threads), so
we always see the

  'Thread N "foo" hit'

prefix, which the testcase isn't expecting.

Fix it by optionally expecting such the "Thread ... hit" prefix bit.

Change-Id: Ia06eaf1e152f512f39324d04298e6784eca3e537

7 weeks agoSimplify gdb.base/memops-watchpoint.exp
Pedro Alves [Thu, 30 Jan 2025 20:38:29 +0000 (20:38 +0000)] 
Simplify gdb.base/memops-watchpoint.exp

gdb.base/memops-watchpoint.exp has the same code basically repeated
three times.  Simplify by refactoring the common code to a procedure.

Modernize the gdb_test_multiple call a little bit while at it: use
-wrap and $gdb_test_name.

Change-Id: I42d9cbccf32760a2bc3dab2aa60412ad5a2ae291

7 weeks agoSkip gdb.base/libsegfault.exp on Cygwin
Pedro Alves [Fri, 23 Jun 2023 19:23:20 +0000 (20:23 +0100)] 
Skip gdb.base/libsegfault.exp on Cygwin

Running gdb.base/libsegfault.exp on Cygwin, in parallel mode causes
badness:

 $ make check-parallel TESTS="gdb.base/libsegfault.exp"
 ...
 Running /home/alves/gdb/src/gdb/testsuite/gdb.base/libsegfault.exp ...
       0 [main] expect 6611 C:\cygwin64\bin\expect.exe: *** fatal error in forked process - error while loading shared libraries: libSegFault.so: cannot open shared object file: No such file or directory
*** starting '"C:\cygwin64\bin\dumper.exe" -n "C:\cygwin64\bin\expect.exe" 8012' for pid 6611, tid 7992
 *** continuing pid 6611
 parent: sync byte write: broken pipe
 make[1]: *** [Makefile:320: check/gdb.base/libsegfault.exp] Error 255
 make[1]: Target 'do-check-parallel' not remade because of errors.
 make[1]: Leaving directory '/home/alves/gdb/build-cygwin-testsuite'
 outputs/gdb.base/libsegfault/gdb.sum: no recognised summary line
 outputs/gdb.base/libsegfault/gdb.log: no recognised summary line
 make: *** [Makefile:260: check-parallel] Error 2
 $

I.e., Expect's spawn fails, and that brings down the whole Expect
process, for some reason.  The result is that we end up with
incomplete gdb.sum/gdb.log files, which dg-extract-results.sh can't
process.  Since libSegFault.so is a glibc feature that doesn't exist
on Cygwin, just skip the test there.

Change-Id: I44bdbffa25a5d21c5019418b68776d334a57be26

7 weeks agogdb testsuite: Introduce allow_multi_inferior_tests and use it throughout
Pedro Alves [Thu, 1 Jun 2023 17:43:15 +0000 (18:43 +0100)] 
gdb testsuite: Introduce allow_multi_inferior_tests and use it throughout

The Windows port does not support multi-process debugging.  Testcases
that want to exercise multi-process currently FAIL and some hit
cascading timeouts.  Add a new allow_multi_inferior_tests procedure,
meant to be used with require, and sprinkle it throughout testcases as
needed.

Change-Id: I4a10d8f04f9fa10f4b751f140ad0a6d31fbd9dfb

7 weeks agogdb testsuite: Introduce allow_fork_tests and use it throughout
Pedro Alves [Thu, 1 Jun 2023 15:19:03 +0000 (16:19 +0100)] 
gdb testsuite: Introduce allow_fork_tests and use it throughout

Cygwin debugging does not support follow fork.  There is currently no
interface between the debugger and the Cygwin runtime to be able to
intercept forks and execs.  Consequently, testcases that try to
exercise fork/exec all FAIL, and several hit long cascading timeouts.

Add a new allow_fork_tests procedure, meant to be used with require,
and sprinkle it throughout testcases that exercise fork.

Note that some tests currently are skipped on targets other than
Linux, with something like:

 # Until "set follow-fork-mode" and "catch vfork" are implemented on
 # other targets...
 #
 if {![istarget "*-linux*"]} {
     continue
 }

However, some BSD ports also support fork debugging nowadays, and the
testcases were never adjusted...  That is why the new allow_fork_tests
procedure doesn't look for linux.

With this patch, on Cygwin, I get this:

 $ make check TESTS="*/*fork*.exp"

 ...
 === gdb Summary ===

 # of expected passes            6
 # of untested testcases         1
 # of unsupported tests          31

Reviewed-By: Keith Seitz <keiths@redhat.com>
Change-Id: I0c5e8c574d1f61b28d370c22a0b0b6bc3efaf978

7 weeks agogdb.multi/attach-no-multi-process.exp: Detect no remote non-stop
Pedro Alves [Fri, 2 Jun 2023 00:05:38 +0000 (01:05 +0100)] 
gdb.multi/attach-no-multi-process.exp: Detect no remote non-stop

Running gdb.multi/attach-no-multi-process.exp on Cygwin, where
GDBserver does not support non-stop mode, I see:

 FAIL: gdb.multi/attach-no-multi-process.exp: target_non_stop=off: info threads
 FAIL: gdb.multi/attach-no-multi-process.exp: target_non_stop=on: attach to the program via remote (timeout)
 FAIL: gdb.multi/attach-no-multi-process.exp: target_non_stop=on: info threads (timeout)

Let's ignore the first "info threads" fail.  The timeouts look like
this:

 builtin_spawn /home/alves/gdb-cache-cygwin/gdb/../gdbserver/gdbserver --once --multi localhost:2346
 Listening on port 2346
 target extended-remote localhost:2346
 Remote debugging using localhost:2346
 Non-stop mode requested, but remote does not support non-stop
 (gdb) gdb_do_cache: can_spawn_for_attach (  )
 builtin_spawn /home/alves/gdb/build-cygwin-testsuite/outputs/gdb.multi/attach-no-multi-process/attach-no-multi-process
 attach 14540
 FAIL: gdb.multi/attach-no-multi-process.exp: target_non_stop=on: attach to the program via remote (timeout)
 info threads
 FAIL: gdb.multi/attach-no-multi-process.exp: target_non_stop=on: info threads (timeout)

Note the "Non-stop mode requested, but remote does not support
non-stop" line.

The intro to gdb_target_cmd_ext says:

 # gdb_target_cmd_ext
 # Send gdb the "target" command.  Returns 0 on success, 1 on failure, 2 on
 # unsupported.

That's perfect here, we can just use gdb_target_cmd_ext instead of
gdb_target_cmd, and check for 2 (unsupported).  That's what this patch
does.

However gdb_target_cmd_ext incorrectly returns 1 instead of 2 for the
case where the remote target says it does not support non-stop.  That
is also fixed by this patch.

With this, we no longer get those timeout fails.  We get instead:

 target extended-remote localhost:2346
 Remote debugging using localhost:2346
 Non-stop mode requested, but remote does not support non-stop
 (gdb) UNSUPPORTED: gdb.multi/attach-no-multi-process.exp: target_non_stop=on: non-stop RSP

Change-Id: I1ab3162f74200c6c02a17a0600b102d2d12db236

7 weeks ago7.8-symtab-cygwin.patch
Pedro Alves [Mon, 29 Apr 2024 20:19:01 +0000 (21:19 +0100)] 
7.8-symtab-cygwin.patch

See https://sourceware.org/ml/gdb-patches/2002-03/msg00557.html

palves: #ifndef added for Linux

Change-Id: I6c28cec0279bd9c9ad18fa415f7c9e0e410f2d62

7 weeks agoHack canonicalize_file_name (should be fixed in gnulib)
Pedro Alves [Fri, 22 Mar 2024 16:27:01 +0000 (16:27 +0000)] 
Hack canonicalize_file_name (should be fixed in gnulib)

Needed when cross compiling.

The gnulib canonicalize_file_name override breaks finding cygwin1.dll.

When compiling natively, gnulib doesn't override
canonicalize_file_name, but gnulib has hardcoded defaults for cross
compiling, and the default is wrong for Cygwin.

Change-Id: Ief87ddf798c137fb6dff91fe0fa4c5ada6da1153

7 weeks agoSuspended REPLY_LATER (WIP)
Pedro Alves [Thu, 10 Apr 2025 22:28:34 +0000 (23:28 +0100)] 
Suspended REPLY_LATER (WIP)

This should be needed, but I haven't managed to trigger it, yet...

Change-Id: I38aa876fe93a9427d43d17f1888c01ee43fe431c

7 weeks agoShow CONTEXT_EXCEPTION_REQUEST info in "info threads" (submit separately) (WIP)
Pedro Alves [Mon, 12 Jun 2023 18:07:30 +0000 (19:07 +0100)] 
Show CONTEXT_EXCEPTION_REQUEST info in "info threads" (submit separately) (WIP)

document CONTEXT_EXCEPTION_REQUEST / CONTEXT_EXCEPTION_REPORTING /
   CONTEXT_EXCEPTION_ACTIVE / CONTEXT_SERVICE_ACTIVE.

    "so interesting... so I've been looking at only remaining testsuite
    hang that I saw in my last testsuite run.  it's a test that enables
    schedlock, and then calls a function in each thread in the program.
    on cygwin, the infcalls hang, and things break down such that the
    testcase ends up hanging forever.  back to the infcall hanging -- the
    issue is calling a function in a thread that is currently running
    kernel code.  on linux, most system calls are interruptible, and then
    syscall restart is a thing.  on Windows, system calls are NOT
    interruptible.  The threads in question in the testcase are stopped
    inside the syscall done by ntdll!ZwWaitForMultipleObjects .  I can
    pause the hung thread with ctrl-c, and its (userspace) PC won't have
    changed, still pointing to the entry to the function GDB wants to
    call.  Now, I remembered from reading about SuspendThread and
    GetThreadContext woes that there was a way to tell whether the
    interrupted thread was running kernel or userspace code.  After
    digging through my bookmarks, I found it.  It's explained here, in a
    comment from 2014 on a blog from 2010:

      https://zachsaw.blogspot.com/2010/11/wow64-bug-getthreadcontext-may-return.html#c5639760895973344002

    other places around the interwebs that I see with
    CONTEXT_EXCEPTION_REQUEST references all point to that sole comment...
    Microsoft doesn't document these flags, AFAICT.  Kind of funny.

    not sure what to do with that.  Maybe we could add a warning whenever
    GDB changes register contents of a thread blocked inside a syscall.
    For now, I'll just see if I can avoid the issue / hang in the test
    itself.

    "interesting -- I tried the same with visual studio, and it
     doesn't prevent evaluating the expression -- a dialog pops up
     saying something like "evaluating expression", and then after a few
     seconds it aborts it, with the result being the above.

     a time out for function calls sounds like a good idea to me.  I
     think lldb has one."

   At:
     https://learn.microsoft.com/en-us/visualstudio/debugger/error-evaluating-the-function-function-timed-out-and-needed-to-be-aborted-in-an-unsafe-way?view=vs-2022

     "One common reason for this problem is that when the debugger
     evaluates a property, it only allows the thread being inspected to
     execute. So if the property is waiting on other threads to run
     inside the debugged application, and if it is waiting in a way that
     the .NET Runtime isn't able to interrupt, this problem will
     happen."

Change-Id: I04221f123eef81d59b5cc1c9fbb298f7a33fa001

7 weeks agoFix MI -break-insert assertion failure (submit separately) (WIP)
Pedro Alves [Wed, 9 Apr 2025 13:29:53 +0000 (14:29 +0100)] 
Fix MI -break-insert assertion failure (submit separately) (WIP)

TODO:
  - commit log
  - testcase

This is exposed by some pre-existing test.  Need to check which one it
was.

 (gdb) interpreter-exec mi "222-break-insert -g i100 foo"
 &"../../src/gdb/breakpoint.c:9165: internal-error: find_program_space_for_breakpoint: Assertion `inf != nullptr' failed.\nA problem internal to GDB has been detected,\nfurther debugging may prove unreliable."
 &"\n"
 &"----- Backtrace -----\n"
 &"Backtrace unavailable\n"
 &"---------------------\n"
 ~"../../src/gdb/breakpoint.c:9165: internal-error: find_program_space_for_breakpoint: Assertion `inf != nullptr' failed.\nA problem internal to GDB has been detected,\nfurther debugging may prove unreliable.\nQuit this debugging session? (y or n) "

From here:

 (top-gdb) bt
 #0  internal_error_loc (file=0x555556187e56 "../../src/gdb/breakpoint.c", line=9165, fmt=0x555556187bc8 "%s: Assertion `%s' failed.") at ../../src/gdbsupport/errors.cc:53
 #1  0x0000555555791a55 in find_program_space_for_breakpoint (thread=-1, inferior=100) at ../../src/gdb/breakpoint.c:9165
 #2  0x0000555555791f96 in create_breakpoint (gdbarch=0x5555568db900, locspec=0x5555567e7100, cond_string=0x0, thread=-1, inferior=100, extra_string=0x0, force_condition=false, parse_extra=0, tempflag=0, type_wanted=bp_breakpoint, ignore_count=0, pending_break_support=AUTO_BOOLEAN_FALSE, ops=0x555556642aa0 <code_breakpoint_ops>, from_tty=0, enabled=1, internal=0, flags=0) at ../../src/gdb/breakpoint.c:9275
 #3  0x0000555555bb9d15 in mi_cmd_break_insert_1 (dprintf=0, command=0x5555567e6fd0 "break-insert", argv=0x5555567e7070, argc=3) at ../../src/gdb/mi/mi-cmd-break.c:366
 #4  0x0000555555bb9e15 in mi_cmd_break_insert (command=0x5555567e6fd0 "break-insert", argv=0x5555567e7070, argc=3) at ../../src/gdb/mi/mi-cmd-break.c:383
 ...

Change-Id: Ibde0d4d098bf0b5d7b057e818a77a63c84806a3c

7 weeks ago=== v2 series ends here ===
Pedro Alves [Wed, 15 Jan 2025 13:49:01 +0000 (13:49 +0000)] 
=== v2 series ends here ===

Change-Id: I9f84bd7b08c5d64a7da452cfb87457ca111c41c6

7 weeks agoMention Windows scheduler-locking and non-stop support in NEWS
Pedro Alves [Mon, 22 May 2023 18:16:30 +0000 (19:16 +0100)] 
Mention Windows scheduler-locking and non-stop support in NEWS

Add a couple notes to gdb/NEWS mentioning:

  - Windows native target scheduler-locking support.
  - Windows native target non-stop support.

Change-Id: Id0e28525c06e57120c47b07f978581d1627d70f3

7 weeks agoWindows gdb: Always non-stop (default to "maint set target-non-stop on")
Pedro Alves [Fri, 16 May 2025 20:11:08 +0000 (21:11 +0100)] 
Windows gdb: Always non-stop (default to "maint set target-non-stop on")

Since having the target backend work in non-stop mode adds features
compared to old all-stop mode (signal/exception passing/suppression is
truly per-thread), this switches the backend to do
all-stop-on-top-of-non-stop, by having
windows_nat_target::always_non_stop_p return true if non-stop mode is
possible.

To be clear, this just changes how the backend works in coordination
with infrun.  The user-visible mode default mode is still all-stop.

The difference is that infrun is responsible for stopping all threads
when needed, instead of the backend (actually the kernel) always doing
that before reporting an event to infrun.

Change-Id: I83d23dbb1edc7692d5d8b37f5b9e0264c74d4940

7 weeks agoinfrun: with AS+NS, prefer process exit over thread exit
Pedro Alves [Wed, 14 May 2025 18:02:34 +0000 (19:02 +0100)] 
infrun: with AS+NS, prefer process exit over thread exit

This patch fixes gdb.base/ending-run.exp for Windows when the target
backend supports notifying infrun about thread exit events (which is
added by the Windows non-stop support, later).

Without this patch, and with the Windows target in non-stop mode
("maint set target-non-stop on"), we get, when stepping out of main:

 (gdb) PASS: gdb.base/ending-run.exp: Step to return
 next
 32      }
 (gdb) next
 [Thread 7956.0x2658 exited]
 [Thread 7956.0x2500 exited]
 [Thread 7956.0x2798 exited]
 Command aborted, thread exited.
 (gdb) FAIL: gdb.base/ending-run.exp: step out of main

With the patch, we get:

 (gdb) next
 [Thread 9424.0x40c exited]
 [Inferior 1 (process 9424) exited normally]
 (gdb) PASS: gdb.base/ending-run.exp: step out of main

In the failing case, what happens is that "next" enables
target_thread_events.  Then, the main thread causes the whole process
to exit.  On Windows, that makes the main thread report a thread exit
event, followed by thread exit events for all other threads, except
the last thread that happens to be the one that exits last.  That last
one reports an exit-process event instead.

Since "next" enabled target_thread_events, the Windows target backend
reports the main thread's exit event to infrun.  And then, since the
thread that was stepping reported a thread-exit, GDB aborts the "next"
command.

Stepping out of main is a very common thing to do, and I think
reporting the thread exit in this case when the whole process is
exiting isn't very useful.  I think we can do better.  So instead, if
we're about to report a thread exit in all-stop mode with the backend
in non-stop mode, and while stopping all threads, we see a
whole-process-exit event, prefer processing that event instead of
reporting the original thread exit.

A similar issue can be triggered on GNU/Linux as well, if we step over
an exit syscall that is called by any thread other than main.  This
scenario is exercised by the new testcase added by this patch.

Without the patch, the testcase shows:

 (gdb) next
 [Thread 0x7ffff7a00640 (LWP 3207243) exited]
 warning: error removing breakpoint 0 at 0x5555555551c3
 warning: error removing breakpoint 0 at 0x5555555551c3
 warning: error removing breakpoint 0 at 0x5555555551c3
 Command aborted, thread exited.
 Cannot remove breakpoints because program is no longer writable.
 Further execution is probably impossible.
 (gdb)

This is fixed for GNU/Linux by the patch, which results in:

 (gdb) next
 [Thread 0x7ffff7a00640 (LWP 3230550) exited]
 warning: error removing breakpoint 0 at 0x5555555551c3
 warning: error removing breakpoint 0 at 0x5555555551c3
 warning: error removing breakpoint 0 at 0x5555555551c3
 [Inferior 1 (process 3230539) exited normally]
 (gdb)

Pure all-stop targets (such as GNU/Linux GDBserver unless you force
non-stop with "maint set target-non-stop on") will unfortunately still
have the "Further execution is probably impossible." behavior, because
GDB can't see the process-exit event until the target is re-resumed.
That's unfortunate, but I don't think that should prevent improving
non-stop targets.  (And eventually I would like remote targets to be
always "maint set target-non-stop on" by default if possible, too.)

Change-Id: I56559f13e04aeafd812d15e4b408c8337bca5294

7 weeks agoAdd gdb.threads/leader-exit-schedlock.exp
Pedro Alves [Wed, 7 May 2025 17:29:56 +0000 (18:29 +0100)] 
Add gdb.threads/leader-exit-schedlock.exp

This adds a new test for letting the main thread exit the process with
scheduler-locking on, while there are other threads live.

On Linux, when the main thread exits without causing a whole-process
exit (e.g., via the main thread doing pthread_exit), the main thread
becomes zombie but does not report a thread exit event.  When
eventually all other threads of the process exit, the main thread is
unblocked out of its zombie state and reports its exit which we
interpret as the whole-process exit.

If the main-thread-exit causes a whole-process exit (e.g., via the
exit syscall), the process is the same, except that the exit syscall
makes the kernel force-close all threads immediately.

Importantly, the main thread on Linux is always the last thread that
reports the exit event.

On Windows, the main thread exiting is not special at all.  When the
main thread causes a process exit (e.g., for ExitProcess or by
returning from main), the debugger sees a normal thread exit event for
the main thread.  All other threads will follow up with a thread-exit
event too, except whichever thread happens to be the last one.  That
last one is the one that reports a whole-process-exit event instead of
an exit-thread event.  So, since programs are typically multi-threaded
on Windows (because the OS/runtime spawns some threads), when the main
thread just returns from main(), it is very typically _not_ the main
thread that reports the whole-process exit.

As a result, stepping the main thread with schedlock on Windows
results in the main thread exiting and the continue aborting due to
no-resumed-threads left instead of a whole-process exit as seen on
Linux:

(gdb) info threads
  Id   Target Id                                    Frame
* 1    Thread 11768.0x1bc "leader-exit-schedlock"   main () at .../gdb.threads/leader-exit-schedlock.c:55
  2    Thread 11768.0x31e0 (in kernel)              0x00007ffbb23dfc77 in ntdll!ZwWaitForWorkViaWorkerFactory () from C:/WINDOWS/SYSTEM32/ntdll.dll
  3    Thread 11768.0x2dec "sig" (in kernel)        0x00007ffbb23dc087 in ntdll!ZwReadFile () from C:/WINDOWS/SYSTEM32/ntdll.dll
  4    Thread 11768.0x2530 (in kernel)              0x00007ffbb23dfc77 in ntdll!ZwWaitForWorkViaWorkerFactory () from C:/WINDOWS/SYSTEM32/ntdll.dll
  5    Thread 11768.0x3384 "leader-exit-schedlock"  0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
  6    Thread 11768.0x3198 "leader-exit-schedlock"  0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
  7    Thread 11768.0x1ab8 "leader-exit-schedlock"  0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
  8    Thread 11768.0x3fe4 "leader-exit-schedlock"  0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
  9    Thread 11768.0x3b5c "leader-exit-schedlock"  0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
  10   Thread 11768.0x45c "leader-exit-schedlock"   0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
  11   Thread 11768.0x3724 "leader-exit-schedlock"  0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
  12   Thread 11768.0x1e44 "leader-exit-schedlock"  0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
  13   Thread 11768.0x23f0 "leader-exit-schedlock"  0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
  14   Thread 11768.0x3b80 "leader-exit-schedlock"  0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
(gdb) set scheduler-locking on
(gdb) c
Continuing.
[Thread 11768.0x1bc exited]
No unwaited-for children left.
(gdb) info threads
  Id   Target Id                                                     Frame
  2    Thread 11768.0x31e0 (exiting)                                 0x00007ffbb23dfc77 in ntdll!ZwWaitForWorkViaWorkerFactory () from C:/WINDOWS/SYSTEM32/ntdll.dll
  3    Thread 11768.0x2dec "sig" (exiting)                           0x00007ffbb23dc087 in ntdll!ZwReadFile () from C:/WINDOWS/SYSTEM32/ntdll.dll
  4    Thread 11768.0x2530 (exiting)                                 0x00007ffbb23dfc77 in ntdll!ZwWaitForWorkViaWorkerFactory () from C:/WINDOWS/SYSTEM32/ntdll.dll
  5    Thread 11768.0x3384 "leader-exit-schedlock" (exiting)         0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
  6    Thread 11768.0x3198 "leader-exit-schedlock" (exiting)         0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
  7    Thread 11768.0x1ab8 "leader-exit-schedlock" (exiting)         0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
  8    Thread 11768.0x3fe4 "leader-exit-schedlock" (exiting)         0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
  9    Thread 11768.0x3b5c "leader-exit-schedlock" (exiting)         0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
  10   Thread 11768.0x45c "leader-exit-schedlock" (exiting)          0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
  11   Thread 11768.0x3724 "leader-exit-schedlock" (exiting)         0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
  12   Thread 11768.0x1e44 "leader-exit-schedlock" (exiting)         0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
  13   Thread 11768.0x23f0 "leader-exit-schedlock" (exiting)         0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
  14   Thread 11768.0x3b80 "leader-exit-schedlock" (exiting process) 0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll

The current thread <Thread ID 1> has terminated.  See `help thread'.
(gdb)

The "(exiting)" and "(exiting process)" threads are threads for which
the kernel already reported their exit to GDB's Windows backend (via
WaitForDebugEvent), but the Windows backend hasn't yet reported the
event to infrun.  The events are still pending in windows-nat.c.

The "(exiting process)" thread above (thread 14) is the one that won
the process-exit event lottery on the Windows kernel side (because it
was the last to exit).  Continuing the (exiting) threads with
schedlock enabled should result in the Windows backend reporting that
thread's pending exit to infrun.  While continuing thread 14 should
result in the inferior exiting.  Vis:

 (gdb) c
 Continuing.
 [Thread 11768.0x31e0 exited]
 No unwaited-for children left.
 (gdb) t 14
 [Switching to thread 14 (Thread 11768.0x3b80)]
 #0  0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
 (gdb) c
 Continuing.
 [Inferior 1 (process 11768) exited normally]

The testcase continues all the (exiting) threads, one by one, and then
finally continues the (exiting process) one, expecting an inferior
exit.

The testcase also tries a similar scenario: instead immediately
continue the (exiting process) thread without continuing the others.
That should result in the inferior exiting immediately.

It is actually not guaranteed that the Windows backend will consume
all the thread and process exit events out of the kernel before the
first thread exit event is processed by infrun.  So often we will see
for example, instead:

(gdb) info threads
  Id   Target Id                                                     Frame
  2    Thread 11768.0x31e0 (exiting)                                 0x00007ffbb23dfc77 in ntdll!ZwWaitForWorkViaWorkerFactory () from C:/WINDOWS/SYSTEM32/ntdll.dll
  3    Thread 11768.0x2dec "sig" (exiting)                           0x00007ffbb23dc087 in ntdll!ZwReadFile () from C:/WINDOWS/SYSTEM32/ntdll.dll
  4    Thread 11768.0x2530 (exiting)                                 0x00007ffbb23dfc77 in ntdll!ZwWaitForWorkViaWorkerFactory () from C:/WINDOWS/SYSTEM32/ntdll.dll
  5    Thread 11768.0x3384 "leader-exit-schedlock" (exiting)         0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
  6    Thread 11768.0x3198 "leader-exit-schedlock" (exiting)         0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
  7    Thread 11768.0x1ab8 "leader-exit-schedlock" (exiting)         0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
  8    Thread 11768.0x3fe4 "leader-exit-schedlock" (exiting)         0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
  9    Thread 11768.0x3b5c "leader-exit-schedlock" (exiting)         0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
  10   Thread 11768.0x45c "leader-exit-schedlock"                    0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
  11   Thread 11768.0x3724 "leader-exit-schedlock"                   0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
  12   Thread 11768.0x1e44 "leader-exit-schedlock"                   0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
  13   Thread 11768.0x23f0 "leader-exit-schedlock" (exiting)         0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll
  14   Thread 11768.0x3b80 "leader-exit-schedlock" (exiting)         0x00007ffbb23dcb17 in ntdll!ZwWaitForMultipleObjects () from C:/WINDOWS/SYSTEM32/ntdll.dll

Above, we can't tell which thread will get the exit-process event,
there is no "(exiting process)" thread.  We do know it'll be one of
threads 10, 11, and 12, because those do not have "(exiting)".  The
Windows kernel has already decided which one it is at this point, we
just haven't seen the exit-process event yet.

This is actually what we _always_ see with "maint set target-non-stop
off" too, because in all-stop, the Windows backend only processes one
Windows debug event at a time.

So when the the test first continues all the (exiting) threads, one by
one, and then when there are no more "(exiting)" threads, if there is
no "(exiting process)" thread, it tries to exit the remaining threads,
(in the above case threads 10, 11 and 12), expecting that one of those
continues may cause an inferior exit.

On systems other than Windows, the testcase expects that continuing
the main thread results in an inferior exit.  If we find out that
isn't correct for some system, we can adjust the testcase then.

Change-Id: I52fb8de5e72bc12195ffb8bedd1d8070464332d3

7 weeks agoWindows gdb: extra thread info => show exiting
Pedro Alves [Tue, 22 Apr 2025 10:28:11 +0000 (11:28 +0100)] 
Windows gdb: extra thread info => show exiting

Now that we have easy access to each thread's last event, we can
easily include some extra info in "info threads" output related to
each thread's last event.

This patch makes us show whether the thread is exiting, or causing a
whole-process exit.  This is useful when multiple threads hit events
at the same time, and the thread/process exit events are still pending
until the user re-resumes the program.

This is similar to how linux-thread-db.c also shows "Exiting" in its
target_extra_thread_info implementation.

This will be relied on by the testcase added by the following patch.

Change-Id: I493b7ea3e14574dc972b1341eb5062fbbfda1521

7 weeks agoWindows gdb: Watchpoints while running (internal vs external stops)
Pedro Alves [Fri, 11 Apr 2025 21:10:50 +0000 (22:10 +0100)] 
Windows gdb: Watchpoints while running (internal vs external stops)

Teach the Windows target to temporarily pause all threads when we
change the debug registers for a watchpoint.  Implements the same
logic as Linux uses:

    ~~~
      /*                             (...) if threads are running when the
         mirror changes, a temporary and transparent stop on all threads
         is forced so they can get their copy of the debug registers
         updated on re-resume.   (...)  */
    ~~~

On Linux, we send each thread a SIGSTOP to step them.  On Windows,
SuspendThread itself doesn't cause any asynchronous debug event to be
reported.  However, we've implemented windows_nat_target::stop such
that it uses SuspendThread, and then queues a pending GDB_SIGNAL_0
stop on the thread.  That results in a user-visible stop, while here
we want a non-user-visible stop.  So what we do is re-use that
windows_nat_target::stop stopping mechanism, but add an external vs
internal stopping kind distinction.  An internal stop results in
windows_nat_target::wait immediately re-resuming the thread.

Note we don't make the debug registers poking code SuspendThread ->
write debug registers -> ContinueThread itself, because SuspendThread
is actually asynchronous and may take a bit to stop the thread (a
following GetThreadContext blocks until the thread is actually
suspended), and, there will be several debug register writes when a
watchpoint is set, because we have to set all of DR0, DR1, DR2, DR3,
and DR7.  Defering the actualy writes to ::wait avoids a bunch of
SuspendThread/ResumeThread sequences, so in principle should be
faster.

Change-Id: I39c2492c7aac06d23ef8f287f4afe3747b7bc53f

7 weeks agoWindows gdb: Eliminate invalidate_context
Pedro Alves [Thu, 29 Aug 2024 19:48:43 +0000 (20:48 +0100)] 
Windows gdb: Eliminate invalidate_context

After the previous patch, windows_per_inferior::invalidate_context
isn't used anymore.  Delete it.

Change-Id: I89839c2aaf3a7b0852be596feb1c345944dc8866

7 weeks agoWindows gdb: Add non-stop support
Pedro Alves [Sat, 17 May 2025 09:54:50 +0000 (10:54 +0100)] 
Windows gdb: Add non-stop support

This patch adds non-stop support to the native Windows target.

This is made possible by the ContinueDebugEvent DBG_REPLY_LATER flag:

https://learn.microsoft.com/en-us/windows/win32/api/debugapi/nf-debugapi-continuedebugevent

  Supported in Windows 10, version 1507 or above, this flag causes
  dwThreadId to replay the existing breaking event after the target
  continues. By calling the SuspendThread API against dwThreadId, a
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  debugger can resume other threads in the process and later return to
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  the breaking.
  ^^^^^^^^^^^^

The patch adds a new comment section in gdb/windows-nat.c providing an
overall picture of how all-stop / non-stop work.

Without DBG_REPLY_LATER, if we SuspendThread the thread, and then
immediately ContinueDebugThread(DBG_CONTINUE) before getting back to
the prompt, we could still have non-stop mode working, however, then
users wouldn't have a chance to decide whether to pass the signal to
the inferior the next time they resume the program, as that is done by
passing DBG_EXCEPTION_NOT_HANDLED to ContinueDebugEvent, and that has
already been called.

The patch teaches the Windows native backend to use that
DBG_REPLY_LATER flag, and also adds support for target_stop, so the
core can pause threads at its discretion.  This pausing does not use
the same mechanisms used in windows_nat_target::interrupt, as that
injects a new thread in the inferior.  Instead, for each thread the
core wants paused, it uses SuspendThread, and enqueues a pending
GDB_SIGNAL_0 stop on the thread.

Since DBG_REPLY_LATER only exists on Windows 10 and later, we only
enable non-stop mode on Windows 10 and later.

There is no displaced stepping support, but that's "just" a missed
optimization to be done later.

Cygwin signals handling was a major headache, but I managed to get it
working.  See the "Cygwin signals" description section I added at the
top of windows-nat.c.

Another interesting bit, is that the use DBG_REPLY_LATER caused one
problem with detach.  The Windows kernel re-raises any exception
previously intercepted and deferred with DBG_REPLY_LATER in the
inferior after we detach.  We need to flush those events, and suppress
those which aren't meant to be seen by the inferior (e.g.,
breakpoints, single-steps, any with matching "handle SIG nopass",
etc.), otherwise the inferior dies immediately after the detach, due
to an unhandled exception.

Change-Id: Id71aef461c43c244120635b5bedc638fe77c31fb

7 weeks agoIntroduce windows_nat::event_code_to_string
Pedro Alves [Fri, 11 Apr 2025 21:36:10 +0000 (22:36 +0100)] 
Introduce windows_nat::event_code_to_string

Instead of:

   switch (event_code)
     {
     case FOO_DEBUG_EVENT:
      DEBUG_EVENTS (..., "FOO_DEBUG_EVENT");
      ...
     case BAR_DEBUG_EVENT:
      DEBUG_EVENTS (..., "BAR_DEBUG_EVENT");
      ...

... with one DEBUG_EVENTS call per event type, log the event just once
before the switch, and introduce a new event_code_to_string function
to handle the event code to string conversion.

Do the same on GDB's and gdbserver's Windows backends.

Change-Id: Id38b7e30df182e4742f3179538de3c643cf42668

7 weeks agoWindows GDB: make windows_thread_info be private thread_info data
Pedro Alves [Thu, 10 Apr 2025 22:28:34 +0000 (23:28 +0100)] 
Windows GDB: make windows_thread_info be private thread_info data

With Windows non-stop support, we'll add support for
target_thread_events to the Windows target.

When that is supported, and the core wants to be notified of thread
exit events, the target backend does not delete the thread for which
the event is being reported.  Instead, infrun takes care of that.

That causes one problem on Windows, which is that Windows maintains
its own separate Windows threads list, in parallel with the struct
thread_info thread list maintained by the core.  In the
target_thread_events events scenario, when infrun deletes the thread,
the corresponding object in the Windows backend thread list is left
dangling, causing problems.

Fix this by eliminating the parallel thread list from the Windows
backend, instead making the windows_thread_info data by registered as
the private data associated with thread_info, like other targets do.

It also adds a all_windows_threads walker function, and associated
range and iterator classes, so that most of the Windows target code
can iterate over Windows threads without having to worry about
fetching the Windows thread data out of thread_info's private data.

Change-Id: I5058969b46e0dd238c89b6c28403c1848f083683

7 weeks agolinux-nat: Factor out get_detach_signal code to common code
Pedro Alves [Fri, 17 May 2024 19:09:18 +0000 (20:09 +0100)] 
linux-nat: Factor out get_detach_signal code to common code

The Windows target backend will want to do most of what the
get_detach_signal function in gdb/linux-nat.c does, except for the
Linux-specific bits.  This commit moves the code that is shareable to
infrun.c, so that other targets can use it too.

Change-Id: Ifaa96b4a41bb83d868079af4d47633715c0e1940

7 weeks agoWindows gdb+gdbserver: Check whether DBG_REPLY_LATER is available
Pedro Alves [Thu, 9 May 2024 11:32:53 +0000 (12:32 +0100)] 
Windows gdb+gdbserver: Check whether DBG_REPLY_LATER is available

Per
<https://learn.microsoft.com/en-us/windows/win32/api/debugapi/nf-debugapi-continuedebugevent>,
DBG_REPLY_LATER is "Supported in Windows 10, version 1507 or above, ..."

Since we support versions of Windows older than 10, we need to know
whether DBG_REPLY_LATER is available.  And we need to know this before
starting any inferior.

This adds a function that probes for support (and caches the result),
by trying to call ContinueDebugEvent on pid=0,tid=0 with
DBG_REPLY_LATER, and inspecting the resulting error.

Suggested-by: Hannes Domani <ssbssa@yahoo.de>
Suggested-by: Eli Zaretskii <eliz@gnu.org>
Approved-By: Tom Tromey <tom@tromey.com>
Change-Id: Ia27b981aeecaeef430ec90cebc5b3abdce00449d

7 weeks agoWindows gdb: Avoid writing debug registers if watchpoint hit pending
Pedro Alves [Tue, 7 May 2024 19:41:37 +0000 (20:41 +0100)] 
Windows gdb: Avoid writing debug registers if watchpoint hit pending

Several watchpoint-related testcases, such as
gdb.threads/watchthreads.exp for example, when tested with the backend
in non-stop mode, exposed an interesting detail of the Windows debug
API that wasn't considered before.  The symptom observed is spurious
SIGTRAPs, like:

  Thread 1 "watchthreads" received signal SIGTRAP, Trace/breakpoint trap.
  0x00000001004010b1 in main () at .../src/gdb/testsuite/gdb.threads/watchthreads.c:48
  48              args[i] = 1; usleep (1); /* Init value.  */

After a good amount of staring at logs and headscratching, I realized
the problem:

 #0 - It all starts with the fact that multiple threads can hit an
      event at the same time.  Say, a watchpoint for thread A, and a
      breakpoint for thread B.

 #1 - Say, WaitForDebugEvent reports the breakpoint hit for thread B
      first, then GDB for some reason decides to update debug
      registers, and continue.  Updating debug registers means writing
      the debug registers to _all_ threads, with SetThreadContext.

 #2 - WaitForDebugEvent reports the watchpoint hit for thread A.
      Watchpoint hits are reported as EXCEPTION_SINGLE_STEP.

 #3 - windows-nat checks the Dr6 debug register to check if the step
      was a watchpoint or hardware breakpoint stop, and finds that Dr6
      is completely cleared.  So windows-nat reports a plain SIGTRAP
      (given EXCEPTION_SINGLE_STEP) to the core.

 #4 - Thread A was not supposed to be stepping, so infrun reports the
      SIGTRAP to the user as a random signal.

The strange part is #3 above.  Why was Dr6 cleared?

Turns out that (at least in Windows 10 & 11), writing to _any_ debug
register has the side effect of clearing Dr6, even if you write the
same values the registers already had, back to the registers.

I confirmed it clearly by adding this hack to GDB:

  if (th->context.ContextFlags == 0)
    {
      th->context.ContextFlags = CONTEXT_DEBUGGER_DR;

      /* Get current values of debug registers.  */
      CHECK (GetThreadContext (th->h, &th->context));

      DEBUG_EVENTS ("For 0x%x (once),  Dr6=0x%llx", th->tid, th->context.Dr6);

      /* Write debug registers back to thread, same values,
 and re-read them.  */
      CHECK (SetThreadContext (th->h, &th->context));
      CHECK (GetThreadContext (th->h, &th->context));

      DEBUG_EVENTS ("For 0x%x (twice), Dr6=0x%llx", th->tid, th->context.Dr6);
    }

Which showed Dr6=0 after the write + re-read:

  [windows events] fill_thread_context: For 0x6a0 (once),  Dr6=0xffff0ff1
  [windows events] fill_thread_context: For 0x6a0 (twice), Dr6=0x0

This commit fixes the issue by detecting that a thread has a pending
watchpoint hit to report (Dr6 has interesting bits set), and if so,
avoid mofiying any debug register.  Instead, let the pending
watchpoint hit be reported by WaitForDebugEvent.  If infrun did want
to modify watchpoints, it will still be done when the thread is
eventually re-resumed after the pending watchpoint hit is reported.
(infrun knows how to gracefully handle the case of a watchpoint hit
for a watchpoint that has since been deleted.)

Change-Id: I21a3daa9e34eecfa054f0fea706e5ab40aabe70a

7 weeks agoWindows gdb: cygwin_set_dr => windows_set_dr, etc.
Pedro Alves [Wed, 17 May 2023 16:05:43 +0000 (17:05 +0100)] 
Windows gdb: cygwin_set_dr => windows_set_dr, etc.

The Windows backend functions that manipulate the x86 debug registers
are called "cygwin_foo", which is outdated, because native MinGW gdb
also uses those functions, they are not Cygwin-specific.  Rename them
to "windows_foo" to avoid confusion.

Approved-By: Tom Tromey <tom@tromey.com>
Change-Id: I46df3b44f5272adadf960da398342a3cbdb98533

7 weeks agoWindows gdb: Change serial_event management
Pedro Alves [Mon, 22 May 2023 10:29:44 +0000 (11:29 +0100)] 
Windows gdb: Change serial_event management

windows_nat_target::windows_continue, when it finds a resumed thread
that has a pending event, does:

  /* There's no need to really continue, because there's already
     another event pending.  However, we do need to inform the
     event loop of this.  */
  serial_event_set (m_wait_event);
  return TRUE;

If we have more than one pending event ready to be consumed, and,
windows_nat_target::wait returns without calling
windows_nat_target::windows_continue, which it will with the non-stop
support in the following patch, then we will miss waking up the event
loop.

This patch makes windows-nat.c manage the serial_event similarly to
how linux-nat.c does it.  Clear it on entry to
windows_nat_target::wait, and set it if there may be more events to
process.  With this, there's no need to set it from
windows_nat_target::wait_for_debug_event_main_thread, so the patch
also makes us not do it.

Change-Id: I44e1682721aa4866f1dbb052b3cfb4870fb13579

7 weeks agoWindows gdb+gdbserver: Eliminate struct pending_stop
Pedro Alves [Wed, 17 May 2023 13:34:53 +0000 (14:34 +0100)] 
Windows gdb+gdbserver: Eliminate struct pending_stop

After the previous patches, struct pending_stop only contains one
field.  So move that field into the windows_thread_info structure
directly, and eliminate struct pending_stop.

Change-Id: I7955884b3f378d8b39b908f6252d215f6568b367

7 weeks agoWindows gdb+gdbserver: Share $_siginfo reading code
Pedro Alves [Mon, 22 May 2023 17:17:54 +0000 (18:17 +0100)] 
Windows gdb+gdbserver: Share $_siginfo reading code

Both GDB and GDBserver have similar code to read the $_siginfo data.
This patch moves the bulk of it to gdb/nat/windows-nat.c so it can be
shared.

Approved-By: Tom Tromey <tom@tromey.com>
Change-Id: I58f9074caf6362274453c78ed1fc9e31249f6854

7 weeks agoAdd backpointer from windows_thread_info to windows_process_info
Pedro Alves [Fri, 30 Aug 2024 15:02:21 +0000 (16:02 +0100)] 
Add backpointer from windows_thread_info to windows_process_info

The next patch will move some duplicated code in gdb and gdbserver to
gdb/nat/windows-nat.c, where it would be convenient to get at the
Windows process info of a given Windows thread info, from within a
windows_thread_info method.

I first thought of passing down the windows_process_info pointer as
argument to the windows_thread_info method, but that looked a bit odd.
I think it looks better to just add a back pointer, so that's what
this patch does.  The following patch will then add a use of it.

I suspect this will help moving more duplicated code to
gdb/nat/windows-nat.c in the future, too.

Approved-By: Tom Tromey <tom@tromey.com>
Change-Id: I47fc0d3323be5b6f6fcfe912b768051a41910666

7 weeks agoWindows gdb+gdbserver: Make siginfo_er per-thread state
Pedro Alves [Mon, 22 May 2023 16:33:16 +0000 (17:33 +0100)] 
Windows gdb+gdbserver: Make siginfo_er per-thread state

With non-stop mode support, each thread has its own "last event", and
so printing $_siginfo should print the siginfo of the selected thread.
Likewise, with all-stop and scheduler-locking.

This patch reworks the siginfo functions in gdb/windows-nat.c and
gdbserver/win32-low.cc to reuse the exception record already saved
within each thread's 'last_event' field.

Here's an example of what you'll see after the whole non-stop series:

  (gdb) thread apply all p -pretty -- $_siginfo

  Thread 3 (Thread 2612.0x1470):
  $1 = {
    ExceptionCode = DBG_CONTROL_C,
    ExceptionFlags = 0,
    ExceptionRecord = 0x0,
    ExceptionAddress = 0x7ffd0583e929 <KERNELBASE!EncodeRemotePointer+8249>,
    NumberParameters = 0,
    {
      ExceptionInformation = {0 <repeats 15 times>},
      AccessViolationInformation = {
Type = READ_ACCESS_VIOLATION,
Address = 0x0
      }
    }
  }

  Thread 2 (Thread 2612.0x1704):
  $2 = {
    ExceptionCode = SINGLE_STEP,
    ExceptionFlags = 0,
    ExceptionRecord = 0x0,
    ExceptionAddress = 0x7ffd080ad6e4 <ntdll!ZwDelayExecution+20>,
    NumberParameters = 0,
    {
      ExceptionInformation = {0 <repeats 15 times>},
      AccessViolationInformation = {
Type = READ_ACCESS_VIOLATION,
Address = 0x0
      }
    }
  }

  Thread 1 (Thread 2612.0x434):
  $3 = {
    ExceptionCode = BREAKPOINT,
    ExceptionFlags = 0,
    ExceptionRecord = 0x0,
    ExceptionAddress = 0x7ff6f691174c <main+185>,
    NumberParameters = 1,
    {
      ExceptionInformation = {0 <repeats 15 times>},
      AccessViolationInformation = {
Type = READ_ACCESS_VIOLATION,
Address = 0x0
      }
    }
  }
  (gdb)

This was in non-stop mode, and the program originally had two threads.
Thread 1 stopped for a breakpoint, then thread 2 was manually
interrupted/paused and then single-stepped.  And then I typed Ctrl-C
in the inferior's terminal, which made Windows inject thread 3 in the
inferior, and report a DBG_CONTROL_C exception for it.

Change-Id: I5d4f1b62f59e8aef3606642c6524df2362b0fb7d

7 weeks agoWindows gdb+gdbserver: Make last_sig per-thread state
Pedro Alves [Mon, 22 May 2023 18:09:13 +0000 (19:09 +0100)] 
Windows gdb+gdbserver: Make last_sig per-thread state

With non-stop mode, each thread is controlled independently of the
others, and each thread has its own independent reason for its last
stop.

Thus, any thread-specific state that is currently per-process must be
converted to per-thread state.

This patch converts windows_process_info::last_sig to per-thread
state, moving it to windows_thread_info instead.

This adjusts both native gdb and gdbserver.

Change-Id: Ie8c673a819be445753d967afd3a6084565648448

7 weeks agoWindows gdb+gdbserver: Make current_event per-thread state
Pedro Alves [Thu, 21 Oct 2021 17:16:58 +0000 (18:16 +0100)] 
Windows gdb+gdbserver: Make current_event per-thread state

With non-stop mode, each thread is controlled independently of the
others, and each thread has its own independent reason for its last
stop.

Thus, any thread-specific state that is currently per-process must be
converted to per-thread state.

This patch converts windows_process_info::current_event, moving it to
windows_thread_info instead, renamed to last_event.

Since each thread will have its own copy of its last Windows debug
event, we no longer need the same information stored in struct
pending_stop.

Since windows_process.current_event no longer exists, we need to pass
the current event as parameter to a number of methods.

This adjusts both native gdb and gdbserver.

Change-Id: Ice09a5d932c912210608d5af25e1898f823e3c99

7 weeks agoWindows gdbserver: Eliminate soft-interrupt mechanism
Pedro Alves [Thu, 11 May 2023 17:41:27 +0000 (18:41 +0100)] 
Windows gdbserver: Eliminate soft-interrupt mechanism

I noticed that faked_breakpoint is write only.  And then I hacked
win32_process_target::request_interrupt to force it to stop threads
using the soft_interrupt_requested mechanism (which suspends threads,
and then fakes a breakpoint event in the main thread), and saw that it
no longer works -- gdbserver crashes accessing a NULL current_thread,
because fake_breakpoint_event does not switch to a thread.

This code was originally added for Windows CE, as neither
GenerateConsoleCtrlEvent nor DebugBreakProcess worked there.  Windows
CE support has since been removed.

We nowadays require Windows XP or later, and XP has DebugBreakProcess.

The soft_interrupt_requested mechanism has other problems, like for
example faking the event in the main thread, even if that thread was
previously stopped, due to scheduler-locking.

A following patch will add a similar mechanism stopping all threads
with SuspendThread to native GDB, for non-stop mode, which doesn't
have these problems.  It's different enough from this old code that I
think we should just rip the old code out, and reimplement it from
scratch (based on gdb's version) when we need it.

Approved-By: Tom Tromey <tom@tromey.com>
Change-Id: I89e98233a9c40c6dcba7c8e1dacee08603843fb1

7 weeks agoWindows gdb: Enable "set scheduler-locking on"
Pedro Alves [Thu, 11 May 2023 22:07:33 +0000 (23:07 +0100)] 
Windows gdb: Enable "set scheduler-locking on"

Surprisingly (to me), enabling scheduler locking on Windows currently
fails:

 (gdb)
 set scheduler-locking on
 Target 'native' cannot support this command.

The backend itself does support scheduler-locking.  This patch
implements windows_nat_target::get_thread_control_capabilities so that
the core knows schedlocking works for this target.

Approved-By: Tom Tromey <tom@tromey.com>
Change-Id: Ie762d3768fd70e4ac398c8bcc03c3213bfa26a6a

7 weeks agoWindows gdbserver: Fix scheduler-locking
Pedro Alves [Thu, 11 May 2023 11:15:36 +0000 (12:15 +0100)] 
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

7 weeks agoWindows gdb: Can't pass signal to thread other than last stopped thread
Pedro Alves [Thu, 11 May 2023 11:27:27 +0000 (12:27 +0100)] 
Windows gdb: Can't pass signal to thread other than last stopped thread

Passing a signal to a thread other than the one that last reported an
event will be later possible with DBG_REPLY_LATER and the Windows
backend working in non-stop mode.

With an all-stop backend that isn't possible, so at least don't
incorrectly consider passing DBG_EXCEPTION_NOT_HANDLED if the thread
that we're going to call ContinueDebugEvent for is not the one that
the user issued "signal SIG" on.

Change-Id: I27092ecfbf0904ebce02dff07d9104d22f3d8f0e

7 weeks agoWindows gdb+gdbserver: Introduce get_last_debug_event_ptid
Pedro Alves [Thu, 11 May 2023 11:27:27 +0000 (12:27 +0100)] 
Windows gdb+gdbserver: Introduce get_last_debug_event_ptid

This will be used in subsequent patches to avoid using
DBG_EXCEPTION_NOT_HANDLED on the wrong thread.

Change-Id: I32915623b5036fb902f9830ce2d6f0b1ccf1f5cf

7 weeks agoWindows gdb+gdbserver: Elim desired_stop_thread_id / rework pending_stops
Pedro Alves [Tue, 7 May 2024 15:04:50 +0000 (16:04 +0100)] 
Windows gdb+gdbserver: Elim desired_stop_thread_id / rework pending_stops

windows_process.desired_stop_thread_id doesn't work for non-stop, as
in that case every thread will have its own independent
WaitForDebugEvent event.

Instead, detect whether we have been reported a stop that was not
supposed to be reported by simply checking whether the thread that is
reporting the event is suspended.  This is now easilly possible since
each thread's suspend state is kept in sync with whether infrun wants
the thread executing or not.

windows_process.desired_stop_thread_id was also used as thread to pass
to windows_continue.  However, we don't really need that either.
windows_continue is used to update the thread's registers, unsuspend
them, and then finally call ContinueDebugEvent.  In most cases, we
only need the ContinueDebugEvent step, so we can convert the
windows_continue calls to continue_last_debug_event_main_thread calls.
The exception is when we see a thread creation event -- in that case,
we need to update the debug registers of the new thread.  We can use
continue_one_thread for that.

Since the pending stop is now stored in windows_thread_info,
get_windows_debug_event needs to avoid reaching the bottom code if
there's no thread associated with the event anymore (i.e.,
EXIT_THREAD_DEBUG_EVENT / EXIT_PROCESS_DEBUG_EVENT).

I considered whether it would be possible to keep the pending_stop
handling code shared in gdb/nat/windows-nat.c, in this patch and
throughout the series, but I conclused that it isn't worth it, until
gdbserver is taught about async and non-stop as well.

The pending_stop struct will eventually be eliminated later down the
series.

Change-Id: Ib7c8e8d16edc0900b7c411976c5d70cf93931c1c

7 weeks agoWindows gdb: Pending stop and current_event
Pedro Alves [Thu, 18 May 2023 18:13:45 +0000 (19:13 +0100)] 
Windows gdb: Pending stop and current_event

I noticed that windows_nat_target::get_windows_debug_event does not
copy the event recorded in pending stop to
windows_process.current_event.  This seems like an oversight.  The
equivalent code in gdbserver/win32-low.cc does copy it.

This change will become moot later in the series, but I figure its
still clearer to correct the buglet as preparatory patch.

Approved-By: Tom Tromey <tom@tromey.com>
Change-Id: Ic8935d854cf67a3a3c4edcbc1a1e8957b800d907

7 weeks agoWindows gdb: Factor code out of windows_nat_target::windows_continue
Pedro Alves [Tue, 9 May 2023 19:34:50 +0000 (20:34 +0100)] 
Windows gdb: Factor code out of windows_nat_target::windows_continue

This factors some code out of windows_nat_target::windows_continue
into a new windows_continue_one function.  This will make the
following patch easier to read (as well as the resulting code itself).

Approved-By: Tom Tromey <tom@tromey.com>
Change-Id: I14a0386b1b8b03015e86273060af173b5130e375

7 weeks agoWindows gdb: Introduce windows_continue_flags
Pedro Alves [Thu, 21 Oct 2021 17:16:58 +0000 (18:16 +0100)] 
Windows gdb: Introduce windows_continue_flags

windows_continue already has two boolean parameters:

  (..., int killed, bool last_call = false)

A patch later in the series would need a third.  Instead, convert
windows_continue to use an optional enum-flags parameter instead of
multiple booleans.

Approved-By: Tom Tromey <tom@tromey.com>
Change-Id: I17c4d8a12b662190f972c380f838cb3317bd2e1e

7 weeks agoWindows gdb: Introduce continue_last_debug_event_main_thread
Pedro Alves [Thu, 21 Oct 2021 17:16:58 +0000 (18:16 +0100)] 
Windows gdb: Introduce continue_last_debug_event_main_thread

We have code using do_synchronously to call continue_last_debug_event,
and later patches in the series would need to add the same code in few
more places.  Factor it out to a continue_last_debug_event_main_thread
function so these other places in future patches can just call it.

In v2:
 - Fix context_str not used in the body of the method.

Change-Id: I945e668d2b3daeb9de968219925a7b3c7c7ce9ed

7 weeks agoWindows gdb+gdbserver: Move suspending thread to when returning event
Pedro Alves [Tue, 9 May 2023 09:27:04 +0000 (10:27 +0100)] 
Windows gdb+gdbserver: Move suspending thread to when returning event

The current code suspends a thread just before calling
GetThreadContext.  You can only call GetThreadContext if the thread is
suspended.  But, after WaitForDebugEvent, all threads are implicitly
suspended.  So I don't think we even needed to call SuspendThread
explictly at all before our GetThreadContext calls.

However, suspending threads when we're about to present a stop to gdb
simplifies adding non-stop support later.  This way, the windows
SuspendThread state corresponds to whether a thread is suspended or
resumed from the core's perspective.  Curiously, I noticed that Wine's
winedbg does something similar:
https://github.com/wine-mirror/wine/blob/234943344f7495d1e072338f0e06fa2d5cbf0aa1/programs/winedbg/gdbproxy.c#L651

This makes it much easier to reason about a thread's suspend state,
and simplifies adding non-stop mode later on.

Change-Id: Ifd6889a8afc041fad33cd1c4500e38941da6781b

7 weeks agoWindows gdb: Simplify windows_nat_target::wait
Pedro Alves [Thu, 11 May 2023 12:16:09 +0000 (13:16 +0100)] 
Windows gdb: Simplify windows_nat_target::wait

The logic in windows_nat_target::wait, where we decide what to do
depending on the result from get_windows_debug_event is harder to
grasp than it looks.

It is not easy to tell what should happen when in async mode
get_windows_debug_event returns that there's no event to process.

And then, if get_windows_debug_event returns null_ptid /
TARGET_WAITKIND_SPURIOUS, then we need to issue a ContinueDebugEvent.

There's also this comment in windows_nat_target::wait, which we're not
really implementing today:

~~~~
  /* We loop when we get a non-standard exception rather than return
     with a SPURIOUS because resume can try and step or modify things,
     which needs a current_thread->h.  But some of these exceptions mark
     the birth or death of threads, which mean that the current thread
     isn't necessarily what you think it is.  */
~~~~

This patch changes things a bit so that the code is more obvious:

 - look at the status kind, instead of ptid_t.

 - add an explicit early return case for no-event.

 - add an explicit case for TARGET_WAITKIND_SPURIOUS.

 - with those, we no longer need to handle the case of find_thread not
   finding a thread, so we can drop one indentation level.

Change-Id: I76c41762e1f893a7ff23465856ccf6a44af1f0e7

7 weeks agoWindows gdb+gdbserver: Eliminate windows_process_info::thread_rec
Pedro Alves [Tue, 9 May 2023 09:18:09 +0000 (10:18 +0100)] 
Windows gdb+gdbserver: Eliminate windows_process_info::thread_rec

After the previous patches, thread_rec is no longer called anywhere.
Delete it.

Approved-By: Tom Tromey <tom@tromey.com>
Change-Id: Ib14e5807fc427e1c3c4a393a9ea7b36b6047a2d7

7 weeks agoWindows gdb+gdbserver: Eliminate DONT_SUSPEND
Pedro Alves [Tue, 9 May 2023 09:13:08 +0000 (10:13 +0100)] 
Windows gdb+gdbserver: Eliminate DONT_SUSPEND

There's a single call to thread_rec(DONT_SUSPEND), in
windows_process_info::handle_exception.

In GDB, the windows-nat.c thread_rec implementation avoids actually
calling SuspendThread on the event thread by doing:

               th->suspended = -1;

I am not exactly sure why, but it kind of looks like it is done as an
optimization, avoiding a SuspendThread call?  It is probably done for
the same reason as the code touched in the previous patch avoided
suspending the event thread.

This however gets in the way of non-stop mode, which will really want
to SuspendThread the event thread for DBG_REPLY_LATER.

In gdbserver's thread_rec implementation DONT_SUSPEND is ignored, and
thread_rec actually always suspends, which really suggests that
SuspendThread on the event thread is really not a problem.  I really
can't imagine why it would be.

DONT_SUSPEND invalidates the thread's context, but there is no need to
invalidate the context when we get an event for a thread, because we
invalidate it when we previously resumed the thread.

So, we can just remove the thread_rec call from
windows_process_info::handle_exception.  That's what this patch does.

Approved-By: Tom Tromey <tom@tromey.com>
Change-Id: I0f328542bda6d8268814ca1ee4ae7a478098ecf2

7 weeks agoWindows gdb+gdbserver: Eliminate thread_rec(INVALIDATE_CONTEXT) calls
Pedro Alves [Mon, 8 May 2023 20:36:28 +0000 (21:36 +0100)] 
Windows gdb+gdbserver: Eliminate thread_rec(INVALIDATE_CONTEXT) calls

Replace thread_rec(INVALIDATE_CONTEXT) calls with find_thread, and
invalidate_context / suspend calls in the spots that might need those.

I don't know why does the INVALIDATE_CONTEXT implementation in GDB
avoid suspending the event thread:

case INVALIDATE_CONTEXT:
  if (ptid.lwp () != current_event.dwThreadId)
    th->suspend ();

Checks for a global "current_event" get in the way of non-stop support
later in the series, as each thread will have its own "last debug
event".  Regardless, it should be fine to suspend the event thread.
As a data point, the GDBserver implementation always suspends.  So
this patch does not try to avoid suspending the event thread on the
native side either.

Approved-By: Tom Tromey <tom@tromey.com>
Change-Id: I8d2f0a749d23329956e62362a7007189902dddb5

7 weeks agoWindows gdb: Eliminate reload_context
Pedro Alves [Tue, 30 Apr 2024 14:33:58 +0000 (15:33 +0100)] 
Windows gdb: Eliminate reload_context

We don't need reload_context, because we can get the same information
out of th->context.ContextFlags.  If ContextFlags is zero, then we
need to fetch the context out of the inferior thread.  This is what
gdbserver does too.

Approved-By: Tom Tromey <tom@tromey.com>
Change-Id: Ied566037c81383414c46c77713bdd1aec6377b23

7 weeks agoWindows gdb: handle_output_debug_string return type
Pedro Alves [Mon, 8 May 2023 18:40:50 +0000 (19:40 +0100)] 
Windows gdb: handle_output_debug_string return type

handle_output_debug_string returns a Windows thread id, so it should
return a DWORD instead of an int.

Approved-By: Tom Tromey <tom@tromey.com>
Change-Id: Icbd071a1a37de8a0fc8918bd13254a8d40311e32

7 weeks agoWindows gdb+gdbserver: New find_thread, replaces thread_rec(DONT_INVALIDATE_CONTEXT)
Pedro Alves [Mon, 8 May 2023 16:09:58 +0000 (17:09 +0100)] 
Windows gdb+gdbserver: New find_thread, replaces thread_rec(DONT_INVALIDATE_CONTEXT)

The goal of the next few patches is to eliminate thread_rec
completely.  This is the first patch in that effort.

thread_rec(DONT_INVALIDATE_CONTEXT) is really just a thread lookup
with no side effects, so this adds a find_thread function that lets
you do that.

Approved-By: Tom Tromey <tom@tromey.com>
Change-Id: Ie486badce00e234b10caa478b066c34537103e3f

7 weeks agoWindows gdb: Eliminate global current_process.dr[8] global
Pedro Alves [Tue, 2 May 2023 19:42:35 +0000 (20:42 +0100)] 
Windows gdb: Eliminate global current_process.dr[8] global

current_process.dr needs to be per-thread for non-stop.  Actually, it
doesn't even need to exist at all.  We have x86_debug_reg_state
recording intent, and then the
cygwin_get_dr/cygwin_get_dr6/cygwin_get_dr7 functions are registered
as x86_dr_low_type vector functions, so they should return the current
value in the inferior's registers.  See this comment in x86-dregs.c:

~~~
  /* In non-stop/async, threads can be running while we change the
     global dr_mirror (and friends).  Say, we set a watchpoint, and
     let threads resume.  Now, say you delete the watchpoint, or
     add/remove watchpoints such that dr_mirror changes while threads
     are running.  On targets that support non-stop,
     inserting/deleting watchpoints updates the global dr_mirror only.
     It does not update the real thread's debug registers; that's only
     done prior to resume.  Instead, if threads are running when the
     mirror changes, a temporary and transparent stop on all threads
     is forced so they can get their copy of the debug registers
     updated on re-resume.  Now, say, a thread hit a watchpoint before
     having been updated with the new dr_mirror contents, and we
     haven't yet handled the corresponding SIGTRAP.  If we trusted
     dr_mirror below, we'd mistake the real trapped address (from the
     last time we had updated debug registers in the thread) with
     whatever was currently in dr_mirror.  So to fix this, dr_mirror
     always represents intention, what we _want_ threads to have in
     debug registers.  To get at the address and cause of the trap, we
     need to read the state the thread still has in its debug
     registers.

     In sum, always get the current debug register values the current
     thread has, instead of trusting the global mirror.  If the thread
     was running when we last changed watchpoints, the mirror no
     longer represents what was set in this thread's debug
     registers.  */
~~~

This patch makes the Windows native target follow that model as well.

I don't understand why would windows_nat_target::resume want to call
SetThreadContext itself.  That duplicates things as it is currently
worrying about setting the debug registers as well.  windows_continue
also does that, and windows_nat_target::resume always calls it.  So
this patch simplifies windows_nat_target::resume too.

Tromey pointed out that gdb/2388 mentioned in the code being removed
was moved to https://sourceware.org/bugzilla/show_bug.cgi?id=9493 in
the bugzilla migration.  I tried the reproducer mentioned there, and
it still works correctly.

Change-Id: Id762d0faa7d5e788402f2ff5adad5352447a7526

7 weeks agoWindows gdb: Dead code in windows_nat_target::do_initial_windows_stuff
Pedro Alves [Tue, 2 May 2023 19:42:35 +0000 (20:42 +0100)] 
Windows gdb: Dead code in windows_nat_target::do_initial_windows_stuff

In windows_nat_target::do_initial_windows_stuff, there's no point in
setting windows_process.current_event.dwProcessId.  It's a nop, given
the following memset.

Approved-By: Tom Tromey <tom@tromey.com>
Change-Id: I2fe460341b598ad293ea60d5f702b10cefc30711

7 weeks agothread_info::executing+resumed -> thread_info::internal_state
Pedro Alves [Wed, 19 Feb 2025 14:37:39 +0000 (14:37 +0000)] 
thread_info::executing+resumed -> thread_info::internal_state

While working on Windows non-stop support, I ran into a
very-hard-to-track-down bug.

The problem turned out to be that
infrun.c:proceed_resume_thread_checked resumed an already-executing
thread because the thread was marked as "executing=true,
resumed=false", and that function only skips resuming threads that are
marked resumed=true.  The consequence was that GDB corrupted the
registers of the Windows DLL loader threads, eventually leading to a
GDB+inferior deadlock.

Originally, the "resumed" flag was only ever set when infrun decided
is was ready to process a thread's pending wait status.  infrun has
since evolved to set the resumed flag when we set a thread's executing
flag too.  We are not always consistent throughout in guaranteeing
that a thread is marked resumed=true whenever it is marked
executing=true, though.  For instance, no target code that supports
non-stop mode (linux-nat, remote, and windows-nat with this series) is
making sure that new threads are marked resumed=true when they are
added to the thread list.  They are only marked as {state=running,
executing=true}, the "resumed" flag is not touched.

Making proceed_resume_thread_checked check thr->executing() in
addition to thr->resumed(), feels like papering over a combination of
states that shouldn't happen nowadays.

OTOH, having to have the target backends mark new threads as
resumed=true just feels like too many different states (three) to set:

  add_thread (...);
  set_running (...);
  set_executing (...);
  set_resumed (...);

Yuck.  I think we can do better.

We really have too many "state tracking" flags in a thread.
Basically:

 - whether a thread is "running/stopped/exited" (from the user's
   perspective).  This is the thread_info::state field.

 - whether a thread is "executing" (infrun asked the target to set the
   thread executing).  This is thread_info::executing().

 - whether a thread is "resumed" (infrun wants the thread to be
   resumed, but maybe can't yet because the thread has a pending wait
   status).  This is thread_info::resumed()

"running", "executing", and "resumed" are almost synonyms, so this can
be highly confusing English-wise too.

For "running" vs "executing", in comments, we tipically need to
explain that "running/stopped/exited" is for the user/frontend
perspective, while "executing true/false" is for gdb's internal run
control.

(Also, "executing or not" can also mean something else in GDB's
codebase -- "target has execution" does not mean that threads are
actually running right now -- it's a test for whether we have a live
process vs a core dump!)

One simplification we can do that avoids this running vs executing
ambiguity is to replace the "executing" field with an "internal_state"
field, similar to the thread_info::state field, and make that new
internal_state field reuse the same enum thread_state type that is
used by thread_info::state.  Like:

  struct thread_info
  {
  ...
    /* Frontend/public/external/user view of the thread state.  */
    enum thread_state m_state = THREAD_STOPPED;

    /* The thread's internal state.  When the thread is stopped
       internally while handling an internal event, like a software
       single-step breakpoint, the internal state will be
       THREAD_STOPPED, but the external state will still be
       THREAD_RUNNING.  */
    enum thread_state m_internal_state = THREAD_STOPPED;
  };

(Assume we'd add state() and internal_state() getters.)

With that, every check for thr->executing() is replaced with a
'thr->internal_state() == THREAD_RUNNING' check, and the code is
clearer by design.  There is no confusion between "running" vs
"executing" any more, because they now mean the exact same thing.
Instead, we say e.g., 'thread has (user) state "running", and internal
state "stopped"'.  Or simpler, 'thread is running (from the user's
perspective), but internally stopped'.  That is after all what we
would way in comments today already.

That still leaves the 'resumed' flag, though.  That's the least
obvious one.  Turns out we can get rid of it, and make it a new state
tracked by thread_info::internal_state.  That is, we make
internal_state have its own enumeration type (decoupled from
thread_info::state's type), and convert the resumed true/false flag to
a new enumerator of this new enumeration.  Like so:

  enum thread_int_state
  {
    THREAD_INT_STOPPED,
    THREAD_INT_RUNNING,
 +   THREAD_INT_RESUMED_PENDING_STATUS,
    THREAD_INT_EXITED,
  };

That is what this patch does.  So in summary, we go from:

 thread_info::state {THREAD_STOPPED, THREAD_RUNNING, THREAD_EXITED}
 thread_info::executing {false, true}
 thread_info::resumed {false, true}

to:

 thread_info::state {THREAD_STOPPED, THREAD_RUNNING, THREAD_EXITED}
 thread_info::internal_state {THREAD_INT_STOPPED, THREAD_INT_RUNNING,
                              THREAD_INT_RESUMED_PENDING_STATUS,
      THREAD_INT_EXITED}

The patch adds getters/setters for both (user) state and
internal_state, and adds assertions around state transitions, ensuring
that internal_state doesn't get out of sync with
thread::have_pending_wait_status().  It also adds an assertion to
clear_proceed_status_thread, making sure that we don't try to proceed
a thread that is already running.  Turns out that catches
attach_command calling init_wait_for_inferior too late, after
attaching has already created already-running threads.

The code that adds/removes threads from the proc_target's
resumed_with_pending_wait_status list is all centralized within
thread_info::set_internal_state, when we switch to/from the
resumed-pending-status state.  With the assertions in place, it should
be impossible to end up with a THREAD_INT_RUNNING thread with a
pending status.

The thread.c:set_running, thread.c:set_executing, thread.c:set_resumed
global functions are all gone, replaced with new thread.c:set_state
and thread.c:set_internal_state functions.

Tested on x86_64-linux-gnu, native and gdbserver.

Change-Id: I4f5097d68f4694d44e1ae23fea3e9bce45fb078c

7 weeks agoinfrun: Split currently_stepping, fix sw watchpoints issue
Pedro Alves [Fri, 16 May 2025 20:05:17 +0000 (21:05 +0100)] 
infrun: Split currently_stepping, fix sw watchpoints issue

The gdb.base/watchpoint.exp on Windows with non-stop support added
(later in the series) exposed an issue with the currently_stepping
logic when tested with software watchpoints.

The issue only happens when:

 - You have multiple threads.  gdb.base/watchpoint.exp exposed it on
   Windows because there the OS always spawns a few extra threads.

 - Displaced stepping is not available.  The Windows non-stop work
   does not implement displaced stepping yet.  That is left as an
   optimization for later.

 - The target backend is working in non-stop mode.

I've written a new test that exposes the issue on GNU/Linux as well
(on hardware single-step targets, like x86-64).  There, we see:

 continue
 Continuing.
 ../../src/gdb/infrun.c:2918: internal-error: resume_1: Assertion `!(thread_has_single_step_breakpoints_set (tp) && step)' failed.
 A problem internal to GDB has been detected,
 further debugging may prove unreliable.
 ----- Backtrace -----
 FAIL: gdb.threads/sw-watchpoint-step-over-bp-with-threads.exp: target-non-stop=on: displaced-stepping=off: continue until exit (GDB internal error)

Currently, software watchpoints are implemented by forcing
single-stepping.  That is done by currently_stepping returning true
when we have a software watchpoint.  proceed calls resume, which calls
resume_1, which then ends up always requesting a single-step resume,
even if the higher layers wanted a continue.

Now, if you set a software watchpoint, and then continue the program,
and there's a breakpoint at the current PC, GDB needs to step over
that breakpoint first.  If displaced stepping is not available, then
GDB temporarily pauses all threads, removes the breakpoint,
single-steps the thread that needs to move past the breakpoint, and
then finally, reinserts the breakpoint, and restarts all threads
again.  That last restarting step happens in the restart_threads
infrun function.

restart_threads iterates over all threads trying to restart them one
by one.  There, we have:

      if (currently_stepping (tp))
  {
    infrun_debug_printf ("restart threads: [%s] was stepping",
         tp->ptid.to_string ().c_str ());

but, what if TP is actually a new thread that hasn't yet ever set
stepping?  currently_stepping still returns true, due to the software
watchpoint, and we end up in keep_going_stepped_thread, here:

  if (tp->stop_pc () != tp->prev_pc)
    {
      ptid_t resume_ptid;

      infrun_debug_printf ("expected thread advanced also (%s -> %s)",
   paddress (current_inferior ()->arch (), tp->prev_pc),
   paddress (current_inferior ()->arch (),
     tp->stop_pc ()));

... because prev_pc was stale at that point (we had no reason to
update it earlier).  E.g. on Windows we see something like:

  [infrun] restart_threads: start: event_thread=1867996.1867996.0, inf=-1
    [infrun] restart_threads: restart threads: [1867996.1867996.0] is event thread
    [infrun] restart_threads: restart threads: [1867996.1868003.0] was stepping
    [infrun] keep_going_stepped_thread: resuming previously stepped thread
    [infrun] keep_going_stepped_thread: expected thread advanced also (0 -> 0x7ffff7ce57f8)
    [infrun] clear_step_over_info: clearing step over info
    [infrun] do_target_resume: resume_ptid=1867996.1868003.0, step=0, sig=GDB_SIGNAL_0

On GNU/Linux, we may see:

    [infrun] keep_going_stepped_thread: expected thread advanced also (0x7ffff7d2683d -> 0x7ffff7ce57f8)

there prev_pc might have been updated on an earlier proceed call,
which makes the issue harder to see, but it is stale too here.

That means we insert a single-step breakpoint at the current PC, and
continue the thread, with target_resume directly, asking for a normal
continue.

Eventually, something causes a user-visible stop.  For example, the
software watchpoint triggers.  That makes GDB stop all threads.

Now, if the user re-resumes the program, say, with "continue", we fail
this assertion in resume_1 coming from proceed:

  /* If STEP is set, it's a request to use hardware stepping
     facilities.  But in that case, we should never
     use singlestep breakpoint.  */
  gdb_assert (!(thread_has_single_step_breakpoints_set (tp) && step));

"step" is true because currently_stepping returns true since we have a
software watchpoint.  And the thread has a single-step breakpoint
installed from earlier, because of that code mentioned above, in
keep_going_stepped_thread reached from restart_threads.

This patch fixes the root cause -- the currently_stepping call in
restart_threads returned true for a thread that has never set stepping
in the first place.  This is because currently_stepping really serves
two purposes currently:

  #1 - for a thread that we are about to resume, should we set it
       stepping?

  #2 - for a thread that just stopped, was it stepping before?

The fix is thus to decouple those two aspects:

  - for #1, we simply rename currently_stepping to should_step.

  - for #2, we record whether the thread was stepping before in a new
    currently_stepping flag in thread_info.

As mentioned, there's a new testcase included.  I tested this on
x86-64 GNU/Linux, native and gdbserver, and on Windows x64 with the
non-stop series.  The assertion triggers on all of those with the fix,
and is fixed by this patch on all of those, too.

Change-Id: Id7aa00692531450695771f8110893cc25626262f

7 weeks agoinfrun: Remove unnecessary currently_stepping call
Pedro Alves [Mon, 10 Mar 2025 17:30:52 +0000 (17:30 +0000)] 
infrun: Remove unnecessary currently_stepping call

There's one unnecessary check for currently_stepping in
handle_signal_stop that can be removed.  It is unnecessary because
currently_stepping is only ever called if
ecs->event_thread->control.trap_expected is true, and then if it is
true, then currently_stepping always returns true too.

Change-Id: I7b07bc62e8570333d2e4856d2e55ae6e58f8260c

7 weeks agoAdd test for continuing with some threads running
Pedro Alves [Fri, 24 Jan 2025 18:10:50 +0000 (18:10 +0000)] 
Add test for continuing with some threads running

This testcase would have helped catch some issues I ran into while
working on the Windows non-stop support.

It tests continuing all threads in all-stop mode when at least one
thread is already running.

Change-Id: Ie8cd5c67502aed3c3b159d5eb5eeedee2f84eeef

7 weeks agoAdjust gdb.cp/cpexprs.exp for Cygwin
Pedro Alves [Mon, 9 Jun 2025 14:41:28 +0000 (15:41 +0100)] 
Adjust gdb.cp/cpexprs.exp for Cygwin

Running gdb.cp/cpexprs.exp on x86-64 GNU/Linux, I see:

 break base::~base
 Breakpoint 117 at 0x555555555d90: file .../src/gdb/testsuite/gdb.cp/cpexprs.cc, line 135.
 (gdb) continue
 Continuing.

 Breakpoint 117, base::~base (this=0x7fffffffd0f8, __in_chrg=<optimized out>) at .../src/gdb/testsuite/gdb.cp/cpexprs.cc:135
 135   ~base (void) { } // base::~base
 (gdb) PASS: gdb.cp/cpexprs.exp: continue to base::~base

Here, the breakpoint only got one location because both the in-charge
and the not-in-charge dtors are identical and got the same address:

 $ nm -A ./testsuite/outputs/gdb.cp/cpexprs/cpexprs| c++filt |grep "~base"
 ./testsuite/outputs/gdb.cp/cpexprs/cpexprs:0000000000001d84 W base::~base()
 ./testsuite/outputs/gdb.cp/cpexprs/cpexprs:0000000000001d84 W base::~base()

While on Cygwin, we get two locations for the same breakpoint, which
the testcase isn't expecting:

 break base::~base
 Breakpoint 117 at 0x100402678: base::~base. (2 locations)
 (gdb) continue
 Continuing.

 Thread 1 "cpexprs" hit Breakpoint 117.1, base::~base (this=0x7ffffcaf8, __in_chrg=<optimized out>) at .../src/gdb/testsuite/gdb.cp/cpexprs.cc:135
 135   ~base (void) { } // base::~base
 (gdb) FAIL: gdb.cp/cpexprs.exp: continue to base::~base

We got two locations because the in-charge and the not-in-charge dtors
have different addresses:

 $ nm -A outputs/gdb.cp/cpexprs/cpexprs.exe | c++filt | grep "~base"
 outputs/gdb.cp/cpexprs/cpexprs.exe:0000000100402680 T base::~base()
 outputs/gdb.cp/cpexprs/cpexprs.exe:0000000100402690 T base::~base()

On Cygwin, we also see the typical failure due to not expecting the
inferior to be multi-threaded:

  (gdb) continue
  Continuing.
  [New Thread 628.0xe08]

  Thread 1 "cpexprs" hit Breakpoint 200, test_function (argc=1, argv=0x7ffffcc20) at .../src/gdb/testsuite/gdb.cp/cpexprs.cc:336
  336   derived d;
  (gdb) FAIL: gdb.cp/cpexprs.exp: continue to test_function for policyd3::~policyd

Both issues are fixed by this patch, and now the testcase passes
cleanly on Cygwin, for me.

Reviewed-By: Keith Seitz <keiths@redhat.com>
Change-Id: If7eb95d595f083f36dfebf9045c0fc40ef5c5df1

7 weeks agogdb.threads/thread-execl, don't re-exec forever
Pedro Alves [Fri, 23 Jun 2023 20:01:39 +0000 (21:01 +0100)] 
gdb.threads/thread-execl, don't re-exec forever

I noticed on Cygwin, gdb.thread/thread-execl.exp would hang, (not that
surprising since we can't follow-exec on Cygwin).  Looking at the
process list running on the machine, we end up with a thread-execl.exe
process constantly respawning another process [1].

We see the same constant-reexec if we launch gdb.thread/thread-execl
manually on the shell:

 $ ./testsuite/outputs/gdb.threads/thread-execl/thread-execl
 # * doesn't exit, constantly re-execing *
 ^C

Prevent this leftover constantly-re-execing scenario by making the
testcase program only exec once.  We now get:

  $ ./testsuite/outputs/gdb.threads/thread-execl/thread-execl
  $   # exits immediately after one exec.

On Cygwin, the testcase now fails reasonably quickly, and doesn't
leave stale processes behind.

Still passes cleanly on x86-64 GNU/Linux.

[1] Cygwin's exec emulation spawns a new Windows process for the new
image.

Approved-By: Andrew Burgess <aburgess@redhat.com>
Change-Id: I0de1136cf2ef7e89465189bc43489a2139a80efb

7 weeks agoSupport core dumping testcases with Cygwin's dumper
Pedro Alves [Mon, 26 Jun 2023 12:56:26 +0000 (13:56 +0100)] 
Support core dumping testcases with Cygwin's dumper

Cygwin supports dumping ELF cores via a dumper.exe utility, see
https://www.cygwin.com/cygwin-ug-net/dumper.html.

When I run a testcase that has the "kernel" generate a corefile, like
gdb.base/corefile.exp, Cygwin invokes dumper.exe correctly and
generates an ELF core file, however, the testsuite doesn't find the
generated core:

 Running /home/alves/gdb/src/gdb/testsuite/gdb.base/corefile.exp ...
 WARNING: can't generate a core file - core tests suppressed - check ulimit -c

The file is correctly put under $coredir, e.g., like so:

  outputs/gdb.base/corefile/coredir.8926/corefile.exe.core

The problem is in this line in core_find:

  foreach i "${coredir}/core ${coredir}/core.coremaker.c ${binfile}.core" {

Note that that isn't looking for "${binfile}.core" inside
${coredir}...  That is fixed in this patch.

However, that still isn't sufficient for Cygwin + dumper, as in that
case the core is going to be called foo.exe.core, not foo.core.  Fix
that by looking for foo.exe.core in the core dir as well.

With this, gdb.base/corefile.exp and other tests that use core_find
now run.  They don't pass cleanly, but at least now they're exercised.

Approved-By: Tom Tromey <tom@tromey.com>
Change-Id: Ic807dd2d7f22c5df291360a18c1d4fbbbb9b993e

7 weeks agoAdjust gdb.base/sigall.exp for Cygwin
Pedro Alves [Mon, 26 Jun 2023 20:03:32 +0000 (21:03 +0100)] 
Adjust gdb.base/sigall.exp for Cygwin

The gdb.base/sigall.exp testcase has many FAILs on Cygwin currently.

From:

 Thread 1 "sigall" received signal SIGPWR, Power fail/restart.
 0x00007ffeac9ed134 in ntdll!ZwWaitForSingleObject () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
 (gdb) FAIL: gdb.base/sigall.exp: get signal LOST

we see two issues.  The test is expecting "Program received ..." which
only appears if the inferior is single-threaded.  All Cygwin inferiors
are multi-threaded, because both Windows and the Cygwin runtime spawn
a few helper threads.

And then, SIGLOST is the same as SIGPWR on Cygwin.  The testcase
already knows to treat them the same on SPARC64 GNU/Linux.  We just
need to extend the relevant code to treat Cygwin the same.

With this, the test passes cleanly on Cygwin.

Approved-By: Tom Tromey <tom@tromey.com>
Change-Id: Ie3553d043f4aeafafc011347b6cb61ed58501667

7 weeks agoAdjust gdb.arch/amd64-watchpoint-downgrade.exp for Cygwin
Pedro Alves [Tue, 5 Sep 2023 14:06:20 +0000 (15:06 +0100)] 
Adjust gdb.arch/amd64-watchpoint-downgrade.exp for Cygwin

The gdb.arch/amd64-watchpoint-downgrade.exp testcase is assuming the
output of debugging a single-thread program, like so, on e.g.,
GNU/Linux:

 starti
 Starting program: .../gdb.arch/amd64-watchpoint-downgrade/amd64-watchpoint-downgrade
 warning: watchpoint 1 downgraded to software watchpoint

 Program stopped.
 0x00007ffff7fe32b0 in _start () from /lib64/ld-linux-x86-64.so.2

However, on Cygwin, where all inferiors are multi-threaded (because
both Windows and the Cygwin runtime spawn a few helper threads), we
get:

 starti
 Starting program: .../gdb.arch/amd64-watchpoint-downgrade/amd64-watchpoint-downgrade
 [New Thread 4652.0x17e4]
 warning: watchpoint 1 downgraded to software watchpoint

 Thread 1 stopped.
 0x00007ffbfc1c0911 in ntdll!LdrInitShimEngineDynamic () from C:/Windows/SYSTEM32/ntdll.dll

This commit adjusts the testcase to work with either output.

(Note GDB may print a thread name after the thread number.)

Approved-by: Kevin Buettner <kevinb@redhat.com>
Change-Id: I3aedfec04924ea3fb3bb87ba3251e2b720f8d59c

7 weeks agoAdjust gdb.base/bp-permanent.exp for Cygwin
Pedro Alves [Tue, 5 Sep 2023 12:38:14 +0000 (13:38 +0100)] 
Adjust gdb.base/bp-permanent.exp for Cygwin

On Cygwin, all inferiors are multi-threaded, because both Windows and
the Cygwin runtime spawn a few helper threads.  Adjust the
gdb.base/bp-permanent.exp testcase to work with either single- or
multi-threaded inferiors.

Approved-by: Kevin Buettner <kevinb@redhat.com>
Change-Id: I28935b34fc9f739c2a5490e83aa4995d29927be2

7 weeks agoAdjust gdb.base/bp-cond-failure.exp for Cygwin
Pedro Alves [Tue, 5 Sep 2023 12:24:17 +0000 (13:24 +0100)] 
Adjust gdb.base/bp-cond-failure.exp for Cygwin

Currently on Cygwin, I get:

 Running /home/alves/gdb/src/gdb/testsuite/gdb.base/bp-cond-failure.exp ...
 FAIL: gdb.base/bp-cond-failure.exp: access_type=char: cond_eval=auto: multi-loc: continue
 FAIL: gdb.base/bp-cond-failure.exp: access_type=char: cond_eval=auto: single-loc: continue
 FAIL: gdb.base/bp-cond-failure.exp: access_type=short: cond_eval=auto: multi-loc: continue
 FAIL: gdb.base/bp-cond-failure.exp: access_type=short: cond_eval=auto: single-loc: continue
 FAIL: gdb.base/bp-cond-failure.exp: access_type=int: cond_eval=auto: multi-loc: continue
 FAIL: gdb.base/bp-cond-failure.exp: access_type=int: cond_eval=auto: single-loc: continue
 FAIL: gdb.base/bp-cond-failure.exp: access_type=long long: cond_eval=auto: multi-loc: continue
 FAIL: gdb.base/bp-cond-failure.exp: access_type=long long: cond_eval=auto: single-loc: continue

On GNU/Linux, we see:

 Breakpoint 2.1, foo () at .../src/gdb/testsuite/gdb.base/bp-cond-failure.c:21
 21        return 0;     /* Multi-location breakpoint here.  */
 (gdb) PASS: gdb.base/bp-cond-failure.exp: access_type=char: cond_eval=auto: multi-loc: continue

While on Cygwin, we see:

 Thread 1 "bp-cond-failure" hit Breakpoint 2.1, foo () at .../src/gdb/testsuite/gdb.base/bp-cond-failure.c:21
 21        return 0;     /* Multi-location breakpoint here.  */
 (gdb) FAIL: gdb.base/bp-cond-failure.exp: access_type=char: cond_eval=auto: multi-loc: continue

The difference is the "Thread 1" part in the beginning of the quoted
output.  It appears on Cygwin, but not on Linux.  That's because on
Cygwin, all inferiors are multi-threaded, because both Windows and the
Cygwin runtime spawn a few helper threads.

Fix this by adjusting the gdb.base/bp-cond-failure.exp testcase to
work with either single- or multi-threaded inferiors.

The testcase passes cleanly for me after this.

Approved-by: Kevin Buettner <kevinb@redhat.com>
Change-Id: I5ff11d06ac1748d044cef025f1e78b8f84ad3349

7 weeks agoMAINTAINERS: Add myself as an AArch64 maintainer
Alice Carlotti [Mon, 9 Jun 2025 15:48:04 +0000 (16:48 +0100)] 
MAINTAINERS: Add myself as an AArch64 maintainer

7 weeks agoaarch64: Increase the number of feature words to 3
Richard Earnshaw [Fri, 6 Jun 2025 14:12:50 +0000 (15:12 +0100)] 
aarch64: Increase the number of feature words to 3

Now that most of the effort of updating the number of feature words is
handled by macros, add an additional one, taking the number of
supported features to 192.

7 weeks agoaarch64: use macro trickery to automate feature array size replication
Richard Earnshaw [Thu, 22 May 2025 15:18:11 +0000 (16:18 +0100)] 
aarch64: use macro trickery to automate feature array size replication

There are quite a few macros that need to be changed when we need to
increase the number of words in the features data structure.  With
some macro trickery we can automate most of this so that a single
macro needs to be updated.

With C2X we could probably do even better by using recursion, but this
is still a much better situation than we had previously.

A static assertion is used to ensure that there is always enough space
in the flags macro for the number of feature bits we need to support.

7 weeks agoaarch64: Fix typos in opcode headers
Yury Khrustalev [Fri, 6 Jun 2025 09:49:03 +0000 (10:49 +0100)] 
aarch64: Fix typos in opcode headers

7 weeks agochange some listing.c variables to unsigned.
Alan Modra [Mon, 9 Jun 2025 03:24:42 +0000 (12:54 +0930)] 
change some listing.c variables to unsigned.

The values are unsigned, and changing the types allows some casts to
be removed.

7 weeks agodwarf2dbg.c line_entry.next assert
Alan Modra [Mon, 9 Jun 2025 03:21:01 +0000 (12:51 +0930)] 
dwarf2dbg.c line_entry.next assert

I was puzzling over how it was correct to cast what is clearly a
struct line_entry** pointer to a struct line_entry* pointer for a
few moments, and was going to write a comment but then decided we
really don't require the "next" pointer to be where it is.  Replace
the assert with an inline function that does any necessary pointer
adjustments.

* dwarf2dbg.c (line_entry.next): Delete static assertion.
(line_entry_at_tail): New inline function.
(dwarf2_gen_line_info_1, dwarf2_finish): Replace casts in
set_or_check_view arguments with line_entry_at_tail.

7 weeks agostr_hash_find casts
Alan Modra [Mon, 9 Jun 2025 03:16:23 +0000 (12:46 +0930)] 
str_hash_find casts

Putting an explicit cast on the void* return from str_hash_find isn't
necessary and doesn't add much to code clarity.  In other cases, poor
choice of function parameter types, eg. "void *value" in
tc-aarch64.c checked_hash_insert rather than "const void *value" leads
to needing (void *) casts all over the place just to cast away const.
Fix that by correcting the parameter type.  (And it really is a const,
the function and str_hash_insert don't modify the strings.)
This patch also removes some unnecessary casts in hash.c

7 weeks agostr_hash_find_int
Alan Modra [Mon, 9 Jun 2025 02:36:00 +0000 (12:06 +0930)] 
str_hash_find_int

This changes the internal representation of string_tuple.value from
a void* to an intptr_t, removing any concerns that code wanting to
store an integer value will use values that are trap encodings or
suchlike for a pointer.  The ISO C standard says any void* can be
converted to intptr_t and back again and will compare equal to the
original pointer.  It does *not* say any intptr_t can be converted to
void* and back again to get the original integer..

Two new functions, str_hash_find_int and str_hash_insert_int are
provided for handling integer values.  str_hash_find_int returns
(intptr_t) -1 on failing to find the key string.

Most target code need minimal changes to use the new interface, but
some simplification is possible since now a zero can be stored and
differentiated from the NULL "can't find" return.  (Yes, that means
(intptr_t) -1 can't be stored.)

I've changed the avr_no_sreg_hash dummy value to zero, and the
loongarch register numbers don't need to be incremented.  loongarch
also doesn't need to store an empty key string (if it ever did).

7 weeks agometag build error
Alan Modra [Sat, 7 Jun 2025 11:58:41 +0000 (21:28 +0930)] 
metag build error

gas/config/tc-metag.c: In function ‘parse_dsp_addr’:
gas/config/tc-metag.c:4386:29: error: ‘regs[0]’ may be used uninitialized [-Werror=maybe-uninitialized]
 4386 |   if (!is_addr_unit (regs[0]->unit) &&
      |                      ~~~~~~~^~~~~~

It looks like regs_read can be zero with "l" non-NULL, so this gcc
complaint is accurate.

* config/tc-metag.c (parse_dsp_addr, parse_dget_set): Check
regs_read.

7 weeks agoAutomatic date update in version.in
GDB Administrator [Mon, 9 Jun 2025 00:00:12 +0000 (00:00 +0000)] 
Automatic date update in version.in

7 weeks agoAutomatic date update in version.in
GDB Administrator [Sun, 8 Jun 2025 00:00:39 +0000 (00:00 +0000)] 
Automatic date update in version.in

7 weeks ago[gdb/build] Fix buildbreaker in hardwire_setbaudrate
Tom de Vries [Sat, 7 Jun 2025 21:28:53 +0000 (23:28 +0200)] 
[gdb/build] Fix buildbreaker in hardwire_setbaudrate

When building on x86_64-cygwin, I run into:
...
In file included from gdbsupport/common-defs.h:203,
                 from gdb/defs.h:26,
                 from <command-line>:
gdb/ser-unix.c: In function ‘void hardwire_setbaudrate(serial*, int)’:
gdbsupport/gdb_locale.h:28:20: error: expected ‘)’ before ‘gettext’
   28 | # define _(String) gettext (String)
      |                    ^~~~~~~
gdbsupport/gdb_assert.h:43:43: note: in expansion of macro ‘_’
   43 |   internal_error_loc (__FILE__, __LINE__, _("%s: " message), __func__, \
      |                                           ^
gdb/ser-unix.c:590:7: note: in expansion of macro ‘gdb_assert_not_reached’
  590 |       gdb_assert_not_reached (_("Serial baud rate was not found in B_codes"));
      |       ^~~~~~~~~~~~~~~~~~~~~~
gdb/ser-unix.c:590:31: note: in expansion of macro ‘_’
  590 |       gdb_assert_not_reached (_("Serial baud rate was not found in B_codes"));
      |                               ^
gdbsupport/gdb_locale.h:28:28: note: to match this ‘(’
   28 | # define _(String) gettext (String)
      |                            ^
gdbsupport/gdb_assert.h:43:43: note: in expansion of macro ‘_’
   43 |   internal_error_loc (__FILE__, __LINE__, _("%s: " message), __func__, \
      |                                           ^
gdb/ser-unix.c:590:7: note: in expansion of macro ‘gdb_assert_not_reached’
  590 |       gdb_assert_not_reached (_("Serial baud rate was not found in B_codes"));
      |       ^~~~~~~~~~~~~~~~~~~~~~
...

Fix this by dropping the unneeded _() on the gdb_assert_not_reached argument.

PR build/33064
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33064

7 weeks ago[gdb/testsuite] Fix gdb.ada/dyn-bit-offset.exp on s390x
Tom de Vries [Sat, 7 Jun 2025 11:59:52 +0000 (13:59 +0200)] 
[gdb/testsuite] Fix gdb.ada/dyn-bit-offset.exp on s390x

On s390x-linux, with test-case gdb.ada/dyn-bit-offset.exp and gcc 7.5.0 I get:
...
(gdb) print spr^M
$1 = (discr => 3, array_field => (-5, -6, -7), field => -6, another_field => -6)^M
(gdb) FAIL: $exp: print spr
print spr.field^M
$2 = -6^M
(gdb) FAIL: $exp: print spr.field
...

On x86_64-linux, with the same compiler version I get:
...
(gdb) print spr^M
$1 = (discr => 3, array_field => (-5, -6, -7), field => -4, another_field => -4)^M
(gdb) XFAIL: $exp: print spr
print spr.field^M
$2 = -4^M
(gdb) PASS: $exp: print spr.field
...

In both cases, we're hitting the same compiler problem, but it manifests
differently on little and big endian.

Make sure the values seen for both little and big endian trigger xfails
for both tests.

Printing spr.field gives the expected value -4 for x86_64, but that's an
accident.  Change the actual spr.field value to -5, to make sure
that we get the same number of xfails on x86_64 and s390x.

Finally, make the xfails conditional on the compiler version.

Tested using gcc 7.5.0 on both x86_64-linux and s390x-linux.

Approved-By: Andrew Burgess <aburgess@redhat.com>
PR testsuite/33042
https://sourceware.org/bugzilla/show_bug.cgi?id=33042

7 weeks agoAVR: ld/32968 - Assert that .progmem data resides in the lower 64 KiB.
Georg-Johann Lay [Thu, 15 May 2025 08:29:25 +0000 (10:29 +0200)] 
AVR: ld/32968 - Assert that .progmem data resides in the lower 64 KiB.

This patch locates the linker stubs / trampolines *after* all the .progmem
sections.  This is the natural placement since progmem data has to reside
in the lower 64 KiB (it is accessed using LPM), whereas the linker stubs
are only required to be located in the lower 128 KiB of program memory.
(They must be in the range of EICALL / EIJMP with EIND = 0.)

The current location of the linker stubs was motivated by an invalid test
case from PR13812 that allocates more than 64 KiB of progmem data.

The patch adds an assertion that makes sure that no progmem data is
allocated past 0xffff.

Data that is accessed using ELPM should be located to .progmemx so that
no .progmem addresses are wasted.  .progmemx was introduced in 2017 and
is used by __memx, __flashx and by the current AVR-LibC.
(The compiler uses .jumptables.gcc for its jump dispatch tables since
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63223 / GCC v4.9.2).

PR ld/32968
ld/
* scripttempl/avr.sc: Move the trampolines section after the
.progmem sections.  Assert that .progmem is in the lower 64 KiB.

7 weeks agoAutomatic date update in version.in
GDB Administrator [Sat, 7 Jun 2025 00:01:08 +0000 (00:01 +0000)] 
Automatic date update in version.in

7 weeks agogdb/guile: fix memory leak in gdbscm_parse_command_name
Andrew Burgess [Thu, 5 Jun 2025 13:50:41 +0000 (14:50 +0100)] 
gdb/guile: fix memory leak in gdbscm_parse_command_name

For reference see the previous commit.

Fix a memory leak in gdbscm_parse_command_name when a guile exception
is thrown.  To reveal the memory leak I placed the following content
into a file 'leak.scm':

  (use-modules (gdb))
  (register-command!
   (make-command
    "break cmd"
    #:command-class COMMAND_OBSCURE
    #:invoke (lambda (self arg from-tty)
               (display "Hello World"))))

Then in GDB:

  (gdb) source leak.scm
  ERROR: In procedure register-command!:
  In procedure gdbscm_register_command_x: Out of range: 'break' is not a prefix command in position 1: "break cmd"
  Error while executing Scheme code.

Running this under valgrind reveals a memory leak for 'result' and
'prefix_text' from gdbscm_parse_command_name.

Another leak can be revealed with this input script:

  (use-modules (gdb))
  (register-command!
   (make-command
    "unknown-prefix cmd"
    #:command-class COMMAND_OBSCURE
    #:invoke (lambda (self arg from-tty)
               (display "Hello World"))))

This one occurs earlier in gdbscm_parse_command_name, and now only
'result' leaks.

The problem is that, when guile throws an exception then a longjmp is
performed from the function that raise the exception back to the guile
run-time.  A consequence of this is that no function local destructors
will be run.

In gdbscm_parse_command_name, this means that the two function locals
`result` and `prefix_text` will not have their destructors run, and
any memory managed by these objects will be leaked.

Fix this by assigning nullptr to these two function locals before
throwing an exception.  This will cause the managed memory to be
deallocated.

I could have implemented a fix that made use of Guile's dynwind
mechanism to register a cleanup callback, however, this felt like
overkill.  At the point the exception is being thrown we know that we
no longer need the managed memory, so we might as well just free the
memory at that point.

With this fix in place, the two leaks are now fixed in the valgrind
output.

Approved-By: Tom Tromey <tom@tromey.com>
7 weeks agogdb/python/guile: remove some explicit calls to xmalloc
Andrew Burgess [Wed, 4 Jun 2025 18:54:01 +0000 (19:54 +0100)] 
gdb/python/guile: remove some explicit calls to xmalloc

In gdbpy_parse_command_name (python/py-cmd.c) there is a call to
xmalloc that can easily be replaced with a call to
make_unique_xstrndup, which makes the code easier to read (I think).

In gdbscm_parse_command_name (guile/scm-cmd.c) the same fix can be
applied to remove an identical xmalloc call.  And there is an
additional xmalloc call, which can also be replaced with
make_unique_xstrndup in the same way.

The second xmalloc call in gdbscm_parse_command_name was also present
in gdbpy_parse_command_name at one point, but was replaced with a use
of std::string by this commit:

  commit 075c55e0cc0a68eeab777027213c2f545618e844
  Date:   Wed Dec 26 11:05:57 2018 -0700

      Remove more calls to xfree from Python

I haven't changed the gdbscm_parse_command_name to use std::string
though, as that doesn't work well with the guile exception model.
Guile exceptions work by performing a longjmp from the function that
raises the exception, back to the guile run-time.  The consequence of
this is that destructors are not run.  For example, if
gdbscm_parse_command_name calls gdbscm_out_of_range_error, then any
function local objects in gdbscm_parse_command_name will not have
their destructors called.

What this means is that, for the existing `result` and `prefix_text`
locals, any allocated memory managed by these objects will be leaked
if an exception is called.  However, fixing this is pretty easy, one
way is to just assign nullptr to these locals before raising the
exception, this would cause the allocated memory to be released.

But for std::string it is harder to ensure that the managed memory has
actually been released.  We can call std::string::clear() and then
maybe std::string::shrink_to_fit(), but this is still not guaranteed
to release any managed memory.  In fact, I believe the only way to
ensure all managed memory is released, is to call the std::string
destructor.

And so, for functions that can throw a guile exception, it is easier
to just avoid std::string.

As for the memory leak that I identify above; I'll fix that in a
follow on commit.

Approved-By: Tom Tromey <tom@tromey.com>
7 weeks agogdb/solib: make _linker_namespace use selected frame
Guinevere Larsen [Fri, 6 Jun 2025 19:23:37 +0000 (16:23 -0300)] 
gdb/solib: make _linker_namespace use selected frame

When the convenience variable $_linker_namespace was introduced, I meant
for it to print the namespace of the frame that where the user was
stopped. However, due to confusing what "current_frame" and
"selected_frame" meant, it instead printed the namespace of the
lowermost frame.

This commit updates the code to follow my original intent. Since the
variable was never in a GDB release, updating the behavior should not
cause any disruption. It also adds a test to verify the functionality.

Approved-By: Tom Tromey <tom@tromey.com>
7 weeks agobfd: sframe: fix typo in comments
Indu Bhagat [Fri, 6 Jun 2025 20:36:04 +0000 (13:36 -0700)] 
bfd: sframe: fix typo in comments

bfd/
* elflink.c (elf_link_input_bfd): Replace ctf frame with SFrame.

7 weeks agogdb: unix: allow to use custom baud rate
Alexey Lapshin [Wed, 9 Apr 2025 16:19:02 +0000 (16:19 +0000)] 
gdb: unix: allow to use custom baud rate

Modern unix systems allow to set custom baud rate instead of predefined in termios.h.

- To use this in Linux it must have BOTHER macro in "asm/termio.h"
- MacOS could handle this using IOSSIOSPEED passed to ioctl()

Approved-By: Simon Marchi <simon.marchi@efficios.com>
Change-Id: I5bc95982f5d90c7030b73f484ecc0f75c060ebf7