15 Commits

Author SHA1 Message Date
50838d1be7 Don't write to inferior_ptid in windows-nat.c, part II
Writing to inferior_ptid in
windows_nat_target::get_windows_debug_event is just incorrect and not
necessary.  We'll report the event to GDB's core, which then takes
care of switching inferior_ptid / current thread.

Related (see windows_nat_target::get_windows_debug_event), there's
also a "current_windows_thread" global that is just begging to get out
of sync with core GDB's current thread.  This patch removes it.
gdbserver already does not have an equivalent global in win32-low.cc.

gdb/ChangeLog:
2020-06-18  Pedro Alves  <palves@redhat.com>

	* nat/windows-nat.c (current_windows_thread): Remove.
	* nat/windows-nat.h (current_windows_thread): Remove.
	* windows-nat.c (windows_nat_target::stopped_by_sw_breakpoint):
	Adjust.
	(display_selectors): Adjust to fetch the current
	windows_thread_info based on inferior_ptid.
	(fake_create_process): No longer write to current_windows_thread.
	(windows_nat_target::get_windows_debug_event):
	Don't set inferior_ptid or current_windows_thread.
	(windows_nat_target::wait): Adjust to not rely on
	current_windows_thread.
	(do_initial_windows_stuff): Now a method of windows_nat_target.
	Switch to the last_ptid thread.
	(windows_nat_target::attach): Adjust.
	(windows_nat_target::detach): Use switch_to_no_thread instead of
	writing to inferior_ptid directly.
	(windows_nat_target::create_inferior): Adjust.
2020-06-18 23:17:01 +01:00
ac637ec30d Don't close thread handles provided by WaitForDebugEvent
I sometimes encountered a weird breakpoint failure when using start:

(gdb) start
Temporary breakpoint 2 at 0x40162d: file gdb-25911.c, line 4.
Starting program: C:\src\tests\gdb-25911.exe
Warning:
Cannot insert breakpoint 2.
Cannot access memory at address 0x401628

After trying a lot of combinations, I found a way to reproduce it:

(gdb) file gdb-25987.exe
Reading symbols from gdb-25987.exe...
(gdb) start
Temporary breakpoint 1 at 0x401638: file gdb-25987.cpp, line 13.
Starting program: C:\src\tests\gdb-25987.exe

