mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2025-02-21 01:53:05 +00:00
* Makefile.in (mingw-hdep.o, posix-hdep.o, remote-fileio.o): Update.
* event-loop.c (call_async_signal_handler): New. * event-loop.h (call_async_signal_handler) (gdb_call_async_signal_handler): Declare. (mark_async_signal_handler): Add comments. * event-top.c (handle_sigint): Use gdb_call_async_signal_handler. * mingw-hdep.c (sigint_event, sigint_handler): New. (gdb_select): Use them. Wait for the readline signal handler to finish. (gdb_call_async_signal_handler, _initialize_mingw_hdep): New functions. * posix-hdep.c (gdb_call_async_signal_handler): New function. * remote-fileio.c (sigint_fileio_token, async_remote_fileio_interrupt): New. (remote_fileio_ctrl_c_signal_handler): Use gdb_call_async_signal_handler. (initialize_remote_fileio): Initialize sigint_fileio_token. * remote.c (initialize_sigint_signal_handler, handle_remote_sigint): Do not initialize tokens here. (handle_remote_sigint_twice): Likewise. Reinstall handle_remote_sigint. (async_remote_interrupt_twice): Just call interrupt_query. (cleanup_sigint_signal_handler): Do not delete tokens. (remote_interrupt, remote_interrupt_twice): Use gdb_call_async_signal_handler. (interrupt_query): Reinstall the default signal handler. (_initialize_remote): Initialize tokens here.
This commit is contained in:
parent
7e8064706d
commit
b803fb0f0f
@ -1,3 +1,32 @@
|
||||
2008-03-05 Daniel Jacobowitz <dan@codesourcery.com>
|
||||
|
||||
* Makefile.in (mingw-hdep.o, posix-hdep.o, remote-fileio.o): Update.
|
||||
* event-loop.c (call_async_signal_handler): New.
|
||||
* event-loop.h (call_async_signal_handler)
|
||||
(gdb_call_async_signal_handler): Declare.
|
||||
(mark_async_signal_handler): Add comments.
|
||||
* event-top.c (handle_sigint): Use gdb_call_async_signal_handler.
|
||||
* mingw-hdep.c (sigint_event, sigint_handler): New.
|
||||
(gdb_select): Use them. Wait for the readline signal handler
|
||||
to finish.
|
||||
(gdb_call_async_signal_handler, _initialize_mingw_hdep): New functions.
|
||||
* posix-hdep.c (gdb_call_async_signal_handler): New function.
|
||||
* remote-fileio.c (sigint_fileio_token, async_remote_fileio_interrupt):
|
||||
New.
|
||||
(remote_fileio_ctrl_c_signal_handler): Use
|
||||
gdb_call_async_signal_handler.
|
||||
(initialize_remote_fileio): Initialize sigint_fileio_token.
|
||||
* remote.c (initialize_sigint_signal_handler, handle_remote_sigint): Do
|
||||
not initialize tokens here.
|
||||
(handle_remote_sigint_twice): Likewise. Reinstall
|
||||
handle_remote_sigint.
|
||||
(async_remote_interrupt_twice): Just call interrupt_query.
|
||||
(cleanup_sigint_signal_handler): Do not delete tokens.
|
||||
(remote_interrupt, remote_interrupt_twice): Use
|
||||
gdb_call_async_signal_handler.
|
||||
(interrupt_query): Reinstall the default signal handler.
|
||||
(_initialize_remote): Initialize tokens here.
|
||||
|
||||
2008-03-04 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
* features/rs6000/power-core.xml, features/rs6000/power64-core.xml,
|
||||
|
@ -2456,8 +2456,8 @@ mep-tdep.o: $(defs_h) $(frame_h) $(frame_unwind_h) $(frame_base_h) \
|
||||
$(floatformat_h) $(sim_regno_h) $(disasm_h) $(trad_frame_h) \
|
||||
$(reggroups_h) $(elf_bfd_h) $(elf_mep_h) $(gdb_assert_h) \
|
||||
$(mep_desc_h) $(mep_opc_h) $(prologue_value_h) $(infcall_h)
|
||||
mingw-hdep.o: mingw-hdep.c $(defs_h) $(serial_h) $(gdb_assert_h) \
|
||||
$(gdb_select_h) $(gdb_string_h)
|
||||
mingw-hdep.o: mingw-hdep.c $(defs_h) $(serial_h) $(event_loop_h) \
|
||||
$(gdb_assert_h) $(gdb_select_h) $(gdb_string_h) $(readline_h)
|
||||
minsyms.o: minsyms.c $(defs_h) $(gdb_string_h) $(symtab_h) $(bfd_h) \
|
||||
$(symfile_h) $(objfiles_h) $(demangle_h) $(value_h) $(cp_abi_h)
|
||||
mips64obsd-nat.o: mips64obsd-nat.c $(defs_h) $(inferior_h) $(regcache_h) \
|
||||
@ -2554,7 +2554,8 @@ p-exp.o: p-exp.c $(defs_h) $(gdb_string_h) $(expression_h) $(value_h) \
|
||||
p-lang.o: p-lang.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \
|
||||
$(expression_h) $(parser_defs_h) $(language_h) $(p_lang_h) \
|
||||
$(valprint_h) $(value_h)
|
||||
posix-hdep.o: posix-hdep.c $(defs_h) $(gdb_string_h) $(gdb_select_h)
|
||||
posix-hdep.o: posix-hdep.c $(defs_h) $(event_loop_h) $(gdb_string_h) \
|
||||
$(gdb_select_h)
|
||||
ppcbug-rom.o: ppcbug-rom.c $(defs_h) $(gdbcore_h) $(target_h) $(monitor_h) \
|
||||
$(serial_h) $(regcache_h)
|
||||
ppc-linux-nat.o: ppc-linux-nat.c $(defs_h) $(gdb_string_h) $(frame_h) \
|
||||
@ -2625,7 +2626,7 @@ remote.o: remote.c $(defs_h) $(gdb_string_h) $(inferior_h) $(bfd_h) \
|
||||
$(target_descriptions_h) $(gdb_fileio_h)
|
||||
remote-fileio.o: remote-fileio.c $(defs_h) $(gdb_string_h) $(gdbcmd_h) \
|
||||
$(remote_h) $(gdb_fileio_h) $(gdb_wait_h) $(gdb_stat_h) \
|
||||
$(exceptions_h) $(remote_fileio_h)
|
||||
$(exceptions_h) $(remote_fileio_h) $(event_loop_h)
|
||||
remote-m32r-sdi.o: remote-m32r-sdi.c $(defs_h) $(gdbcmd_h) $(gdbcore_h) \
|
||||
$(inferior_h) $(target_h) $(regcache_h) $(gdb_string_h) $(serial_h)
|
||||
remote-mips.o: remote-mips.c $(defs_h) $(inferior_h) $(bfd_h) $(symfile_h) \
|
||||
|
@ -891,6 +891,15 @@ create_async_signal_handler (sig_handler_func * proc, gdb_client_data client_dat
|
||||
return async_handler_ptr;
|
||||
}
|
||||
|
||||
/* Call the handler from HANDLER immediately. This function runs
|
||||
signal handlers when returning to the event loop would be too
|
||||
slow. */
|
||||
void
|
||||
call_async_signal_handler (struct async_signal_handler *handler)
|
||||
{
|
||||
(*handler->proc) (handler->client_data);
|
||||
}
|
||||
|
||||
/* Mark the handler (ASYNC_HANDLER_PTR) as ready. This information will
|
||||
be used when the handlers are invoked, after we have waited for
|
||||
some event. The caller of this function is the interrupt handler
|
||||
|
@ -86,9 +86,30 @@ extern void start_event_loop (void);
|
||||
extern int gdb_do_one_event (void *data);
|
||||
extern void delete_file_handler (int fd);
|
||||
extern void add_file_handler (int fd, handler_func * proc, gdb_client_data client_data);
|
||||
extern void mark_async_signal_handler (struct async_signal_handler *async_handler_ptr);
|
||||
extern struct async_signal_handler *
|
||||
create_async_signal_handler (sig_handler_func * proc, gdb_client_data client_data);
|
||||
extern void delete_async_signal_handler (struct async_signal_handler **async_handler_ptr);
|
||||
extern int create_timer (int milliseconds, timer_handler_func * proc, gdb_client_data client_data);
|
||||
extern void delete_timer (int id);
|
||||
|
||||
/* Call the handler from HANDLER immediately. This function
|
||||
runs signal handlers when returning to the event loop would be too
|
||||
slow. Do not call this directly; use gdb_call_async_signal_handler,
|
||||
below, with IMMEDIATE_P == 1. */
|
||||
void call_async_signal_handler (struct async_signal_handler *handler);
|
||||
|
||||
/* Call the handler from HANDLER the next time through the event loop.
|
||||
Do not call this directly; use gdb_call_async_signal_handler,
|
||||
below, with IMMEDIATE_P == 0. */
|
||||
void mark_async_signal_handler (struct async_signal_handler *handler);
|
||||
|
||||
/* Wrapper for the body of signal handlers. Call this function from
|
||||
any SIGINT handler which needs to access GDB data structures or
|
||||
escape via longjmp. If IMMEDIATE_P is set, this triggers either
|
||||
immediately (for POSIX platforms), or from gdb_select (for
|
||||
MinGW). If IMMEDIATE_P is clear, the handler will run the next
|
||||
time we return to the event loop and any current select calls
|
||||
will be interrupted. */
|
||||
|
||||
void gdb_call_async_signal_handler (struct async_signal_handler *handler,
|
||||
int immediate_p);
|
||||
|
@ -975,13 +975,9 @@ handle_sigint (int sig)
|
||||
immediate_quit is set. If we didn't, SIGINT would be really
|
||||
processed only the next time through the event loop. To get to
|
||||
that point, though, the command that we want to interrupt needs to
|
||||
finish first, which is unacceptable. */
|
||||
if (immediate_quit)
|
||||
async_request_quit (0);
|
||||
else
|
||||
/* If immediate quit is not set, we process SIGINT the next time
|
||||
through the loop, which is fine. */
|
||||
mark_async_signal_handler_wrapper (sigint_token);
|
||||
finish first, which is unacceptable. If immediate quit is not set,
|
||||
we process SIGINT the next time through the loop, which is fine. */
|
||||
gdb_call_async_signal_handler (sigint_token, immediate_quit);
|
||||
}
|
||||
|
||||
/* Quit GDB if SIGTERM is received.
|
||||
|
@ -19,13 +19,23 @@
|
||||
|
||||
#include "defs.h"
|
||||
#include "serial.h"
|
||||
#include "event-loop.h"
|
||||
|
||||
#include "gdb_assert.h"
|
||||
#include "gdb_select.h"
|
||||
#include "gdb_string.h"
|
||||
#include "readline/readline.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
/* This event is signalled whenever an asynchronous SIGINT handler
|
||||
needs to perform an action in the main thread. */
|
||||
static HANDLE sigint_event;
|
||||
|
||||
/* When SIGINT_EVENT is signalled, gdb_select will call this
|
||||
function. */
|
||||
struct async_signal_handler *sigint_handler;
|
||||
|
||||
/* The strerror() function can return NULL for errno values that are
|
||||
out of range. Provide a "safe" version that always returns a
|
||||
printable string.
|
||||
@ -141,14 +151,9 @@ gdb_select (int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
||||
handles[num_handles++] = except;
|
||||
}
|
||||
}
|
||||
/* If we don't need to wait for any handles, we are done. */
|
||||
if (!num_handles)
|
||||
{
|
||||
if (timeout)
|
||||
Sleep (timeout->tv_sec * 1000 + timeout->tv_usec / 1000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
gdb_assert (num_handles < MAXIMUM_WAIT_OBJECTS);
|
||||
handles[num_handles++] = sigint_event;
|
||||
|
||||
event = WaitForMultipleObjects (num_handles,
|
||||
handles,
|
||||
@ -203,5 +208,51 @@ gdb_select (int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
||||
}
|
||||
}
|
||||
|
||||
/* With multi-threaded SIGINT handling, there is a race between the
|
||||
readline signal handler and GDB. It may still be in
|
||||
rl_prep_terminal in another thread. Do not return until it is
|
||||
done; we can check the state here because we never longjmp from
|
||||
signal handlers on Windows. */
|
||||
while (RL_ISSTATE (RL_STATE_SIGHANDLER))
|
||||
Sleep (1);
|
||||
|
||||
if (h == sigint_event
|
||||
|| WaitForSingleObject (sigint_event, 0) == WAIT_OBJECT_0)
|
||||
{
|
||||
if (sigint_handler != NULL)
|
||||
call_async_signal_handler (sigint_handler);
|
||||
|
||||
if (num_ready == 0)
|
||||
{
|
||||
errno = EINTR;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return num_ready;
|
||||
}
|
||||
|
||||
/* Wrapper for the body of signal handlers. On Windows systems, a
|
||||
SIGINT handler runs in its own thread. We can't longjmp from
|
||||
there, and we shouldn't even prompt the user. Delay HANDLER
|
||||
until the main thread is next in gdb_select. */
|
||||
|
||||
void
|
||||
gdb_call_async_signal_handler (struct async_signal_handler *handler,
|
||||
int immediate_p)
|
||||
{
|
||||
if (immediate_p)
|
||||
sigint_handler = handler;
|
||||
else
|
||||
{
|
||||
mark_async_signal_handler (handler);
|
||||
sigint_handler = NULL;
|
||||
}
|
||||
SetEvent (sigint_event);
|
||||
}
|
||||
|
||||
void
|
||||
_initialize_mingw_hdep (void)
|
||||
{
|
||||
sigint_event = CreateEvent (0, FALSE, FALSE, 0);
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "event-loop.h"
|
||||
|
||||
#include "gdb_string.h"
|
||||
|
||||
@ -50,3 +51,16 @@ gdb_select (int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
||||
{
|
||||
return select (n, readfds, writefds, exceptfds, timeout);
|
||||
}
|
||||
|
||||
/* Wrapper for the body of signal handlers. Nothing special needed on
|
||||
POSIX platforms. */
|
||||
|
||||
void
|
||||
gdb_call_async_signal_handler (struct async_signal_handler *handler,
|
||||
int immediate_p)
|
||||
{
|
||||
if (immediate_p)
|
||||
call_async_signal_handler (handler);
|
||||
else
|
||||
mark_async_signal_handler (handler);
|
||||
}
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "gdb_stat.h"
|
||||
#include "exceptions.h"
|
||||
#include "remote-fileio.h"
|
||||
#include "event-loop.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <sys/time.h>
|
||||
@ -47,6 +48,8 @@ static struct {
|
||||
|
||||
static int remote_fio_system_call_allowed = 0;
|
||||
|
||||
static struct async_signal_handler *sigint_fileio_token;
|
||||
|
||||
static int
|
||||
remote_fileio_init_fd_map (void)
|
||||
{
|
||||
@ -503,13 +506,19 @@ remote_fileio_sig_exit (void)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
async_remote_fileio_interrupt (gdb_client_data arg)
|
||||
{
|
||||
deprecated_throw_reason (RETURN_QUIT);
|
||||
}
|
||||
|
||||
static void
|
||||
remote_fileio_ctrl_c_signal_handler (int signo)
|
||||
{
|
||||
remote_fileio_sig_set (SIG_IGN);
|
||||
remote_fio_ctrl_c_flag = 1;
|
||||
if (!remote_fio_no_longjmp)
|
||||
deprecated_throw_reason (RETURN_QUIT);
|
||||
gdb_call_async_signal_handler (sigint_fileio_token, 1);
|
||||
remote_fileio_sig_set (remote_fileio_ctrl_c_signal_handler);
|
||||
}
|
||||
|
||||
@ -1451,6 +1460,9 @@ void
|
||||
initialize_remote_fileio (struct cmd_list_element *remote_set_cmdlist,
|
||||
struct cmd_list_element *remote_show_cmdlist)
|
||||
{
|
||||
sigint_fileio_token =
|
||||
create_async_signal_handler (async_remote_fileio_interrupt, NULL);
|
||||
|
||||
add_cmd ("system-call-allowed", no_class,
|
||||
set_system_call_allowed,
|
||||
_("Set if the host system(3) call is allowed for the target."),
|
||||
|
35
gdb/remote.c
35
gdb/remote.c
@ -3158,8 +3158,6 @@ remote_async_resume (ptid_t ptid, int step, enum target_signal siggnal)
|
||||
static void
|
||||
initialize_sigint_signal_handler (void)
|
||||
{
|
||||
sigint_remote_token =
|
||||
create_async_signal_handler (async_remote_interrupt, NULL);
|
||||
signal (SIGINT, handle_remote_sigint);
|
||||
}
|
||||
|
||||
@ -3168,8 +3166,6 @@ static void
|
||||
handle_remote_sigint (int sig)
|
||||
{
|
||||
signal (sig, handle_remote_sigint_twice);
|
||||
sigint_remote_twice_token =
|
||||
create_async_signal_handler (async_remote_interrupt_twice, NULL);
|
||||
mark_async_signal_handler_wrapper (sigint_remote_token);
|
||||
}
|
||||
|
||||
@ -3179,9 +3175,7 @@ handle_remote_sigint (int sig)
|
||||
static void
|
||||
handle_remote_sigint_twice (int sig)
|
||||
{
|
||||
signal (sig, handle_sigint);
|
||||
sigint_remote_twice_token =
|
||||
create_async_signal_handler (inferior_event_handler_wrapper, NULL);
|
||||
signal (sig, handle_remote_sigint);
|
||||
mark_async_signal_handler_wrapper (sigint_remote_twice_token);
|
||||
}
|
||||
|
||||
@ -3203,13 +3197,8 @@ async_remote_interrupt_twice (gdb_client_data arg)
|
||||
{
|
||||
if (remote_debug)
|
||||
fprintf_unfiltered (gdb_stdlog, "remote_interrupt_twice called\n");
|
||||
/* Do something only if the target was not killed by the previous
|
||||
cntl-C. */
|
||||
if (target_executing)
|
||||
{
|
||||
interrupt_query ();
|
||||
signal (SIGINT, handle_remote_sigint);
|
||||
}
|
||||
|
||||
interrupt_query ();
|
||||
}
|
||||
|
||||
/* Reinstall the usual SIGINT handlers, after the target has
|
||||
@ -3218,10 +3207,6 @@ static void
|
||||
cleanup_sigint_signal_handler (void *dummy)
|
||||
{
|
||||
signal (SIGINT, handle_sigint);
|
||||
if (sigint_remote_twice_token)
|
||||
delete_async_signal_handler (&sigint_remote_twice_token);
|
||||
if (sigint_remote_token)
|
||||
delete_async_signal_handler (&sigint_remote_token);
|
||||
}
|
||||
|
||||
/* Send ^C to target to halt it. Target will respond, and send us a
|
||||
@ -3239,10 +3224,7 @@ remote_interrupt (int signo)
|
||||
/* If this doesn't work, try more severe steps. */
|
||||
signal (signo, remote_interrupt_twice);
|
||||
|
||||
if (remote_debug)
|
||||
fprintf_unfiltered (gdb_stdlog, "remote_interrupt called\n");
|
||||
|
||||
target_stop ();
|
||||
gdb_call_async_signal_handler (sigint_remote_token, 1);
|
||||
}
|
||||
|
||||
/* The user typed ^C twice. */
|
||||
@ -3251,7 +3233,7 @@ static void
|
||||
remote_interrupt_twice (int signo)
|
||||
{
|
||||
signal (signo, ofunc);
|
||||
interrupt_query ();
|
||||
gdb_call_async_signal_handler (sigint_remote_twice_token, 1);
|
||||
signal (signo, remote_interrupt);
|
||||
}
|
||||
|
||||
@ -3282,6 +3264,7 @@ interrupt_query (void)
|
||||
Give up (and stop debugging it)? "))
|
||||
{
|
||||
target_mourn_inferior ();
|
||||
signal (SIGINT, handle_sigint);
|
||||
deprecated_throw_reason (RETURN_QUIT);
|
||||
}
|
||||
|
||||
@ -7507,6 +7490,12 @@ _initialize_remote (void)
|
||||
/* Hook into new objfile notification. */
|
||||
observer_attach_new_objfile (remote_new_objfile);
|
||||
|
||||
/* Set up signal handlers. */
|
||||
sigint_remote_token =
|
||||
create_async_signal_handler (async_remote_interrupt, NULL);
|
||||
sigint_remote_twice_token =
|
||||
create_async_signal_handler (inferior_event_handler_wrapper, NULL);
|
||||
|
||||
#if 0
|
||||
init_remote_threadtests ();
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user