mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-24 20:28:28 +08:00
* win32-low.c (soft_interrupt_requested, faked_breakpoint): New
global variables. (child_add_thread): Minor cleanup. (child_continue): Resume artificially suspended threads before calling ContinueDebugEvent. (suspend_one_thread): New. (fake_breakpoint_event): New. (get_child_debug_event): Change return type to int. Check here if gdb sent an interrupt request. If a soft interrupt was requested, fake a breakpoint event. Return 0 if there is no event to handle, and 1 otherwise. (win32_wait): Don't check here if gdb sent an interrupt request. Ensure there is a valid event to handle. (win32_request_interrupt): Add soft interruption method as last resort.
This commit is contained in:
@ -1,3 +1,22 @@
|
|||||||
|
2007-12-03 Leo Zayas
|
||||||
|
Pedro Alves <pedro_alves@portugalmail.pt>
|
||||||
|
|
||||||
|
* win32-low.c (soft_interrupt_requested, faked_breakpoint): New
|
||||||
|
global variables.
|
||||||
|
(child_add_thread): Minor cleanup.
|
||||||
|
(child_continue): Resume artificially suspended threads before
|
||||||
|
calling ContinueDebugEvent.
|
||||||
|
(suspend_one_thread): New.
|
||||||
|
(fake_breakpoint_event): New.
|
||||||
|
(get_child_debug_event): Change return type to int. Check here if
|
||||||
|
gdb sent an interrupt request. If a soft interrupt was requested,
|
||||||
|
fake a breakpoint event. Return 0 if there is no event to handle,
|
||||||
|
and 1 otherwise.
|
||||||
|
(win32_wait): Don't check here if gdb sent an interrupt request.
|
||||||
|
Ensure there is a valid event to handle.
|
||||||
|
(win32_request_interrupt): Add soft interruption method as last
|
||||||
|
resort.
|
||||||
|
|
||||||
2007-12-03 Leo Zayas
|
2007-12-03 Leo Zayas
|
||||||
Pedro Alves <pedro_alves@portugalmail.pt>
|
Pedro Alves <pedro_alves@portugalmail.pt>
|
||||||
|
|
||||||
|
@ -72,6 +72,14 @@ static enum target_signal last_sig = TARGET_SIGNAL_0;
|
|||||||
/* The current debug event from WaitForDebugEvent. */
|
/* The current debug event from WaitForDebugEvent. */
|
||||||
static DEBUG_EVENT current_event;
|
static DEBUG_EVENT current_event;
|
||||||
|
|
||||||
|
/* Non zero if an interrupt request is to be satisfied by suspending
|
||||||
|
all threads. */
|
||||||
|
static int soft_interrupt_requested = 0;
|
||||||
|
|
||||||
|
/* Non zero if the inferior is stopped in a simulated breakpoint done
|
||||||
|
by suspending all the threads. */
|
||||||
|
static int faked_breakpoint = 0;
|
||||||
|
|
||||||
#define NUM_REGS (the_low_target.num_regs)
|
#define NUM_REGS (the_low_target.num_regs)
|
||||||
|
|
||||||
typedef BOOL WINAPI (*winapi_DebugActiveProcessStop) (DWORD dwProcessId);
|
typedef BOOL WINAPI (*winapi_DebugActiveProcessStop) (DWORD dwProcessId);
|
||||||
@ -134,8 +142,7 @@ child_add_thread (DWORD tid, HANDLE h)
|
|||||||
if ((th = thread_rec (tid, FALSE)))
|
if ((th = thread_rec (tid, FALSE)))
|
||||||
return th;
|
return th;
|
||||||
|
|
||||||
th = (win32_thread_info *) malloc (sizeof (*th));
|
th = calloc (1, sizeof (*th));
|
||||||
memset (th, 0, sizeof (*th));
|
|
||||||
th->tid = tid;
|
th->tid = tid;
|
||||||
th->h = h;
|
th->h = h;
|
||||||
|
|
||||||
@ -293,14 +300,17 @@ continue_one_thread (struct inferior_list_entry *this_thread, void *id_ptr)
|
|||||||
static BOOL
|
static BOOL
|
||||||
child_continue (DWORD continue_status, int thread_id)
|
child_continue (DWORD continue_status, int thread_id)
|
||||||
{
|
{
|
||||||
BOOL res;
|
/* The inferior will only continue after the ContinueDebugEvent
|
||||||
|
call. */
|
||||||
|
find_inferior (&all_threads, continue_one_thread, &thread_id);
|
||||||
|
faked_breakpoint = 0;
|
||||||
|
|
||||||
res = ContinueDebugEvent (current_event.dwProcessId,
|
if (!ContinueDebugEvent (current_event.dwProcessId,
|
||||||
current_event.dwThreadId, continue_status);
|
current_event.dwThreadId,
|
||||||
if (res)
|
continue_status))
|
||||||
find_inferior (&all_threads, continue_one_thread, &thread_id);
|
return FALSE;
|
||||||
|
|
||||||
return res;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fetch register(s) from the current thread context. */
|
/* Fetch register(s) from the current thread context. */
|
||||||
@ -1247,19 +1257,67 @@ handle_exception (struct target_waitstatus *ourstatus)
|
|||||||
last_sig = ourstatus->value.sig;
|
last_sig = ourstatus->value.sig;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the next event from the child. */
|
|
||||||
static void
|
static void
|
||||||
|
suspend_one_thread (struct inferior_list_entry *entry)
|
||||||
|
{
|
||||||
|
struct thread_info *thread = (struct thread_info *) entry;
|
||||||
|
win32_thread_info *th = inferior_target_data (thread);
|
||||||
|
|
||||||
|
if (!th->suspended)
|
||||||
|
{
|
||||||
|
if (SuspendThread (th->h) == (DWORD) -1)
|
||||||
|
{
|
||||||
|
DWORD err = GetLastError ();
|
||||||
|
OUTMSG (("warning: SuspendThread failed in suspend_one_thread, "
|
||||||
|
"(error %d): %s\n", (int) err, strwinerror (err)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
th->suspended = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fake_breakpoint_event (void)
|
||||||
|
{
|
||||||
|
OUTMSG2(("fake_breakpoint_event\n"));
|
||||||
|
|
||||||
|
faked_breakpoint = 1;
|
||||||
|
|
||||||
|
memset (¤t_event, 0, sizeof (current_event));
|
||||||
|
current_event.dwThreadId = main_thread_id;
|
||||||
|
current_event.dwDebugEventCode = EXCEPTION_DEBUG_EVENT;
|
||||||
|
current_event.u.Exception.ExceptionRecord.ExceptionCode
|
||||||
|
= EXCEPTION_BREAKPOINT;
|
||||||
|
|
||||||
|
for_each_inferior (&all_threads, suspend_one_thread);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the next event from the child. */
|
||||||
|
|
||||||
|
static int
|
||||||
get_child_debug_event (struct target_waitstatus *ourstatus)
|
get_child_debug_event (struct target_waitstatus *ourstatus)
|
||||||
{
|
{
|
||||||
BOOL debug_event;
|
|
||||||
|
|
||||||
last_sig = TARGET_SIGNAL_0;
|
last_sig = TARGET_SIGNAL_0;
|
||||||
ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
|
ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
|
||||||
|
|
||||||
/* Keep the wait time low enough for confortable remote interruption,
|
/* Check if GDB sent us an interrupt request. */
|
||||||
but high enough so gdbserver doesn't become a bottleneck. */
|
check_remote_input_interrupt_request ();
|
||||||
if (!(debug_event = WaitForDebugEvent (¤t_event, 250)))
|
|
||||||
return;
|
if (soft_interrupt_requested)
|
||||||
|
{
|
||||||
|
soft_interrupt_requested = 0;
|
||||||
|
fake_breakpoint_event ();
|
||||||
|
goto gotevent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Keep the wait time low enough for confortable remote
|
||||||
|
interruption, but high enough so gdbserver doesn't become a
|
||||||
|
bottleneck. */
|
||||||
|
if (!WaitForDebugEvent (¤t_event, 250))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
gotevent:
|
||||||
|
|
||||||
current_inferior =
|
current_inferior =
|
||||||
(struct thread_info *) find_inferior_id (&all_threads,
|
(struct thread_info *) find_inferior_id (&all_threads,
|
||||||
@ -1376,6 +1434,7 @@ get_child_debug_event (struct target_waitstatus *ourstatus)
|
|||||||
current_inferior =
|
current_inferior =
|
||||||
(struct thread_info *) find_inferior_id (&all_threads,
|
(struct thread_info *) find_inferior_id (&all_threads,
|
||||||
current_event.dwThreadId);
|
current_event.dwThreadId);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wait for the inferior process to change state.
|
/* Wait for the inferior process to change state.
|
||||||
@ -1390,10 +1449,8 @@ win32_wait (char *status)
|
|||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
/* Check if GDB sent us an interrupt request. */
|
if (!get_child_debug_event (&our_status))
|
||||||
check_remote_input_interrupt_request ();
|
continue;
|
||||||
|
|
||||||
get_child_debug_event (&our_status);
|
|
||||||
|
|
||||||
switch (our_status.kind)
|
switch (our_status.kind)
|
||||||
{
|
{
|
||||||
@ -1500,7 +1557,8 @@ win32_request_interrupt (void)
|
|||||||
&& DebugBreakProcess (current_process_handle))
|
&& DebugBreakProcess (current_process_handle))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
OUTMSG (("Could not interrupt process.\n"));
|
/* Last resort, suspend all threads manually. */
|
||||||
|
soft_interrupt_requested = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
|
Reference in New Issue
Block a user