Age | Commit message (Collapse) | Author | Files | Lines |
|
- Need to flush pending kernel-side events
- I realized that while we're detaching, we want to pass exceptions
down to the inferior with DBG_EXCEPTION_NOT_HANDLED, instead of
losing them. I ended up reusing a bit of code from the Linux
target.
Change-Id: Ifaa96b4a41bb83d868079af4d47633715c0e1940
|
|
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
|
|
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 adds that DBG_REPLY_LATER handling, 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 those inject 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.
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 patch also 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.
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.
Change-Id: Id71aef461c43c244120635b5bedc638fe77c31fb
|
|
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 in 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 what (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
|
|
Consolidate the WoW64 & non-WoW64 paths in
windows_per_inferior::continue_one_thread to avoid code duplication.
The next patch will add more code to this function, and this
unification avoids writing that new code twice.
Change-Id: I794aadb412a3b8081212e4acf2af80d3edba7392
|
|
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.
Change-Id: I46df3b44f5272adadf960da398342a3cbdb98533
|
|
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
|
|
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
|
|
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.
Change-Id: I47fc0d3323be5b6f6fcfe912b768051a41910666
|
|
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.
Change-Id: I47fc0d3323be5b6f6fcfe912b768051a41910666
|
|
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
|
|
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: Ice09a5d932c912210608d5af25e1898f823e3c99
|
|
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
|
|
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.
Change-Id: Ie762d3768fd70e4ac398c8bcc03c3213bfa26a6a
|
|
Passing a signal to a thread other than the one that last reported an
event would be later possible with DBG_REPLY_LATER and a 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: I32915623b5036fb902f9830ce2d6f0b1ccf1f5cf
|
|
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
|
|
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.
Change-Id: Ic8935d854cf67a3a3c4edcbc1a1e8957b800d907
|
|
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).
Change-Id: I14a0386b1b8b03015e86273060af173b5130e375
|
|
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.
Change-Id: I17c4d8a12b662190f972c380f838cb3317bd2e1e
|
|
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.
Change-Id: I945e668d2b3daeb9de968219925a7b3c7c7ce9ed
|
|
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
|
|
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
|
|
After the previous patches, thread_rec is no longer called anywhere.
Delete it.
Change-Id: Ib14e5807fc427e1c3c4a393a9ea7b36b6047a2d7
|
|
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.
Change-Id: I0f328542bda6d8268814ca1ee4ae7a478098ecf2
|
|
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.
Change-Id: I8d2f0a749d23329956e62362a7007189902dddb5
|
|
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.
Change-Id: Ied566037c81383414c46c77713bdd1aec6377b23
|
|
handle_output_debug_string returns a Windows thread id, so it should
return a DWORD instead of an int.
Change-Id: Icbd071a1a37de8a0fc8918bd13254a8d40311e32
|
|
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.
Change-Id: Ie486badce00e234b10caa478b066c34537103e3f
|
|
current_process.dr needs to be per-thread for non-stop. Actually, it
doesn't even need to exist at all. We have the 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.
Change-Id: I2fe460341b598ad293ea60d5f702b10cefc30711
|
|
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.
Change-Id: I2fe460341b598ad293ea60d5f702b10cefc30711
|
|
On Cygwin, with "attach PID":
- GDB first tries to interpret PID as a Windows native PID, and tries
to attach to that.
- if the attach fails, GDB then tries to interpret the PID as a
Cygwin PID, and attach to that.
If converting the user-provided PID from a Cygwin PID to a Windows PID
fails, you get this:
(gdb) attach 12345
Can't attach to process 0 (error 2: The system cannot find the file specified.)
Note "process 0".
With the fix in this commit, we'll now get:
(gdb) attach 12345
Can't attach to process 12345 (error 2: The system cannot find the file specified.)
I noticed this while looking at gdb.log after running
gdb.base/attach.exp on Cygwin.
Change-Id: I05b9dc1f3a634a822ea49bb5c61719f5e62c8514
Approved-By: Luis Machado <luis.machado@arm.com>
|
|
On Cygwin, gdb.base/attach.exp exposes that an "attach" after a
previously failed "attach" hangs:
(gdb) PASS: gdb.base/attach.exp: do_attach_failure_tests: attach to digits-starting nonsense is prohibited
attach 0
Can't attach to process 0 (error 2: The system cannot find the file specified.)
(gdb) PASS: gdb.base/attach.exp: do_attach_failure_tests: attach to nonexistent process is prohibited
attach 10644
FAIL: gdb.base/attach.exp: do_attach_failure_tests: first attach (timeout)
The problem is that windows_nat_target::attach always returns success
even if the attach fails. When we return success, the helper thread
begins waiting for events (which will never come), and thus the next
attach deadlocks on the do_synchronously call within
windows_nat_target::attach.
"run" has the same problem, which is exposed by the new
gdb.base/run-fail-twice.exp testcase added in a following patch:
(gdb) run
Starting program: .../gdb.base/run-fail-twice/run-fail-twice.nox
Error creating process .../gdb.base/run-fail-twice/run-fail-twice.nox, (error 6: The handle is invalid.)
(gdb) PASS: gdb.base/run-fail-twice.exp: test: bad run 1
run
Starting program: .../gdb.base/run-fail-twice/run-fail-twice.nox
FAIL: gdb.base/run-fail-twice.exp: test: bad run 2 (timeout)
The problem here is the same, except that this time it is
windows_nat_target::create_inferior that returns the incorrect result.
This commit fixes both the "attach" and "run" paths, and the latter
both the Cygwin and MinGW paths. The tests mentioned above now pass
on Cygwin. Confirmed the fixes manually for MinGW GDB.
Change-Id: I15ec9fa279aff269d4982b00f4ea7c25ae917239
Approved-By: Tom Tromey <tom@tromey.com>
|
|
Most files including gdbcmd.h currently rely on it to access things
actually declared in cli/cli-cmds.h (setlist, showlist, etc). To make
things easy, replace all includes of gdbcmd.h with includes of
cli/cli-cmds.h. This might lead to some unused includes of
cli/cli-cmds.h, but it's harmless, and much faster than going through
the 170 or so files by hand.
Change-Id: I11f884d4d616c12c05f395c98bbc2892950fb00f
Approved-By: Tom Tromey <tom@tromey.com>
|
|
While testing a WIP Cygwin GDB that supports non-stop, I noticed that
gdb.threads/attach-non-stop.exp exposes that this:
(gdb) attach PID&
...
(gdb) detach
... hangs.
And it turns out that it hangs in all-stop as well. This commits
fixes that.
After "attach &", the target is set running, we've called
ContinueDebugEvent and the process_thread thread is waiting for
WaitForDebugEvent events. It is the equivalent of "attach; c&".
In windows_nat_target::detach, the first thing we do is
unconditionally call windows_continue (for ContinueDebugEvent), which
blocks in do_synchronously, until the process_thread sees an event out
of WaitForDebugEvent. Unless the inferior happens to run into a
breakpoint, etc., then this hangs indefinitely.
If we've already called ContinueDebugEvent earlier, then we shouldn't
be calling it again in ::detach.
Still in windows_nat_target::detach, we have an interesting issue that
ends up being the bulk of the patch -- only the process_thread thread
can call DebugActiveProcessStop, but if it is blocked in
WaitForDebugEvent, we need to somehow force it to break out of it.
The only way to do that, is to force the inferior to do something that
causes WaitForDebugEvent to return some event.
This patch uses CreateRemoteThread to do it, which results in
WaitForDebugEvent reporting CREATE_THREAD_DEBUG_EVENT. We then
terminate the injected thread before it has a chance to run any
userspace code.
Note that Win32 functions like DebugBreakProcess and
GenerateConsoleCtrlEvent would also inject a new thread in the
inferior. I first used DebugBreakProcess, but that is actually more
complicated to use, because we'd have to be sure to consume the
breakpoint event before detaching, otherwise the inferior would likely
die due a breakpoint exception being raised with no debugger around to
intercept it.
See the new break_out_process_thread method.
So the fix has two parts:
- Keep track of whether we've called ContinueDebugEvent and the
process_thread thread is waiting for events, or whether
WaitForDebugEvent already returned an event.
- In windows_nat_target::detach, if the process_thread thread is
waiting for events, unblock out of its WaitForDebugEvent, before
proceeding with the actual detach.
New test included. Passes cleanly on GNU/Linux native and gdbserver,
and also passes cleanly on Cygwin and MinGW, with the fix. Before the
fix, it would hang and fail with a timeout.
Tested-By: Hannes Domani <ssbssa@yahoo.de>
Reviewed-By: Tom Tromey <tom@tromey.com>
Change-Id: Ifb91c58c08af1a9bcbafecedc93dfce001040905
|
|
Now that defs.h, server.h and common-defs.h are included via the
`-include` option, it is no longer necessary for source files to include
them. Remove all the inclusions of these files I could find. Update
the generation scripts where relevant.
Change-Id: Ia026cff269c1b7ae7386dd3619bc9bb6a5332837
Approved-By: Pedro Alves <pedro@palves.net>
|
|
While working on Windows non-stop mode, I managed to introduce a bug
that led to fake_create_process being called. That then resulted in
GDB crashes later on, because fake_create_process added a thread with
an incorrect ptid for this target. It is putting dwThreadId in the
tid field of the ptid instead of on the lwp field. This is fixed by
this patch.
Change-Id: Iaee5d2deaa57c501f7e6909f8ac242af9b183215
|
|
Use gdb_realpath instead of realpath in windows-nat.c:windows_make_so,
so that we don't have to manually call free.
Approved-By: John Baldwin <jhb@FreeBSD.org>
Change-Id: Id3cda7e177ac984c9a5f7c23f354e72bd561edff
|
|
There is no need to limit shared library path sizes to
SO_NAME_MAX_PATH_SIZE nowadays. windows_solib::name and
windows_solib::original_name are std::strings nowadays, and so are
solib::so_name and solib::so_original_name in the core solib code.
This commit reworks the code to remove that limit. This also fixes a
leak where we were not releasing 'rname' in the realpath branch if the
'rname' string was larger than SO_NAME_MAX_PATH_SIZE.
Note: I tested the cygwin_conv_path with a manual hack to force that
path, and then stepping through the code. You only get to that path
if Windows doesn't report an absolute path for ntdll.dll, and on my
machine (running Windows 10), it always does.
Approved-By: John Baldwin <jhb@FreeBSD.org>
Change-Id: I79e9862d5a7646eebfef7ab5b05b96318a7ca0c5
|
|
There are two separate #ifndef __CYGWIN__/#else/#endif sections in the
windows_make_so function with 3 lines of shared code separating them.
I find this makes the code harder to understand than necessary.
AFAICS, there is no reason those three shared lines need to be after
the first #ifdef block. There is no early return, nor are 'load_addr'
nor 'name' modified.
This commit moves that shared code to the top of the function, and
then combines the two #ifndef sections.
Approved-By: John Baldwin <jhb@FreeBSD.org>
Change-Id: If2678b52836b1c3134a5e9f9fdaee74448d8b7bc
|
|
Simplify Cygwin signal handling by dropping the special way of getting
inferior context after a Cygwin signal.
I think the reason this existed was because previously we were not
able to unwind through the alternate stack used by _sigfe frames, so
without the hint of the "user" code IP, the backtrace from a signal
was unusable.
Now we can unwind through _sigfe frames, drop all this complexity.
(Restoring this specially obtained context to the inferior (as the
code currently does) skips over the actual signal delivery and
handling. Cygwin has carried for a long time a patch which clears the
ContextFlags in the signal context, so we never attempt to restore it
to the inferior, but that interfers with gdb's ability to modify that
context e.g. if it decides it wants to turn on FLAG_TRACE_BIT.)
Change-Id: I214edd5a99fd17c1a31ad18138d4a6cc420225e3
|
|
Make the current_program_space reference bubble up one level.
Change-Id: Ide917aa306bff1872d961244901d79f65d2da62e
Approved-By: Andrew Burgess <aburgess@redhat.com>
|
|
Starting with C++17, emplace_back returns a reference to the new
object. This patch changes code that uses emplace_back followed by a
call to back() to simply use this reference instead.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
|
|
My earlier attempt to mask the segment registers in gdbserver for
Windows introduced some bugs. That patch is here:
https://sourceware.org/pipermail/gdb-patches/2023-December/205306.html
The problem turned out to be that these fields in the Windows
'CONTEXT' type are just 16 bits, so while masking the values on read
is fine, writing the truncated values back then causes zeros to be
written to some subsequent field.
This patch cleans this up by arranging never to write too much data to
a field.
I also noticed that two register numbers here were never updated for
the 64-bit port. This patch fixes this as well, and renames the "FCS"
register to follow gdb.
Finally, this patch applies the same treatment to windows-nat.c.
Reviewed-by: John Baldwin <jhb@FreeBSD.org>
|
|
This commit is the result of the following actions:
- Running gdb/copyright.py to update all of the copyright headers to
include 2024,
- Manually updating a few files the copyright.py script told me to
update, these files had copyright headers embedded within the
file,
- Regenerating gdbsupport/Makefile.in to refresh it's copyright
date,
- Using grep to find other files that still mentioned 2023. If
these files were updated last year from 2022 to 2023 then I've
updated them this year to 2024.
I'm sure I've probably missed some dates. Feel free to fix them up as
you spot them.
|
|
This changes gdb to use the C++17 [[fallthrough]] attribute rather
than special comments.
This was mostly done by script, but I neglected a few spellings and so
also fixed it up by hand.
I suspect this fixes the bug mentioned below, by switching to a
standard approach that, presumably, clang supports.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=23159
Approved-By: John Baldwin <jhb@FreeBSD.org>
Approved-By: Luis Machado <luis.machado@arm.com>
Approved-By: Pedro Alves <pedro@palves.net>
|
|
This introduces throw_winerror_with_name, a Windows analog of
perror_with_name, and changes various places in gdb to call it.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30770
|
|
Since GDB now requires C++17, we don't need the internally maintained
gdb::optional implementation. This patch does the following replacing:
- gdb::optional -> std::optional
- gdb::in_place -> std::in_place
- #include "gdbsupport/gdb_optional.h" -> #include <optional>
This change has mostly been done automatically. One exception is
gdbsupport/thread-pool.* which did not use the gdb:: prefix as it
already lives in the gdb namespace.
Change-Id: I19a92fa03e89637bab136c72e34fd351524f65e9
Approved-By: Tom Tromey <tom@tromey.com>
Approved-By: Pedro Alves <pedro@palves.net>
|
|
Remove get_current_regcache, inlining the call to get_thread_regcache in
callers. When possible, pass the right thread_info object known from
the local context. Otherwise, fall back to passing `inferior_thread ()`.
This makes the reference to global context bubble up one level, a small
step towards the long term goal of reducing the number of references to
global context (or rather, moving those references as close as possible
to the top of the call tree).
No behavior change expected.
Change-Id: Ifa6980c88825d803ea586546b6b4c633c33be8d6
|
|
Remove uses of obstack in the code generating the libraries XML for
Windows and AIX. Use std::string instead. I'm not able to test this
change, unfortunately.
Change-Id: I28480913337e3fe8d6c31e551626931e6b1367ef
Approved-By: Tom Tromey <tom@tromey.com>
|
|
This function is just a wrapper around the current inferior's gdbarch.
I find that having that wrapper just obscures where the arch is coming
from, and that it's often used as "I don't know which arch to use so
I'll use this magical target_gdbarch function that gets me an arch" when
the arch should in fact come from something in the context (a thread,
objfile, symbol, etc). I think that removing it and inlining
`current_inferior ()->arch ()` everywhere will make it a bit clearer
where that arch comes from and will trigger people into reflecting
whether this is the right place to get the arch or not.
Change-Id: I79f14b4e4934c88f91ca3a3155f5fc3ea2fadf6b
Reviewed-By: John Baldwin <jhb@FreeBSD.org>
Approved-By: Andrew Burgess <aburgess@redhat.com>
|