Temporary breakpoint 1, main () at gdb-25987.cpp:13
13      int main() {
(gdb) c
Continuing.

Program received signal SIGSEGV, Segmentation fault.
MyClass::call (this=0x3d20d0) at gdb-25987.cpp:8
8           *(char*)(nullptr) = 1;
(gdb) kill
Kill the program being debugged? (y or n) y
[Inferior 1 (process 1140) killed]
(gdb) file gdb-25911.exe
Load new symbol table from "gdb-25911.exe"? (y or n) y
Reading symbols from gdb-25911.exe...
(gdb) start
Temporary breakpoint 2 at 0x40162d: file gdb-25911.c, line 4.
Starting program: C:\src\tests\gdb-25911.exe
Warning:
Cannot insert breakpoint 2.
Cannot access memory at address 0x401628

Command aborted.

The actual failure was that ReadProcessMemory used a process handle that
was no longer valid.
And the underlying reason was that the windows_thread_info destructor
closes a thread handle that was provided earlier by WaitForDebugEvent.

But since this is not allowed (and it was actually already closed at this
point, and the handle value reused), this closed another still-needed handle.

gdb/ChangeLog:

2020-05-27  Hannes Domani  <ssbssa@yahoo.de>

	* nat/windows-nat.c (windows_thread_info::~windows_thread_info):
	Don't close thread handle.
2020-05-27 19:15:53 +02:00
a010605fef Fix Cygwin gdb build
Simon pointed out that the windows-nat sharing series broke the Cygwin
build.  This patch fixes the problem, by moving the Cygwin-specific
code to a new handler function.  This approach is taken because this
code calls find_pc_partial_function, which isn't available in
gdbserver.

gdb/ChangeLog
2020-04-16  Tom Tromey  <tromey@adacore.com>

	* windows-nat.c (windows_nat::handle_access_violation): New
	function.
	* nat/windows-nat.h (handle_access_violation): Declare.
	* nat/windows-nat.c (handle_exception): Move Cygwin code to
	windows-nat.c.  Call handle_access_violation.

gdbserver/ChangeLog
2020-04-16  Tom Tromey  <tromey@adacore.com>

	* win32-low.cc (windows_nat::handle_access_violation): New
	function.
2020-04-16 07:24:57 -06:00
13302e956f Fix debugging of WOW64 processes
The new code regarding pending stops only checks for EXCEPTION_BREAKPOINT,
but for WOW64 processes STATUS_WX86_BREAKPOINT is necessary as well.

Also, ignore_first_breakpoint is used now in nat/windows-nat.c as well,
but was not available there.

gdb/ChangeLog:

2020-04-10  Hannes Domani  <ssbssa@yahoo.de>

	* nat/windows-nat.c (STATUS_WX86_BREAKPOINT, STATUS_WX86_SINGLE_STEP):
	Move to...
	* nat/windows-nat.h (STATUS_WX86_BREAKPOINT, STATUS_WX86_SINGLE_STEP):
	... here.
	* windows-nat.c (windows_nat_target::get_windows_debug_event):
	Check for STATUS_WX86_BREAKPOINT.
	(windows_nat_target::wait): Same.
2020-04-10 13:01:31 +02:00
71fbdbafe0 Make last_wait_event static
Now that last_wait_event is entirely handled in nat/windows-nat.c, it
can be made static.

gdb/ChangeLog
2020-04-08  Tom Tromey  <tromey@adacore.com>

	* nat/windows-nat.h (last_wait_event): Don't declare.
	(wait_for_debug_event): Update comment.
	* nat/windows-nat.c (last_wait_event): Now static.
2020-04-08 14:47:59 -06:00
2c1d95e869 Move wait_for_debug_event to nat/windows-nat.c
This moves the wait_for_debug_event helper function to
nat/windows-nat.c, and changes gdbserver to use it.
wait_for_debug_event is a wrapper for WaitForDebugEvent that also sets
last_wait_event when appropriate.  This is needed to properly handle
queued stops.

gdb/ChangeLog
2020-04-08  Tom Tromey  <tromey@adacore.com>

	* windows-nat.c (wait_for_debug_event): Move to
	nat/windows-nat.c.
	* nat/windows-nat.h (wait_for_debug_event): Declare.
	* nat/windows-nat.c (wait_for_debug_event): Move from
	windows-nat.c.  No longer static.

gdbserver/ChangeLog
2020-04-08  Tom Tromey  <tromey@adacore.com>

	* win32-low.c (win32_kill, get_child_debug_event): Use
	wait_for_debug_event.
2020-04-08 14:47:59 -06:00
d2977bc425 Introduce fetch_pending_stop
This introduces a new "fetch_pending_stop" function and changes gdb to
use it.  This function removes the first matching pending stop from
the list of such stops.

gdb/ChangeLog
2020-04-08  Tom Tromey  <tromey@adacore.com>

	* windows-nat.c (get_windows_debug_event): Use
	fetch_pending_stop.
	* nat/windows-nat.h (fetch_pending_stop): Declare.
	* nat/windows-nat.c (fetch_pending_stop): New function.
2020-04-08 14:47:59 -06:00
e758e19c59 Share some inferior-related Windows code
This adds a couple of functions to nat/windows-nat.c and changes gdb
and gdbserver to use them.  One function checks the list of pending
stops for a match (not yet used by gdbserver, but will be in a
subsequent patch); and the other is a wrapper for ContinueDebugEvent
that always uses the last "real" stop event.

gdb/ChangeLog
2020-04-08  Tom Tromey  <tromey@adacore.com>

	* windows-nat.c (windows_continue): Use matching_pending_stop and
	continue_last_debug_event.
	* nat/windows-nat.h (matching_pending_stop)
	(continue_last_debug_event): Declare.
	* nat/windows-nat.c (DEBUG_EVENTS): New define.
	(matching_pending_stop, continue_last_debug_event): New
	functions.

gdbserver/ChangeLog
2020-04-08  Tom Tromey  <tromey@adacore.com>

	* win32-low.c (child_continue): Call continue_last_debug_event.
2020-04-08 14:47:59 -06:00
8d30e39577 Share handle_exception
Both gdb and gdbserver have a "handle_exception" function, the bulk of
which is shared between the two implementations.  This patch arranges
for the entire thing to be moved into nat/windows-nat.c, with the
differences handled by callbacks.  This patch introduces one more
callback to make this possible.

gdb/ChangeLog
2020-04-08  Tom Tromey  <tromey@adacore.com>

	* windows-nat.c (MS_VC_EXCEPTION): Move to nat/windows-nat.c.
	(handle_exception_result): Move to nat/windows-nat.h.
	(DEBUG_EXCEPTION_SIMPLE): Remove.
	(windows_nat::handle_ms_vc_exception): New function.
	(handle_exception): Move to nat/windows-nat.c.
	(get_windows_debug_event): Update.
	(STATUS_WX86_BREAKPOINT, STATUS_WX86_SINGLE_STEP): Move to
	nat/windows-nat.c.
	* nat/windows-nat.h (handle_ms_vc_exception): Declare.
	(handle_exception_result): Move from windows-nat.c.
	(handle_exception): Declare.
	* nat/windows-nat.c (MS_VC_EXCEPTION, handle_exception)
	(STATUS_WX86_SINGLE_STEP, STATUS_WX86_BREAKPOINT): Move from
	windows-nat.c.

gdbserver/ChangeLog
2020-04-08  Tom Tromey  <tromey@adacore.com>

	* win32-low.c (handle_exception): Remove.
	(windows_nat::handle_ms_vc_exception): New function.
	(get_child_debug_event): Add "continue_status" parameter.
	Update.
	(win32_wait): Update.
2020-04-08 14:47:59 -06:00
3c76026df8 Share some Windows-related globals
This moves some Windows-related globals into nat/windows-nat.c,
sharing them between gdb and gdbserver.

gdb/ChangeLog
2020-04-08  Tom Tromey  <tromey@adacore.com>

	* windows-nat.c (current_process_handle, current_process_id)
	(main_thread_id, last_sig, current_event, last_wait_event)
	(current_windows_thread, desired_stop_thread_id, pending_stops)
	(struct pending_stop, siginfo_er): Move to nat/windows-nat.c.
	(display_selectors, fake_create_process)
	(get_windows_debug_event): Update.
	* nat/windows-nat.h (current_process_handle, current_process_id)
	(main_thread_id, last_sig, current_event, last_wait_event)
	(current_windows_thread, desired_stop_thread_id, pending_stops)
	(struct pending_stop, siginfo_er): Move from windows-nat.c.
	* nat/windows-nat.c (current_process_handle, current_process_id)
	(main_thread_id, last_sig, current_event, last_wait_event)
	(current_windows_thread, desired_stop_thread_id, pending_stops)
	(siginfo_er): New globals.  Move from windows-nat.c.

gdbserver/ChangeLog
2020-04-08  Tom Tromey  <tromey@adacore.com>

	* win32-low.c (current_process_handle, current_process_id)
	(main_thread_id, last_sig, current_event, siginfo_er): Move to
	nat/windows-nat.c.
2020-04-08 14:47:58 -06:00
9d8679cc71 Share get_image_name between gdb and gdbserver
This moves get_image_name to nat/windows-nat.c so that it can be
shared between gdb and gdbserver.

gdb/ChangeLog
2020-04-08  Tom Tromey  <tromey@adacore.com>

	* windows-nat.c (get_image_name): Move to nat/windows-nat.c.
	(handle_load_dll): Update.
	* nat/windows-nat.c (get_image_name): Move from windows-nat.c.

gdbserver/ChangeLog
2020-04-08  Tom Tromey  <tromey@adacore.com>

	* win32-low.c (get_image_name): Remove.
	(handle_load_dll): Update.
2020-04-08 14:47:58 -06:00
4834dad062 Wrap shared windows-nat code in windows_nat namespace
This wraps the shared windows-nat code in a windows_nat namespace.
This helps avoid name clashes.

gdb/ChangeLog
2020-04-08  Tom Tromey  <tromey@adacore.com>

	* windows-nat.c: Add "using namespace".
	* nat/windows-nat.h: Wrap contents in windows_nat namespace.
	* nat/windows-nat.c: Wrap contents in windows_nat namespace.

gdbserver/ChangeLog
2020-04-08  Tom Tromey  <tromey@adacore.com>

	* win32-low.h (struct win32_target_ops): Use qualified names where
	needed.
	* win32-i386-low.c: Add "using namespace".
	* win32-low.c: Add "using namespace".
	* win32-arm-low.c: Add "using namespace".
2020-04-08 14:47:58 -06:00
65bafd5b15 Call CloseHandle from ~windows_thread_info
Add a destructor to windows_thread_info that calls CloseHandle.

gdb/ChangeLog
2020-04-08  Tom Tromey  <tromey@adacore.com>

	* nat/windows-nat.h (struct windows_thread_info): Declare
	destructor.
	* nat/windows-nat.c (~windows_thread_info): New.

gdbserver/ChangeLog
2020-04-08  Tom Tromey  <tromey@adacore.com>

	* win32-low.c (delete_thread_info): Don't call CloseHandle.
2020-04-08 14:47:58 -06:00
0a4afda3c6 Handle pending stops from the Windows kernel
PR gdb/22992 concerns an assertion failure in gdb when debugging a
certain inferior:

    int finish_step_over(execution_control_state*): Assertion `ecs->event_thread->control.trap_expected' failed.

Initially the investigation centered on the discovery that gdb was not
suspending other threads when attempting to single-step.  This
oversight is corrected in this patch: now, when stepping a thread, gdb
will call SuspendThread on all other threads.

However, the bug persisted even after this change.  In particular,
WaitForDebugEvent could see a stop for a thread that was ostensibly
suspended.  Our theory of what is happening here is that there are
actually simultaneous breakpoint hits, and the Windows kernel queues
the events, causing the second stop to be reported on a suspended
thread.

In Windows 10 or later gdb could use the DBG_REPLY_LATER flag to
ContinueDebugEvent to request that such events be re-reported later.
However, relying on that did not seem advisable, so this patch instead
arranges to queue such "pending" stops, and then to report them later,
once the step has completed.

In the PR, Pedro pointed out that it's best in this scenario to
implement the stopped_by_sw_breakpoint method, so this patch does this
as well.

gdb/ChangeLog
2020-04-08  Tom Tromey  <tromey@adacore.com>

	PR gdb/22992
	* windows-nat.c (current_event): Update comment.
	(last_wait_event, desired_stop_thread_id): New globals.
	(struct pending_stop): New.
	(pending_stops): New global.
	(windows_nat_target) <stopped_by_sw_breakpoint>
	<supports_stopped_by_sw_breakpoint>: New methods.
	(windows_fetch_one_register): Add assertions.  Adjust PC.
	(windows_continue): Handle pending stops.  Suspend other threads
	when stepping.  Use last_wait_event
	(wait_for_debug_event): New function.
	(get_windows_debug_event): Use wait_for_debug_event.  Handle
	pending stops.  Queue spurious stops.
	(windows_nat_target::wait): Set stopped_at_software_breakpoint.
	(windows_nat_target::kill): Use wait_for_debug_event.
	* nat/windows-nat.h (struct windows_thread_info)
	<stopped_at_software_breakpoint>: New field.
	* nat/windows-nat.c (windows_thread_info::resume): Clear
	stopped_at_software_breakpoint.
2020-04-08 14:47:58 -06:00
98a0328732 Share Windows thread-suspend and -resume code
This adds "suspend" and "resume" methods to windows_thread_info, and
changes gdb and gdbserver to share this code.

gdb/ChangeLog
2020-04-08  Tom Tromey  <tromey@adacore.com>

	* windows-nat.c (thread_rec): Use windows_thread_info::suspend.
	(windows_continue): Use windows_continue::resume.
	* nat/windows-nat.h (struct windows_thread_info) <suspend,
	resume>: Declare new methods.
	* nat/windows-nat.c: New file.
	* configure.nat (NATDEPFILES): Add nat/windows-nat.o when needed.

gdbserver/ChangeLog
2020-04-08  Tom Tromey  <tromey@adacore.com>

	* win32-low.c (win32_require_context, suspend_one_thread): Use
	windows_thread_info::suspend.
	(continue_one_thread): Use windows_thread_info::resume.
	* configure.srv (srv_tgtobj): Add windows-nat.o when needed.
2020-04-08 14:47:58 -06:00