2010-12-28 Michael Snyder <msnyder@vmware.com>
* event-loop.c: Comment clean-up. * event-loop.h: Ditto. * event-top.c: Ditto. * gdb.c: Ditto. * gdb.h: Ditto. * main.c: Ditto. * top.c: Ditto. * top.h: Ditto.
This commit is contained in:
parent
551ce43ca7
commit
371d5dec8e
9 changed files with 500 additions and 454 deletions
|
@ -1,3 +1,14 @@
|
||||||
|
2010-12-28 Michael Snyder <msnyder@vmware.com>
|
||||||
|
|
||||||
|
* event-loop.c: Comment clean-up.
|
||||||
|
* event-loop.h: Ditto.
|
||||||
|
* event-top.c: Ditto.
|
||||||
|
* gdb.c: Ditto.
|
||||||
|
* gdb.h: Ditto.
|
||||||
|
* main.c: Ditto.
|
||||||
|
* top.c: Ditto.
|
||||||
|
* top.h: Ditto.
|
||||||
|
|
||||||
2010-12-28 Pedro Alves <pedro@codesourcery.com>
|
2010-12-28 Pedro Alves <pedro@codesourcery.com>
|
||||||
|
|
||||||
* ax-gdb.c (gen_expr) <OP_REGISTER>: Error out if trying to
|
* ax-gdb.c (gen_expr) <OP_REGISTER>: Error out if trying to
|
||||||
|
|
316
gdb/event-loop.c
316
gdb/event-loop.c
|
@ -16,7 +16,7 @@
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
#include "event-loop.h"
|
#include "event-loop.h"
|
||||||
|
@ -39,7 +39,7 @@
|
||||||
#include "gdb_select.h"
|
#include "gdb_select.h"
|
||||||
|
|
||||||
/* Tell create_file_handler what events we are interested in.
|
/* Tell create_file_handler what events we are interested in.
|
||||||
This is used by the select version of the event loop. */
|
This is used by the select version of the event loop. */
|
||||||
|
|
||||||
#define GDB_READABLE (1<<1)
|
#define GDB_READABLE (1<<1)
|
||||||
#define GDB_WRITABLE (1<<2)
|
#define GDB_WRITABLE (1<<2)
|
||||||
|
@ -56,12 +56,12 @@ typedef struct gdb_event gdb_event;
|
||||||
typedef void (event_handler_func) (event_data);
|
typedef void (event_handler_func) (event_data);
|
||||||
|
|
||||||
/* Event for the GDB event system. Events are queued by calling
|
/* Event for the GDB event system. Events are queued by calling
|
||||||
async_queue_event and serviced later on by gdb_do_one_event. An
|
async_queue_event and serviced later on by gdb_do_one_event. An
|
||||||
event can be, for instance, a file descriptor becoming ready to be
|
event can be, for instance, a file descriptor becoming ready to be
|
||||||
read. Servicing an event simply means that the procedure PROC will
|
read. Servicing an event simply means that the procedure PROC will
|
||||||
be called. We have 2 queues, one for file handlers that we listen
|
be called. We have 2 queues, one for file handlers that we listen
|
||||||
to in the event loop, and one for the file handlers+events that are
|
to in the event loop, and one for the file handlers+events that are
|
||||||
ready. The procedure PROC associated with each event is dependant
|
ready. The procedure PROC associated with each event is dependant
|
||||||
of the event source. In the case of monitored file descriptors, it
|
of the event source. In the case of monitored file descriptors, it
|
||||||
is always the same (handle_file_event). Its duty is to invoke the
|
is always the same (handle_file_event). Its duty is to invoke the
|
||||||
handler associated with the file descriptor whose state change
|
handler associated with the file descriptor whose state change
|
||||||
|
@ -82,36 +82,39 @@ struct gdb_event
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Information about each file descriptor we register with the event
|
/* Information about each file descriptor we register with the event
|
||||||
loop. */
|
loop. */
|
||||||
|
|
||||||
typedef struct file_handler
|
typedef struct file_handler
|
||||||
{
|
{
|
||||||
int fd; /* File descriptor. */
|
int fd; /* File descriptor. */
|
||||||
int mask; /* Events we want to monitor: POLLIN, etc. */
|
int mask; /* Events we want to monitor: POLLIN, etc. */
|
||||||
int ready_mask; /* Events that have been seen since
|
int ready_mask; /* Events that have been seen since
|
||||||
the last time. */
|
the last time. */
|
||||||
handler_func *proc; /* Procedure to call when fd is ready. */
|
handler_func *proc; /* Procedure to call when fd is ready. */
|
||||||
gdb_client_data client_data; /* Argument to pass to proc. */
|
gdb_client_data client_data; /* Argument to pass to proc. */
|
||||||
int error; /* Was an error detected on this fd? */
|
int error; /* Was an error detected on this fd? */
|
||||||
struct file_handler *next_file; /* Next registered file descriptor. */
|
struct file_handler *next_file; /* Next registered file descriptor. */
|
||||||
}
|
}
|
||||||
file_handler;
|
file_handler;
|
||||||
|
|
||||||
/* PROC is a function to be invoked when the READY flag is set. This
|
/* PROC is a function to be invoked when the READY flag is set. This
|
||||||
happens when there has been a signal and the corresponding signal
|
happens when there has been a signal and the corresponding signal
|
||||||
handler has 'triggered' this async_signal_handler for
|
handler has 'triggered' this async_signal_handler for execution.
|
||||||
execution. The actual work to be done in response to a signal will
|
The actual work to be done in response to a signal will be carried
|
||||||
be carried out by PROC at a later time, within process_event. This
|
out by PROC at a later time, within process_event. This provides a
|
||||||
provides a deferred execution of signal handlers.
|
deferred execution of signal handlers.
|
||||||
|
|
||||||
Async_init_signals takes care of setting up such an
|
Async_init_signals takes care of setting up such an
|
||||||
async_signal_handler for each interesting signal. */
|
async_signal_handler for each interesting signal. */
|
||||||
|
|
||||||
typedef struct async_signal_handler
|
typedef struct async_signal_handler
|
||||||
{
|
{
|
||||||
int ready; /* If ready, call this handler from the main event loop,
|
int ready; /* If ready, call this handler
|
||||||
using invoke_async_handler. */
|
from the main event loop, using
|
||||||
struct async_signal_handler *next_handler; /* Ptr to next handler */
|
invoke_async_handler. */
|
||||||
sig_handler_func *proc; /* Function to call to do the work */
|
struct async_signal_handler *next_handler; /* Ptr to next handler. */
|
||||||
gdb_client_data client_data; /* Argument to async_handler_func */
|
sig_handler_func *proc; /* Function to call to do the work. */
|
||||||
|
gdb_client_data client_data; /* Argument to async_handler_func. */
|
||||||
}
|
}
|
||||||
async_signal_handler;
|
async_signal_handler;
|
||||||
|
|
||||||
|
@ -150,25 +153,25 @@ async_event_handler;
|
||||||
the queue will be processed in a last in first out fashion, while
|
the queue will be processed in a last in first out fashion, while
|
||||||
those inserted at the tail of the queue will be processed in a first
|
those inserted at the tail of the queue will be processed in a first
|
||||||
in first out manner. All the fields are NULL if the queue is
|
in first out manner. All the fields are NULL if the queue is
|
||||||
empty. */
|
empty. */
|
||||||
|
|
||||||
static struct
|
static struct
|
||||||
{
|
{
|
||||||
gdb_event *first_event; /* First pending event */
|
gdb_event *first_event; /* First pending event. */
|
||||||
gdb_event *last_event; /* Last pending event */
|
gdb_event *last_event; /* Last pending event. */
|
||||||
}
|
}
|
||||||
event_queue;
|
event_queue;
|
||||||
|
|
||||||
/* Gdb_notifier is just a list of file descriptors gdb is interested in.
|
/* Gdb_notifier is just a list of file descriptors gdb is interested in.
|
||||||
These are the input file descriptor, and the target file
|
These are the input file descriptor, and the target file
|
||||||
descriptor. We have two flavors of the notifier, one for platforms
|
descriptor. We have two flavors of the notifier, one for platforms
|
||||||
that have the POLL function, the other for those that don't, and
|
that have the POLL function, the other for those that don't, and
|
||||||
only support SELECT. Each of the elements in the gdb_notifier list is
|
only support SELECT. Each of the elements in the gdb_notifier list is
|
||||||
basically a description of what kind of events gdb is interested
|
basically a description of what kind of events gdb is interested
|
||||||
in, for each fd. */
|
in, for each fd. */
|
||||||
|
|
||||||
/* As of 1999-04-30 only the input file descriptor is registered with the
|
/* As of 1999-04-30 only the input file descriptor is registered with the
|
||||||
event loop. */
|
event loop. */
|
||||||
|
|
||||||
/* Do we use poll or select ? */
|
/* Do we use poll or select ? */
|
||||||
#ifdef HAVE_POLL
|
#ifdef HAVE_POLL
|
||||||
|
@ -186,79 +189,79 @@ static unsigned char use_poll = USE_POLL;
|
||||||
|
|
||||||
static struct
|
static struct
|
||||||
{
|
{
|
||||||
/* Ptr to head of file handler list. */
|
/* Ptr to head of file handler list. */
|
||||||
file_handler *first_file_handler;
|
file_handler *first_file_handler;
|
||||||
|
|
||||||
#ifdef HAVE_POLL
|
#ifdef HAVE_POLL
|
||||||
/* Ptr to array of pollfd structures. */
|
/* Ptr to array of pollfd structures. */
|
||||||
struct pollfd *poll_fds;
|
struct pollfd *poll_fds;
|
||||||
|
|
||||||
/* Timeout in milliseconds for calls to poll(). */
|
/* Timeout in milliseconds for calls to poll(). */
|
||||||
int poll_timeout;
|
int poll_timeout;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Masks to be used in the next call to select.
|
/* Masks to be used in the next call to select.
|
||||||
Bits are set in response to calls to create_file_handler. */
|
Bits are set in response to calls to create_file_handler. */
|
||||||
fd_set check_masks[3];
|
fd_set check_masks[3];
|
||||||
|
|
||||||
/* What file descriptors were found ready by select. */
|
/* What file descriptors were found ready by select. */
|
||||||
fd_set ready_masks[3];
|
fd_set ready_masks[3];
|
||||||
|
|
||||||
/* Number of file descriptors to monitor. (for poll) */
|
/* Number of file descriptors to monitor (for poll). */
|
||||||
/* Number of valid bits (highest fd value + 1). (for select) */
|
/* Number of valid bits (highest fd value + 1) (for select). */
|
||||||
int num_fds;
|
int num_fds;
|
||||||
|
|
||||||
/* Time structure for calls to select(). */
|
/* Time structure for calls to select(). */
|
||||||
struct timeval select_timeout;
|
struct timeval select_timeout;
|
||||||
|
|
||||||
/* Flag to tell whether the timeout should be used. */
|
/* Flag to tell whether the timeout should be used. */
|
||||||
int timeout_valid;
|
int timeout_valid;
|
||||||
}
|
}
|
||||||
gdb_notifier;
|
gdb_notifier;
|
||||||
|
|
||||||
/* Structure associated with a timer. PROC will be executed at the
|
/* Structure associated with a timer. PROC will be executed at the
|
||||||
first occasion after WHEN. */
|
first occasion after WHEN. */
|
||||||
struct gdb_timer
|
struct gdb_timer
|
||||||
{
|
{
|
||||||
struct timeval when;
|
struct timeval when;
|
||||||
int timer_id;
|
int timer_id;
|
||||||
struct gdb_timer *next;
|
struct gdb_timer *next;
|
||||||
timer_handler_func *proc; /* Function to call to do the work */
|
timer_handler_func *proc; /* Function to call to do the work. */
|
||||||
gdb_client_data client_data; /* Argument to async_handler_func */
|
gdb_client_data client_data; /* Argument to async_handler_func. */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* List of currently active timers. It is sorted in order of
|
/* List of currently active timers. It is sorted in order of
|
||||||
increasing timers. */
|
increasing timers. */
|
||||||
static struct
|
static struct
|
||||||
{
|
{
|
||||||
/* Pointer to first in timer list. */
|
/* Pointer to first in timer list. */
|
||||||
struct gdb_timer *first_timer;
|
struct gdb_timer *first_timer;
|
||||||
|
|
||||||
/* Id of the last timer created. */
|
/* Id of the last timer created. */
|
||||||
int num_timers;
|
int num_timers;
|
||||||
}
|
}
|
||||||
timer_list;
|
timer_list;
|
||||||
|
|
||||||
/* All the async_signal_handlers gdb is interested in are kept onto
|
/* All the async_signal_handlers gdb is interested in are kept onto
|
||||||
this list. */
|
this list. */
|
||||||
static struct
|
static struct
|
||||||
{
|
{
|
||||||
/* Pointer to first in handler list. */
|
/* Pointer to first in handler list. */
|
||||||
async_signal_handler *first_handler;
|
async_signal_handler *first_handler;
|
||||||
|
|
||||||
/* Pointer to last in handler list. */
|
/* Pointer to last in handler list. */
|
||||||
async_signal_handler *last_handler;
|
async_signal_handler *last_handler;
|
||||||
}
|
}
|
||||||
sighandler_list;
|
sighandler_list;
|
||||||
|
|
||||||
/* All the async_event_handlers gdb is interested in are kept onto
|
/* All the async_event_handlers gdb is interested in are kept onto
|
||||||
this list. */
|
this list. */
|
||||||
static struct
|
static struct
|
||||||
{
|
{
|
||||||
/* Pointer to first in handler list. */
|
/* Pointer to first in handler list. */
|
||||||
async_event_handler *first_handler;
|
async_event_handler *first_handler;
|
||||||
|
|
||||||
/* Pointer to last in handler list. */
|
/* Pointer to last in handler list. */
|
||||||
async_event_handler *last_handler;
|
async_event_handler *last_handler;
|
||||||
}
|
}
|
||||||
async_event_handler_list;
|
async_event_handler_list;
|
||||||
|
@ -276,18 +279,18 @@ static void poll_timers (void);
|
||||||
the specified position.
|
the specified position.
|
||||||
POSITION can be head or tail, with values TAIL, HEAD.
|
POSITION can be head or tail, with values TAIL, HEAD.
|
||||||
EVENT_PTR points to the event to be inserted into the queue.
|
EVENT_PTR points to the event to be inserted into the queue.
|
||||||
The caller must allocate memory for the event. It is freed
|
The caller must allocate memory for the event. It is freed
|
||||||
after the event has ben handled.
|
after the event has ben handled.
|
||||||
Events in the queue will be processed head to tail, therefore,
|
Events in the queue will be processed head to tail, therefore,
|
||||||
events inserted at the head of the queue will be processed
|
events inserted at the head of the queue will be processed
|
||||||
as last in first out. Event appended at the tail of the queue
|
as last in first out. Event appended at the tail of the queue
|
||||||
will be processed first in first out. */
|
will be processed first in first out. */
|
||||||
static void
|
static void
|
||||||
async_queue_event (gdb_event * event_ptr, queue_position position)
|
async_queue_event (gdb_event * event_ptr, queue_position position)
|
||||||
{
|
{
|
||||||
if (position == TAIL)
|
if (position == TAIL)
|
||||||
{
|
{
|
||||||
/* The event will become the new last_event. */
|
/* The event will become the new last_event. */
|
||||||
|
|
||||||
event_ptr->next_event = NULL;
|
event_ptr->next_event = NULL;
|
||||||
if (event_queue.first_event == NULL)
|
if (event_queue.first_event == NULL)
|
||||||
|
@ -298,7 +301,7 @@ async_queue_event (gdb_event * event_ptr, queue_position position)
|
||||||
}
|
}
|
||||||
else if (position == HEAD)
|
else if (position == HEAD)
|
||||||
{
|
{
|
||||||
/* The event becomes the new first_event. */
|
/* The event becomes the new first_event. */
|
||||||
|
|
||||||
event_ptr->next_event = event_queue.first_event;
|
event_ptr->next_event = event_queue.first_event;
|
||||||
if (event_queue.first_event == NULL)
|
if (event_queue.first_event == NULL)
|
||||||
|
@ -324,9 +327,9 @@ create_event (event_handler_func proc, event_data data)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create a file event, to be enqueued in the event queue for
|
/* Create a file event, to be enqueued in the event queue for
|
||||||
processing. The procedure associated to this event is always
|
processing. The procedure associated to this event is always
|
||||||
handle_file_event, which will in turn invoke the one that was
|
handle_file_event, which will in turn invoke the one that was
|
||||||
associated to FD when it was registered with the event loop. */
|
associated to FD when it was registered with the event loop. */
|
||||||
static gdb_event *
|
static gdb_event *
|
||||||
create_file_event (int fd)
|
create_file_event (int fd)
|
||||||
{
|
{
|
||||||
|
@ -344,7 +347,7 @@ create_file_event (int fd)
|
||||||
0 is returned.
|
0 is returned.
|
||||||
Scan the queue from head to tail, processing therefore the high
|
Scan the queue from head to tail, processing therefore the high
|
||||||
priority events first, by invoking the associated event handler
|
priority events first, by invoking the associated event handler
|
||||||
procedure. */
|
procedure. */
|
||||||
static int
|
static int
|
||||||
process_event (void)
|
process_event (void)
|
||||||
{
|
{
|
||||||
|
@ -353,19 +356,19 @@ process_event (void)
|
||||||
event_data data;
|
event_data data;
|
||||||
|
|
||||||
/* First let's see if there are any asynchronous event handlers that
|
/* First let's see if there are any asynchronous event handlers that
|
||||||
are ready. These would be the result of invoking any of the
|
are ready. These would be the result of invoking any of the
|
||||||
signal handlers. */
|
signal handlers. */
|
||||||
|
|
||||||
if (invoke_async_signal_handlers ())
|
if (invoke_async_signal_handlers ())
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/* Look in the event queue to find an event that is ready
|
/* Look in the event queue to find an event that is ready
|
||||||
to be processed. */
|
to be processed. */
|
||||||
|
|
||||||
for (event_ptr = event_queue.first_event; event_ptr != NULL;
|
for (event_ptr = event_queue.first_event; event_ptr != NULL;
|
||||||
event_ptr = event_ptr->next_event)
|
event_ptr = event_ptr->next_event)
|
||||||
{
|
{
|
||||||
/* Call the handler for the event. */
|
/* Call the handler for the event. */
|
||||||
|
|
||||||
proc = event_ptr->proc;
|
proc = event_ptr->proc;
|
||||||
data = event_ptr->data;
|
data = event_ptr->data;
|
||||||
|
@ -373,9 +376,9 @@ process_event (void)
|
||||||
/* Let's get rid of the event from the event queue. We need to
|
/* Let's get rid of the event from the event queue. We need to
|
||||||
do this now because while processing the event, the proc
|
do this now because while processing the event, the proc
|
||||||
function could end up calling 'error' and therefore jump out
|
function could end up calling 'error' and therefore jump out
|
||||||
to the caller of this function, gdb_do_one_event. In that
|
to the caller of this function, gdb_do_one_event. In that
|
||||||
case, we would have on the event queue an event wich has been
|
case, we would have on the event queue an event wich has been
|
||||||
processed, but not deleted. */
|
processed, but not deleted. */
|
||||||
|
|
||||||
if (event_queue.first_event == event_ptr)
|
if (event_queue.first_event == event_ptr)
|
||||||
{
|
{
|
||||||
|
@ -395,12 +398,12 @@ process_event (void)
|
||||||
}
|
}
|
||||||
xfree (event_ptr);
|
xfree (event_ptr);
|
||||||
|
|
||||||
/* Now call the procedure associated with the event. */
|
/* Now call the procedure associated with the event. */
|
||||||
(*proc) (data);
|
(*proc) (data);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* this is the case if there are no event on the event queue. */
|
/* This is the case if there are no event on the event queue. */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -408,7 +411,7 @@ process_event (void)
|
||||||
wait for something to happen (via gdb_wait_for_event), then process
|
wait for something to happen (via gdb_wait_for_event), then process
|
||||||
it. Returns >0 if something was done otherwise returns <0 (this
|
it. Returns >0 if something was done otherwise returns <0 (this
|
||||||
can happen if there are no event sources to wait for). If an error
|
can happen if there are no event sources to wait for). If an error
|
||||||
occurs catch_errors() which calls this function returns zero. */
|
occurs catch_errors() which calls this function returns zero. */
|
||||||
|
|
||||||
int
|
int
|
||||||
gdb_do_one_event (void *data)
|
gdb_do_one_event (void *data)
|
||||||
|
@ -429,7 +432,7 @@ gdb_do_one_event (void *data)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
/* Are any timers that are ready? If so, put an event on the
|
/* Are any timers that are ready? If so, put an event on the
|
||||||
queue. */
|
queue. */
|
||||||
poll_timers ();
|
poll_timers ();
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -469,18 +472,18 @@ gdb_do_one_event (void *data)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Start up the event loop. This is the entry point to the event loop
|
/* Start up the event loop. This is the entry point to the event loop
|
||||||
from the command loop. */
|
from the command loop. */
|
||||||
|
|
||||||
void
|
void
|
||||||
start_event_loop (void)
|
start_event_loop (void)
|
||||||
{
|
{
|
||||||
/* Loop until there is nothing to do. This is the entry point to the
|
/* Loop until there is nothing to do. This is the entry point to the
|
||||||
event loop engine. gdb_do_one_event, called via catch_errors()
|
event loop engine. gdb_do_one_event, called via catch_errors()
|
||||||
will process one event for each invocation. It blocks waits for
|
will process one event for each invocation. It blocks waits for
|
||||||
an event and then processes it. >0 when an event is processed, 0
|
an event and then processes it. >0 when an event is processed, 0
|
||||||
when catch_errors() caught an error and <0 when there are no
|
when catch_errors() caught an error and <0 when there are no
|
||||||
longer any event sources registered. */
|
longer any event sources registered. */
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
int gdb_result;
|
int gdb_result;
|
||||||
|
@ -491,7 +494,7 @@ start_event_loop (void)
|
||||||
|
|
||||||
/* If we long-jumped out of do_one_event, we probably
|
/* If we long-jumped out of do_one_event, we probably
|
||||||
didn't get around to resetting the prompt, which leaves
|
didn't get around to resetting the prompt, which leaves
|
||||||
readline in a messed-up state. Reset it here. */
|
readline in a messed-up state. Reset it here. */
|
||||||
|
|
||||||
if (gdb_result == 0)
|
if (gdb_result == 0)
|
||||||
{
|
{
|
||||||
|
@ -501,7 +504,7 @@ start_event_loop (void)
|
||||||
async_enable_stdin ();
|
async_enable_stdin ();
|
||||||
/* FIXME: this should really be a call to a hook that is
|
/* FIXME: this should really be a call to a hook that is
|
||||||
interface specific, because interfaces can display the
|
interface specific, because interfaces can display the
|
||||||
prompt in their own way. */
|
prompt in their own way. */
|
||||||
display_gdb_prompt (0);
|
display_gdb_prompt (0);
|
||||||
/* This call looks bizarre, but it is required. If the user
|
/* This call looks bizarre, but it is required. If the user
|
||||||
entered a command that caused an error,
|
entered a command that caused an error,
|
||||||
|
@ -512,19 +515,19 @@ start_event_loop (void)
|
||||||
if (after_char_processing_hook)
|
if (after_char_processing_hook)
|
||||||
(*after_char_processing_hook) ();
|
(*after_char_processing_hook) ();
|
||||||
/* Maybe better to set a flag to be checked somewhere as to
|
/* Maybe better to set a flag to be checked somewhere as to
|
||||||
whether display the prompt or not. */
|
whether display the prompt or not. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We are done with the event loop. There are no more event sources
|
/* We are done with the event loop. There are no more event sources
|
||||||
to listen to. So we exit GDB. */
|
to listen to. So we exit GDB. */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Wrapper function for create_file_handler, so that the caller
|
/* Wrapper function for create_file_handler, so that the caller
|
||||||
doesn't have to know implementation details about the use of poll
|
doesn't have to know implementation details about the use of poll
|
||||||
vs. select. */
|
vs. select. */
|
||||||
void
|
void
|
||||||
add_file_handler (int fd, handler_func * proc, gdb_client_data client_data)
|
add_file_handler (int fd, handler_func * proc, gdb_client_data client_data)
|
||||||
{
|
{
|
||||||
|
@ -535,11 +538,11 @@ add_file_handler (int fd, handler_func * proc, gdb_client_data client_data)
|
||||||
if (use_poll)
|
if (use_poll)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_POLL
|
#ifdef HAVE_POLL
|
||||||
/* Check to see if poll () is usable. If not, we'll switch to
|
/* Check to see if poll () is usable. If not, we'll switch to
|
||||||
use select. This can happen on systems like
|
use select. This can happen on systems like
|
||||||
m68k-motorola-sys, `poll' cannot be used to wait for `stdin'.
|
m68k-motorola-sys, `poll' cannot be used to wait for `stdin'.
|
||||||
On m68k-motorola-sysv, tty's are not stream-based and not
|
On m68k-motorola-sysv, tty's are not stream-based and not
|
||||||
`poll'able. */
|
`poll'able. */
|
||||||
fds.fd = fd;
|
fds.fd = fd;
|
||||||
fds.events = POLLIN;
|
fds.events = POLLIN;
|
||||||
if (poll (&fds, 1, 0) == 1 && (fds.revents & POLLNVAL))
|
if (poll (&fds, 1, 0) == 1 && (fds.revents & POLLNVAL))
|
||||||
|
@ -559,26 +562,32 @@ add_file_handler (int fd, handler_func * proc, gdb_client_data client_data)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
create_file_handler (fd, GDB_READABLE | GDB_EXCEPTION, proc, client_data);
|
create_file_handler (fd, GDB_READABLE | GDB_EXCEPTION,
|
||||||
|
proc, client_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add a file handler/descriptor to the list of descriptors we are
|
/* Add a file handler/descriptor to the list of descriptors we are
|
||||||
interested in.
|
interested in.
|
||||||
|
|
||||||
FD is the file descriptor for the file/stream to be listened to.
|
FD is the file descriptor for the file/stream to be listened to.
|
||||||
For the poll case, MASK is a combination (OR) of
|
|
||||||
POLLIN, POLLRDNORM, POLLRDBAND, POLLPRI, POLLOUT, POLLWRNORM,
|
For the poll case, MASK is a combination (OR) of POLLIN,
|
||||||
POLLWRBAND: these are the events we are interested in. If any of them
|
POLLRDNORM, POLLRDBAND, POLLPRI, POLLOUT, POLLWRNORM, POLLWRBAND:
|
||||||
occurs, proc should be called.
|
these are the events we are interested in. If any of them occurs,
|
||||||
For the select case, MASK is a combination of READABLE, WRITABLE, EXCEPTION.
|
proc should be called.
|
||||||
PROC is the procedure that will be called when an event occurs for
|
|
||||||
FD. CLIENT_DATA is the argument to pass to PROC. */
|
For the select case, MASK is a combination of READABLE, WRITABLE,
|
||||||
|
EXCEPTION. PROC is the procedure that will be called when an event
|
||||||
|
occurs for FD. CLIENT_DATA is the argument to pass to PROC. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
create_file_handler (int fd, int mask, handler_func * proc, gdb_client_data client_data)
|
create_file_handler (int fd, int mask, handler_func * proc,
|
||||||
|
gdb_client_data client_data)
|
||||||
{
|
{
|
||||||
file_handler *file_ptr;
|
file_handler *file_ptr;
|
||||||
|
|
||||||
/* Do we already have a file handler for this file? (We may be
|
/* Do we already have a file handler for this file? (We may be
|
||||||
changing its associated procedure). */
|
changing its associated procedure). */
|
||||||
for (file_ptr = gdb_notifier.first_file_handler; file_ptr != NULL;
|
for (file_ptr = gdb_notifier.first_file_handler; file_ptr != NULL;
|
||||||
file_ptr = file_ptr->next_file)
|
file_ptr = file_ptr->next_file)
|
||||||
{
|
{
|
||||||
|
@ -586,8 +595,8 @@ create_file_handler (int fd, int mask, handler_func * proc, gdb_client_data clie
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* It is a new file descriptor. Add it to the list. Otherwise, just
|
/* It is a new file descriptor. Add it to the list. Otherwise, just
|
||||||
change the data associated with it. */
|
change the data associated with it. */
|
||||||
if (file_ptr == NULL)
|
if (file_ptr == NULL)
|
||||||
{
|
{
|
||||||
file_ptr = (file_handler *) xmalloc (sizeof (file_handler));
|
file_ptr = (file_handler *) xmalloc (sizeof (file_handler));
|
||||||
|
@ -644,7 +653,7 @@ create_file_handler (int fd, int mask, handler_func * proc, gdb_client_data clie
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove the file descriptor FD from the list of monitored fd's:
|
/* Remove the file descriptor FD from the list of monitored fd's:
|
||||||
i.e. we don't care anymore about events on the FD. */
|
i.e. we don't care anymore about events on the FD. */
|
||||||
void
|
void
|
||||||
delete_file_handler (int fd)
|
delete_file_handler (int fd)
|
||||||
{
|
{
|
||||||
|
@ -655,7 +664,7 @@ delete_file_handler (int fd)
|
||||||
struct pollfd *new_poll_fds;
|
struct pollfd *new_poll_fds;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Find the entry for the given file. */
|
/* Find the entry for the given file. */
|
||||||
|
|
||||||
for (file_ptr = gdb_notifier.first_file_handler; file_ptr != NULL;
|
for (file_ptr = gdb_notifier.first_file_handler; file_ptr != NULL;
|
||||||
file_ptr = file_ptr->next_file)
|
file_ptr = file_ptr->next_file)
|
||||||
|
@ -670,11 +679,11 @@ delete_file_handler (int fd)
|
||||||
if (use_poll)
|
if (use_poll)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_POLL
|
#ifdef HAVE_POLL
|
||||||
/* Create a new poll_fds array by copying every fd's information but the
|
/* Create a new poll_fds array by copying every fd's information
|
||||||
one we want to get rid of. */
|
but the one we want to get rid of. */
|
||||||
|
|
||||||
new_poll_fds =
|
new_poll_fds = (struct pollfd *)
|
||||||
(struct pollfd *) xmalloc ((gdb_notifier.num_fds - 1) * sizeof (struct pollfd));
|
xmalloc ((gdb_notifier.num_fds - 1) * sizeof (struct pollfd));
|
||||||
|
|
||||||
for (i = 0, j = 0; i < gdb_notifier.num_fds; i++)
|
for (i = 0, j = 0; i < gdb_notifier.num_fds; i++)
|
||||||
{
|
{
|
||||||
|
@ -703,7 +712,7 @@ delete_file_handler (int fd)
|
||||||
if (file_ptr->mask & GDB_EXCEPTION)
|
if (file_ptr->mask & GDB_EXCEPTION)
|
||||||
FD_CLR (fd, &gdb_notifier.check_masks[2]);
|
FD_CLR (fd, &gdb_notifier.check_masks[2]);
|
||||||
|
|
||||||
/* Find current max fd. */
|
/* Find current max fd. */
|
||||||
|
|
||||||
if ((fd + 1) == gdb_notifier.num_fds)
|
if ((fd + 1) == gdb_notifier.num_fds)
|
||||||
{
|
{
|
||||||
|
@ -720,11 +729,11 @@ delete_file_handler (int fd)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Deactivate the file descriptor, by clearing its mask,
|
/* Deactivate the file descriptor, by clearing its mask,
|
||||||
so that it will not fire again. */
|
so that it will not fire again. */
|
||||||
|
|
||||||
file_ptr->mask = 0;
|
file_ptr->mask = 0;
|
||||||
|
|
||||||
/* Get rid of the file handler in the file handler list. */
|
/* Get rid of the file handler in the file handler list. */
|
||||||
if (file_ptr == gdb_notifier.first_file_handler)
|
if (file_ptr == gdb_notifier.first_file_handler)
|
||||||
gdb_notifier.first_file_handler = file_ptr->next_file;
|
gdb_notifier.first_file_handler = file_ptr->next_file;
|
||||||
else
|
else
|
||||||
|
@ -741,7 +750,7 @@ delete_file_handler (int fd)
|
||||||
/* Handle the given event by calling the procedure associated to the
|
/* Handle the given event by calling the procedure associated to the
|
||||||
corresponding file handler. Called by process_event indirectly,
|
corresponding file handler. Called by process_event indirectly,
|
||||||
through event_ptr->proc. EVENT_FILE_DESC is file descriptor of the
|
through event_ptr->proc. EVENT_FILE_DESC is file descriptor of the
|
||||||
event in the front of the event queue. */
|
event in the front of the event queue. */
|
||||||
static void
|
static void
|
||||||
handle_file_event (event_data data)
|
handle_file_event (event_data data)
|
||||||
{
|
{
|
||||||
|
@ -754,21 +763,21 @@ handle_file_event (event_data data)
|
||||||
int event_file_desc = data.integer;
|
int event_file_desc = data.integer;
|
||||||
|
|
||||||
/* Search the file handler list to find one that matches the fd in
|
/* Search the file handler list to find one that matches the fd in
|
||||||
the event. */
|
the event. */
|
||||||
for (file_ptr = gdb_notifier.first_file_handler; file_ptr != NULL;
|
for (file_ptr = gdb_notifier.first_file_handler; file_ptr != NULL;
|
||||||
file_ptr = file_ptr->next_file)
|
file_ptr = file_ptr->next_file)
|
||||||
{
|
{
|
||||||
if (file_ptr->fd == event_file_desc)
|
if (file_ptr->fd == event_file_desc)
|
||||||
{
|
{
|
||||||
/* With poll, the ready_mask could have any of three events
|
/* With poll, the ready_mask could have any of three events
|
||||||
set to 1: POLLHUP, POLLERR, POLLNVAL. These events cannot
|
set to 1: POLLHUP, POLLERR, POLLNVAL. These events
|
||||||
be used in the requested event mask (events), but they
|
cannot be used in the requested event mask (events), but
|
||||||
can be returned in the return mask (revents). We need to
|
they can be returned in the return mask (revents). We
|
||||||
check for those event too, and add them to the mask which
|
need to check for those event too, and add them to the
|
||||||
will be passed to the handler. */
|
mask which will be passed to the handler. */
|
||||||
|
|
||||||
/* See if the desired events (mask) match the received
|
/* See if the desired events (mask) match the received
|
||||||
events (ready_mask). */
|
events (ready_mask). */
|
||||||
|
|
||||||
if (use_poll)
|
if (use_poll)
|
||||||
{
|
{
|
||||||
|
@ -780,8 +789,8 @@ handle_file_event (event_data data)
|
||||||
|
|
||||||
if (error_mask_returned != 0)
|
if (error_mask_returned != 0)
|
||||||
{
|
{
|
||||||
/* Work in progress. We may need to tell somebody what
|
/* Work in progress. We may need to tell somebody
|
||||||
kind of error we had. */
|
what kind of error we had. */
|
||||||
if (error_mask_returned & POLLHUP)
|
if (error_mask_returned & POLLHUP)
|
||||||
printf_unfiltered (_("Hangup detected on fd %d\n"), file_ptr->fd);
|
printf_unfiltered (_("Hangup detected on fd %d\n"), file_ptr->fd);
|
||||||
if (error_mask_returned & POLLERR)
|
if (error_mask_returned & POLLERR)
|
||||||
|
@ -809,10 +818,10 @@ handle_file_event (event_data data)
|
||||||
mask = file_ptr->ready_mask & file_ptr->mask;
|
mask = file_ptr->ready_mask & file_ptr->mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear the received events for next time around. */
|
/* Clear the received events for next time around. */
|
||||||
file_ptr->ready_mask = 0;
|
file_ptr->ready_mask = 0;
|
||||||
|
|
||||||
/* If there was a match, then call the handler. */
|
/* If there was a match, then call the handler. */
|
||||||
if (mask != 0)
|
if (mask != 0)
|
||||||
(*file_ptr->proc) (file_ptr->error, file_ptr->client_data);
|
(*file_ptr->proc) (file_ptr->error, file_ptr->client_data);
|
||||||
break;
|
break;
|
||||||
|
@ -823,8 +832,8 @@ handle_file_event (event_data data)
|
||||||
/* Called by gdb_do_one_event to wait for new events on the monitored
|
/* Called by gdb_do_one_event to wait for new events on the monitored
|
||||||
file descriptors. Queue file events as they are detected by the
|
file descriptors. Queue file events as they are detected by the
|
||||||
poll. If BLOCK and if there are no events, this function will
|
poll. If BLOCK and if there are no events, this function will
|
||||||
block in the call to poll. Return -1 if there are no files
|
block in the call to poll. Return -1 if there are no file
|
||||||
descriptors to monitor, otherwise return 0. */
|
descriptors to monitor, otherwise return 0. */
|
||||||
static int
|
static int
|
||||||
gdb_wait_for_event (int block)
|
gdb_wait_for_event (int block)
|
||||||
{
|
{
|
||||||
|
@ -833,7 +842,7 @@ gdb_wait_for_event (int block)
|
||||||
int num_found = 0;
|
int num_found = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Make sure all output is done before getting another event. */
|
/* Make sure all output is done before getting another event. */
|
||||||
gdb_flush (gdb_stdout);
|
gdb_flush (gdb_stdout);
|
||||||
gdb_flush (gdb_stderr);
|
gdb_flush (gdb_stderr);
|
||||||
|
|
||||||
|
@ -885,7 +894,7 @@ gdb_wait_for_event (int block)
|
||||||
&gdb_notifier.ready_masks[2],
|
&gdb_notifier.ready_masks[2],
|
||||||
timeout_p);
|
timeout_p);
|
||||||
|
|
||||||
/* Clear the masks after an error from select. */
|
/* Clear the masks after an error from select. */
|
||||||
if (num_found == -1)
|
if (num_found == -1)
|
||||||
{
|
{
|
||||||
FD_ZERO (&gdb_notifier.ready_masks[0]);
|
FD_ZERO (&gdb_notifier.ready_masks[0]);
|
||||||
|
@ -899,7 +908,7 @@ gdb_wait_for_event (int block)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enqueue all detected file events. */
|
/* Enqueue all detected file events. */
|
||||||
|
|
||||||
if (use_poll)
|
if (use_poll)
|
||||||
{
|
{
|
||||||
|
@ -922,7 +931,7 @@ gdb_wait_for_event (int block)
|
||||||
if (file_ptr)
|
if (file_ptr)
|
||||||
{
|
{
|
||||||
/* Enqueue an event only if this is still a new event for
|
/* Enqueue an event only if this is still a new event for
|
||||||
this fd. */
|
this fd. */
|
||||||
if (file_ptr->ready_mask == 0)
|
if (file_ptr->ready_mask == 0)
|
||||||
{
|
{
|
||||||
file_event_ptr = create_file_event (file_ptr->fd);
|
file_event_ptr = create_file_event (file_ptr->fd);
|
||||||
|
@ -957,7 +966,7 @@ gdb_wait_for_event (int block)
|
||||||
num_found--;
|
num_found--;
|
||||||
|
|
||||||
/* Enqueue an event only if this is still a new event for
|
/* Enqueue an event only if this is still a new event for
|
||||||
this fd. */
|
this fd. */
|
||||||
|
|
||||||
if (file_ptr->ready_mask == 0)
|
if (file_ptr->ready_mask == 0)
|
||||||
{
|
{
|
||||||
|
@ -976,7 +985,7 @@ gdb_wait_for_event (int block)
|
||||||
This pointer will be used to invoke the handler by
|
This pointer will be used to invoke the handler by
|
||||||
invoke_async_signal_handler.
|
invoke_async_signal_handler.
|
||||||
PROC is the function to call with CLIENT_DATA argument
|
PROC is the function to call with CLIENT_DATA argument
|
||||||
whenever the handler is invoked. */
|
whenever the handler is invoked. */
|
||||||
async_signal_handler *
|
async_signal_handler *
|
||||||
create_async_signal_handler (sig_handler_func * proc, gdb_client_data client_data)
|
create_async_signal_handler (sig_handler_func * proc, gdb_client_data client_data)
|
||||||
{
|
{
|
||||||
|
@ -1005,10 +1014,10 @@ call_async_signal_handler (struct async_signal_handler *handler)
|
||||||
(*handler->proc) (handler->client_data);
|
(*handler->proc) (handler->client_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mark the handler (ASYNC_HANDLER_PTR) as ready. This information will
|
/* Mark the handler (ASYNC_HANDLER_PTR) as ready. This information
|
||||||
be used when the handlers are invoked, after we have waited for
|
will be used when the handlers are invoked, after we have waited
|
||||||
some event. The caller of this function is the interrupt handler
|
for some event. The caller of this function is the interrupt
|
||||||
associated with a signal. */
|
handler associated with a signal. */
|
||||||
void
|
void
|
||||||
mark_async_signal_handler (async_signal_handler * async_handler_ptr)
|
mark_async_signal_handler (async_signal_handler * async_handler_ptr)
|
||||||
{
|
{
|
||||||
|
@ -1177,19 +1186,20 @@ delete_async_event_handler (async_event_handler **async_handler_ptr)
|
||||||
*async_handler_ptr = NULL;
|
*async_handler_ptr = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create a timer that will expire in MILLISECONDS from now. When the
|
/* Create a timer that will expire in MILLISECONDS from now. When the
|
||||||
timer is ready, PROC will be executed. At creation, the timer is
|
timer is ready, PROC will be executed. At creation, the timer is
|
||||||
aded to the timers queue. This queue is kept sorted in order of
|
aded to the timers queue. This queue is kept sorted in order of
|
||||||
increasing timers. Return a handle to the timer struct. */
|
increasing timers. Return a handle to the timer struct. */
|
||||||
int
|
int
|
||||||
create_timer (int milliseconds, timer_handler_func * proc, gdb_client_data client_data)
|
create_timer (int milliseconds, timer_handler_func * proc,
|
||||||
|
gdb_client_data client_data)
|
||||||
{
|
{
|
||||||
struct gdb_timer *timer_ptr, *timer_index, *prev_timer;
|
struct gdb_timer *timer_ptr, *timer_index, *prev_timer;
|
||||||
struct timeval time_now, delta;
|
struct timeval time_now, delta;
|
||||||
|
|
||||||
/* compute seconds */
|
/* Compute seconds. */
|
||||||
delta.tv_sec = milliseconds / 1000;
|
delta.tv_sec = milliseconds / 1000;
|
||||||
/* compute microseconds */
|
/* Compute microseconds. */
|
||||||
delta.tv_usec = (milliseconds % 1000) * 1000;
|
delta.tv_usec = (milliseconds % 1000) * 1000;
|
||||||
|
|
||||||
gettimeofday (&time_now, NULL);
|
gettimeofday (&time_now, NULL);
|
||||||
|
@ -1197,7 +1207,7 @@ create_timer (int milliseconds, timer_handler_func * proc, gdb_client_data clien
|
||||||
timer_ptr = (struct gdb_timer *) xmalloc (sizeof (*timer_ptr));
|
timer_ptr = (struct gdb_timer *) xmalloc (sizeof (*timer_ptr));
|
||||||
timer_ptr->when.tv_sec = time_now.tv_sec + delta.tv_sec;
|
timer_ptr->when.tv_sec = time_now.tv_sec + delta.tv_sec;
|
||||||
timer_ptr->when.tv_usec = time_now.tv_usec + delta.tv_usec;
|
timer_ptr->when.tv_usec = time_now.tv_usec + delta.tv_usec;
|
||||||
/* carry? */
|
/* Carry? */
|
||||||
if (timer_ptr->when.tv_usec >= 1000000)
|
if (timer_ptr->when.tv_usec >= 1000000)
|
||||||
{
|
{
|
||||||
timer_ptr->when.tv_sec += 1;
|
timer_ptr->when.tv_sec += 1;
|
||||||
|
@ -1209,14 +1219,14 @@ create_timer (int milliseconds, timer_handler_func * proc, gdb_client_data clien
|
||||||
timer_ptr->timer_id = timer_list.num_timers;
|
timer_ptr->timer_id = timer_list.num_timers;
|
||||||
|
|
||||||
/* Now add the timer to the timer queue, making sure it is sorted in
|
/* Now add the timer to the timer queue, making sure it is sorted in
|
||||||
increasing order of expiration. */
|
increasing order of expiration. */
|
||||||
|
|
||||||
for (timer_index = timer_list.first_timer;
|
for (timer_index = timer_list.first_timer;
|
||||||
timer_index != NULL;
|
timer_index != NULL;
|
||||||
timer_index = timer_index->next)
|
timer_index = timer_index->next)
|
||||||
{
|
{
|
||||||
/* If the seconds field is greater or if it is the same, but the
|
/* If the seconds field is greater or if it is the same, but the
|
||||||
microsecond field is greater. */
|
microsecond field is greater. */
|
||||||
if ((timer_index->when.tv_sec > timer_ptr->when.tv_sec)
|
if ((timer_index->when.tv_sec > timer_ptr->when.tv_sec)
|
||||||
|| ((timer_index->when.tv_sec == timer_ptr->when.tv_sec)
|
|| ((timer_index->when.tv_sec == timer_ptr->when.tv_sec)
|
||||||
&& (timer_index->when.tv_usec > timer_ptr->when.tv_usec)))
|
&& (timer_index->when.tv_usec > timer_ptr->when.tv_usec)))
|
||||||
|
@ -1245,13 +1255,13 @@ create_timer (int milliseconds, timer_handler_func * proc, gdb_client_data clien
|
||||||
}
|
}
|
||||||
|
|
||||||
/* There is a chance that the creator of the timer wants to get rid of
|
/* There is a chance that the creator of the timer wants to get rid of
|
||||||
it before it expires. */
|
it before it expires. */
|
||||||
void
|
void
|
||||||
delete_timer (int id)
|
delete_timer (int id)
|
||||||
{
|
{
|
||||||
struct gdb_timer *timer_ptr, *prev_timer = NULL;
|
struct gdb_timer *timer_ptr, *prev_timer = NULL;
|
||||||
|
|
||||||
/* Find the entry for the given timer. */
|
/* Find the entry for the given timer. */
|
||||||
|
|
||||||
for (timer_ptr = timer_list.first_timer; timer_ptr != NULL;
|
for (timer_ptr = timer_list.first_timer; timer_ptr != NULL;
|
||||||
timer_ptr = timer_ptr->next)
|
timer_ptr = timer_ptr->next)
|
||||||
|
@ -1262,7 +1272,7 @@ delete_timer (int id)
|
||||||
|
|
||||||
if (timer_ptr == NULL)
|
if (timer_ptr == NULL)
|
||||||
return;
|
return;
|
||||||
/* Get rid of the timer in the timer list. */
|
/* Get rid of the timer in the timer list. */
|
||||||
if (timer_ptr == timer_list.first_timer)
|
if (timer_ptr == timer_list.first_timer)
|
||||||
timer_list.first_timer = timer_ptr->next;
|
timer_list.first_timer = timer_ptr->next;
|
||||||
else
|
else
|
||||||
|
@ -1298,11 +1308,11 @@ handle_timer_event (event_data dummy)
|
||||||
&& (timer_ptr->when.tv_usec > time_now.tv_usec)))
|
&& (timer_ptr->when.tv_usec > time_now.tv_usec)))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Get rid of the timer from the beginning of the list. */
|
/* Get rid of the timer from the beginning of the list. */
|
||||||
timer_list.first_timer = timer_ptr->next;
|
timer_list.first_timer = timer_ptr->next;
|
||||||
saved_timer = timer_ptr;
|
saved_timer = timer_ptr;
|
||||||
timer_ptr = timer_ptr->next;
|
timer_ptr = timer_ptr->next;
|
||||||
/* Call the procedure associated with that timer. */
|
/* Call the procedure associated with that timer. */
|
||||||
(*saved_timer->proc) (saved_timer->client_data);
|
(*saved_timer->proc) (saved_timer->client_data);
|
||||||
xfree (saved_timer);
|
xfree (saved_timer);
|
||||||
}
|
}
|
||||||
|
@ -1310,12 +1320,12 @@ handle_timer_event (event_data dummy)
|
||||||
gdb_notifier.timeout_valid = 0;
|
gdb_notifier.timeout_valid = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check whether any timers in the timers queue are ready. If at least
|
/* Check whether any timers in the timers queue are ready. If at least
|
||||||
one timer is ready, stick an event onto the event queue. Even in
|
one timer is ready, stick an event onto the event queue. Even in
|
||||||
case more than one timer is ready, one event is enough, because the
|
case more than one timer is ready, one event is enough, because the
|
||||||
handle_timer_event() will go through the timers list and call the
|
handle_timer_event() will go through the timers list and call the
|
||||||
procedures associated with all that have expired. Update the
|
procedures associated with all that have expired.l Update the
|
||||||
timeout for the select() or poll() as well. */
|
timeout for the select() or poll() as well. */
|
||||||
static void
|
static void
|
||||||
poll_timers (void)
|
poll_timers (void)
|
||||||
{
|
{
|
||||||
|
@ -1327,15 +1337,15 @@ poll_timers (void)
|
||||||
gettimeofday (&time_now, NULL);
|
gettimeofday (&time_now, NULL);
|
||||||
delta.tv_sec = timer_list.first_timer->when.tv_sec - time_now.tv_sec;
|
delta.tv_sec = timer_list.first_timer->when.tv_sec - time_now.tv_sec;
|
||||||
delta.tv_usec = timer_list.first_timer->when.tv_usec - time_now.tv_usec;
|
delta.tv_usec = timer_list.first_timer->when.tv_usec - time_now.tv_usec;
|
||||||
/* borrow? */
|
/* Borrow? */
|
||||||
if (delta.tv_usec < 0)
|
if (delta.tv_usec < 0)
|
||||||
{
|
{
|
||||||
delta.tv_sec -= 1;
|
delta.tv_sec -= 1;
|
||||||
delta.tv_usec += 1000000;
|
delta.tv_usec += 1000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Oops it expired already. Tell select / poll to return
|
/* Oops it expired already. Tell select / poll to return
|
||||||
immediately. (Cannot simply test if delta.tv_sec is negative
|
immediately. (Cannot simply test if delta.tv_sec is negative
|
||||||
because time_t might be unsigned.) */
|
because time_t might be unsigned.) */
|
||||||
if (timer_list.first_timer->when.tv_sec < time_now.tv_sec
|
if (timer_list.first_timer->when.tv_sec < time_now.tv_sec
|
||||||
|| (timer_list.first_timer->when.tv_sec == time_now.tv_sec
|
|| (timer_list.first_timer->when.tv_sec == time_now.tv_sec
|
||||||
|
@ -1353,8 +1363,8 @@ poll_timers (void)
|
||||||
async_queue_event (event_ptr, TAIL);
|
async_queue_event (event_ptr, TAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now we need to update the timeout for select/ poll, because we
|
/* Now we need to update the timeout for select/ poll, because
|
||||||
don't want to sit there while this timer is expiring. */
|
we don't want to sit there while this timer is expiring. */
|
||||||
if (use_poll)
|
if (use_poll)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_POLL
|
#ifdef HAVE_POLL
|
||||||
|
|
|
@ -18,10 +18,10 @@
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
/* An event loop listens for events from multiple event sources. When
|
/* An event loop listens for events from multiple event sources. When
|
||||||
an event arrives, it is queued and processed by calling the
|
an event arrives, it is queued and processed by calling the
|
||||||
appropriate event handler. The event loop then continues to listen
|
appropriate event handler. The event loop then continues to listen
|
||||||
for more events. An event loop completes when there are no event
|
for more events. An event loop completes when there are no event
|
||||||
sources to listen on. External event sources can be plugged into
|
sources to listen on. External event sources can be plugged into
|
||||||
the loop.
|
the loop.
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@
|
||||||
when the SIGHANDLER_LIST is scanned, the next time through the
|
when the SIGHANDLER_LIST is scanned, the next time through the
|
||||||
infinite loop.
|
infinite loop.
|
||||||
|
|
||||||
Corollary tasks are the creation and deletion of event sources. */
|
Corollary tasks are the creation and deletion of event sources. */
|
||||||
|
|
||||||
typedef void *gdb_client_data;
|
typedef void *gdb_client_data;
|
||||||
struct async_signal_handler;
|
struct async_signal_handler;
|
||||||
|
@ -76,14 +76,14 @@ typedef void (sig_handler_func) (gdb_client_data);
|
||||||
typedef void (async_event_handler_func) (gdb_client_data);
|
typedef void (async_event_handler_func) (gdb_client_data);
|
||||||
typedef void (timer_handler_func) (gdb_client_data);
|
typedef void (timer_handler_func) (gdb_client_data);
|
||||||
|
|
||||||
/* Where to add an event onto the event queue, by queue_event. */
|
/* Where to add an event onto the event queue, by queue_event. */
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
/* Add at tail of queue. It will be processed in first in first
|
/* Add at tail of queue. It will be processed in first in first
|
||||||
out order. */
|
out order. */
|
||||||
TAIL,
|
TAIL,
|
||||||
/* Add at head of queue. It will be processed in last in first out
|
/* Add at head of queue. It will be processed in last in first
|
||||||
order. */
|
out order. */
|
||||||
HEAD
|
HEAD
|
||||||
}
|
}
|
||||||
queue_position;
|
queue_position;
|
||||||
|
@ -93,11 +93,15 @@ queue_position;
|
||||||
extern void start_event_loop (void);
|
extern void start_event_loop (void);
|
||||||
extern int gdb_do_one_event (void *data);
|
extern int gdb_do_one_event (void *data);
|
||||||
extern void delete_file_handler (int fd);
|
extern void delete_file_handler (int fd);
|
||||||
extern void add_file_handler (int fd, handler_func * proc, gdb_client_data client_data);
|
extern void add_file_handler (int fd, handler_func *proc,
|
||||||
|
gdb_client_data client_data);
|
||||||
extern struct async_signal_handler *
|
extern struct async_signal_handler *
|
||||||
create_async_signal_handler (sig_handler_func * proc, gdb_client_data client_data);
|
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 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 int create_timer (int milliseconds,
|
||||||
|
timer_handler_func *proc,
|
||||||
|
gdb_client_data client_data);
|
||||||
extern void delete_timer (int id);
|
extern void delete_timer (int id);
|
||||||
|
|
||||||
/* Call the handler from HANDLER immediately. This function
|
/* Call the handler from HANDLER immediately. This function
|
||||||
|
|
287
gdb/event-top.c
287
gdb/event-top.c
|
@ -18,7 +18,7 @@
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
#include "top.h"
|
#include "top.h"
|
||||||
|
@ -34,10 +34,9 @@
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "gdbthread.h"
|
#include "gdbthread.h"
|
||||||
|
|
||||||
/* For dont_repeat() */
|
#include "gdbcmd.h" /* for dont_repeat() */
|
||||||
#include "gdbcmd.h"
|
|
||||||
|
|
||||||
/* readline include files */
|
/* readline include files. */
|
||||||
#include "readline/readline.h"
|
#include "readline/readline.h"
|
||||||
#include "readline/history.h"
|
#include "readline/history.h"
|
||||||
|
|
||||||
|
@ -50,7 +49,7 @@ static void change_line_handler (void);
|
||||||
static void change_annotation_level (void);
|
static void change_annotation_level (void);
|
||||||
static void command_handler (char *command);
|
static void command_handler (char *command);
|
||||||
|
|
||||||
/* Signal handlers. */
|
/* Signal handlers. */
|
||||||
#ifdef SIGQUIT
|
#ifdef SIGQUIT
|
||||||
static void handle_sigquit (int sig);
|
static void handle_sigquit (int sig);
|
||||||
#endif
|
#endif
|
||||||
|
@ -63,7 +62,7 @@ static void handle_sigwinch (int sig);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Functions to be invoked by the event loop in response to
|
/* Functions to be invoked by the event loop in response to
|
||||||
signals. */
|
signals. */
|
||||||
#if defined (SIGQUIT) || defined (SIGHUP)
|
#if defined (SIGQUIT) || defined (SIGHUP)
|
||||||
static void async_do_nothing (gdb_client_data);
|
static void async_do_nothing (gdb_client_data);
|
||||||
#endif
|
#endif
|
||||||
|
@ -76,65 +75,65 @@ static void async_stop_sig (gdb_client_data);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Readline offers an alternate interface, via callback
|
/* Readline offers an alternate interface, via callback
|
||||||
functions. These are all included in the file callback.c in the
|
functions. These are all included in the file callback.c in the
|
||||||
readline distribution. This file provides (mainly) a function, which
|
readline distribution. This file provides (mainly) a function, which
|
||||||
the event loop uses as callback (i.e. event handler) whenever an event
|
the event loop uses as callback (i.e. event handler) whenever an event
|
||||||
is detected on the standard input file descriptor.
|
is detected on the standard input file descriptor.
|
||||||
readline_callback_read_char is called (by the GDB event loop) whenever
|
readline_callback_read_char is called (by the GDB event loop) whenever
|
||||||
there is a new character ready on the input stream. This function
|
there is a new character ready on the input stream. This function
|
||||||
incrementally builds a buffer internal to readline where it
|
incrementally builds a buffer internal to readline where it
|
||||||
accumulates the line read up to the point of invocation. In the
|
accumulates the line read up to the point of invocation. In the
|
||||||
special case in which the character read is newline, the function
|
special case in which the character read is newline, the function
|
||||||
invokes a GDB supplied callback routine, which does the processing of
|
invokes a GDB supplied callback routine, which does the processing of
|
||||||
a full command line. This latter routine is the asynchronous analog
|
a full command line. This latter routine is the asynchronous analog
|
||||||
of the old command_line_input in gdb. Instead of invoking (and waiting
|
of the old command_line_input in gdb. Instead of invoking (and waiting
|
||||||
for) readline to read the command line and pass it back to
|
for) readline to read the command line and pass it back to
|
||||||
command_loop for processing, the new command_line_handler function has
|
command_loop for processing, the new command_line_handler function has
|
||||||
the command line already available as its parameter. INPUT_HANDLER is
|
the command line already available as its parameter. INPUT_HANDLER is
|
||||||
to be set to the function that readline will invoke when a complete
|
to be set to the function that readline will invoke when a complete
|
||||||
line of input is ready. CALL_READLINE is to be set to the function
|
line of input is ready. CALL_READLINE is to be set to the function
|
||||||
that readline offers as callback to the event_loop. */
|
that readline offers as callback to the event_loop. */
|
||||||
|
|
||||||
void (*input_handler) (char *);
|
void (*input_handler) (char *);
|
||||||
void (*call_readline) (gdb_client_data);
|
void (*call_readline) (gdb_client_data);
|
||||||
|
|
||||||
/* Important variables for the event loop. */
|
/* Important variables for the event loop. */
|
||||||
|
|
||||||
/* This is used to determine if GDB is using the readline library or
|
/* This is used to determine if GDB is using the readline library or
|
||||||
its own simplified form of readline. It is used by the asynchronous
|
its own simplified form of readline. It is used by the asynchronous
|
||||||
form of the set editing command.
|
form of the set editing command.
|
||||||
ezannoni: as of 1999-04-29 I expect that this
|
ezannoni: as of 1999-04-29 I expect that this
|
||||||
variable will not be used after gdb is changed to use the event
|
variable will not be used after gdb is changed to use the event
|
||||||
loop as default engine, and event-top.c is merged into top.c. */
|
loop as default engine, and event-top.c is merged into top.c. */
|
||||||
int async_command_editing_p;
|
int async_command_editing_p;
|
||||||
|
|
||||||
/* This variable contains the new prompt that the user sets with the
|
/* This variable contains the new prompt that the user sets with the
|
||||||
set prompt command. */
|
set prompt command. */
|
||||||
char *new_async_prompt;
|
char *new_async_prompt;
|
||||||
|
|
||||||
/* This is the annotation suffix that will be used when the
|
/* This is the annotation suffix that will be used when the
|
||||||
annotation_level is 2. */
|
annotation_level is 2. */
|
||||||
char *async_annotation_suffix;
|
char *async_annotation_suffix;
|
||||||
|
|
||||||
/* This is used to display the notification of the completion of an
|
/* This is used to display the notification of the completion of an
|
||||||
asynchronous execution command. */
|
asynchronous execution command. */
|
||||||
int exec_done_display_p = 0;
|
int exec_done_display_p = 0;
|
||||||
|
|
||||||
/* This is the file descriptor for the input stream that GDB uses to
|
/* This is the file descriptor for the input stream that GDB uses to
|
||||||
read commands from. */
|
read commands from. */
|
||||||
int input_fd;
|
int input_fd;
|
||||||
|
|
||||||
/* This is the prompt stack. Prompts will be pushed on the stack as
|
/* This is the prompt stack. Prompts will be pushed on the stack as
|
||||||
needed by the different 'kinds' of user inputs GDB is asking
|
needed by the different 'kinds' of user inputs GDB is asking
|
||||||
for. See event-loop.h. */
|
for. See event-loop.h. */
|
||||||
struct prompts the_prompts;
|
struct prompts the_prompts;
|
||||||
|
|
||||||
/* signal handling variables */
|
/* Signal handling variables. */
|
||||||
/* Each of these is a pointer to a function that the event loop will
|
/* Each of these is a pointer to a function that the event loop will
|
||||||
invoke if the corresponding signal has received. The real signal
|
invoke if the corresponding signal has received. The real signal
|
||||||
handlers mark these functions as ready to be executed and the event
|
handlers mark these functions as ready to be executed and the event
|
||||||
loop, in a later iteration, calls them. See the function
|
loop, in a later iteration, calls them. See the function
|
||||||
invoke_async_signal_handler. */
|
invoke_async_signal_handler. */
|
||||||
void *sigint_token;
|
void *sigint_token;
|
||||||
#ifdef SIGHUP
|
#ifdef SIGHUP
|
||||||
void *sighup_token;
|
void *sighup_token;
|
||||||
|
@ -151,10 +150,10 @@ void *sigtstp_token;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Structure to save a partially entered command. This is used when
|
/* Structure to save a partially entered command. This is used when
|
||||||
the user types '\' at the end of a command line. This is necessary
|
the user types '\' at the end of a command line. This is necessary
|
||||||
because each line of input is handled by a different call to
|
because each line of input is handled by a different call to
|
||||||
command_line_handler, and normally there is no state retained
|
command_line_handler, and normally there is no state retained
|
||||||
between different calls. */
|
between different calls. */
|
||||||
int more_to_come = 0;
|
int more_to_come = 0;
|
||||||
|
|
||||||
struct readline_input_state
|
struct readline_input_state
|
||||||
|
@ -169,9 +168,9 @@ readline_input_state;
|
||||||
void (*after_char_processing_hook) ();
|
void (*after_char_processing_hook) ();
|
||||||
|
|
||||||
|
|
||||||
/* Wrapper function for calling into the readline library. The event
|
/* Wrapper function for calling into the readline library. The event
|
||||||
loop expects the callback function to have a paramter, while readline
|
loop expects the callback function to have a paramter, while
|
||||||
expects none. */
|
readline expects none. */
|
||||||
static void
|
static void
|
||||||
rl_callback_read_char_wrapper (gdb_client_data client_data)
|
rl_callback_read_char_wrapper (gdb_client_data client_data)
|
||||||
{
|
{
|
||||||
|
@ -181,21 +180,21 @@ rl_callback_read_char_wrapper (gdb_client_data client_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize all the necessary variables, start the event loop,
|
/* Initialize all the necessary variables, start the event loop,
|
||||||
register readline, and stdin, start the loop. */
|
register readline, and stdin, start the loop. */
|
||||||
void
|
void
|
||||||
cli_command_loop (void)
|
cli_command_loop (void)
|
||||||
{
|
{
|
||||||
/* If we are using readline, set things up and display the first
|
/* If we are using readline, set things up and display the first
|
||||||
prompt, otherwise just print the prompt. */
|
prompt, otherwise just print the prompt. */
|
||||||
if (async_command_editing_p)
|
if (async_command_editing_p)
|
||||||
{
|
{
|
||||||
int length;
|
int length;
|
||||||
char *a_prompt;
|
char *a_prompt;
|
||||||
char *gdb_prompt = get_prompt ();
|
char *gdb_prompt = get_prompt ();
|
||||||
|
|
||||||
/* Tell readline what the prompt to display is and what function it
|
/* Tell readline what the prompt to display is and what function
|
||||||
will need to call after a whole line is read. This also displays
|
it will need to call after a whole line is read. This also
|
||||||
the first prompt. */
|
displays the first prompt. */
|
||||||
length = strlen (PREFIX (0))
|
length = strlen (PREFIX (0))
|
||||||
+ strlen (gdb_prompt) + strlen (SUFFIX (0)) + 1;
|
+ strlen (gdb_prompt) + strlen (SUFFIX (0)) + 1;
|
||||||
a_prompt = (char *) alloca (length);
|
a_prompt = (char *) alloca (length);
|
||||||
|
@ -207,54 +206,54 @@ cli_command_loop (void)
|
||||||
else
|
else
|
||||||
display_gdb_prompt (0);
|
display_gdb_prompt (0);
|
||||||
|
|
||||||
/* Now it's time to start the event loop. */
|
/* Now it's time to start the event loop. */
|
||||||
start_event_loop ();
|
start_event_loop ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Change the function to be invoked every time there is a character
|
/* Change the function to be invoked every time there is a character
|
||||||
ready on stdin. This is used when the user sets the editing off,
|
ready on stdin. This is used when the user sets the editing off,
|
||||||
therefore bypassing readline, and letting gdb handle the input
|
therefore bypassing readline, and letting gdb handle the input
|
||||||
itself, via gdb_readline2. Also it is used in the opposite case in
|
itself, via gdb_readline2. Also it is used in the opposite case in
|
||||||
which the user sets editing on again, by restoring readline
|
which the user sets editing on again, by restoring readline
|
||||||
handling of the input. */
|
handling of the input. */
|
||||||
static void
|
static void
|
||||||
change_line_handler (void)
|
change_line_handler (void)
|
||||||
{
|
{
|
||||||
/* NOTE: this operates on input_fd, not instream. If we are reading
|
/* NOTE: this operates on input_fd, not instream. If we are reading
|
||||||
commands from a file, instream will point to the file. However in
|
commands from a file, instream will point to the file. However in
|
||||||
async mode, we always read commands from a file with editing
|
async mode, we always read commands from a file with editing
|
||||||
off. This means that the 'set editing on/off' will have effect
|
off. This means that the 'set editing on/off' will have effect
|
||||||
only on the interactive session. */
|
only on the interactive session. */
|
||||||
|
|
||||||
if (async_command_editing_p)
|
if (async_command_editing_p)
|
||||||
{
|
{
|
||||||
/* Turn on editing by using readline. */
|
/* Turn on editing by using readline. */
|
||||||
call_readline = rl_callback_read_char_wrapper;
|
call_readline = rl_callback_read_char_wrapper;
|
||||||
input_handler = command_line_handler;
|
input_handler = command_line_handler;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Turn off editing by using gdb_readline2. */
|
/* Turn off editing by using gdb_readline2. */
|
||||||
rl_callback_handler_remove ();
|
rl_callback_handler_remove ();
|
||||||
call_readline = gdb_readline2;
|
call_readline = gdb_readline2;
|
||||||
|
|
||||||
/* Set up the command handler as well, in case we are called as
|
/* Set up the command handler as well, in case we are called as
|
||||||
first thing from .gdbinit. */
|
first thing from .gdbinit. */
|
||||||
input_handler = command_line_handler;
|
input_handler = command_line_handler;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Displays the prompt. The prompt that is displayed is the current
|
/* Displays the prompt. The prompt that is displayed is the current
|
||||||
top of the prompt stack, if the argument NEW_PROMPT is
|
top of the prompt stack, if the argument NEW_PROMPT is
|
||||||
0. Otherwise, it displays whatever NEW_PROMPT is. This is used
|
0. Otherwise, it displays whatever NEW_PROMPT is. This is used
|
||||||
after each gdb command has completed, and in the following cases:
|
after each gdb command has completed, and in the following cases:
|
||||||
1. when the user enters a command line which is ended by '\'
|
1. When the user enters a command line which is ended by '\'
|
||||||
indicating that the command will continue on the next line.
|
indicating that the command will continue on the next line.
|
||||||
In that case the prompt that is displayed is the empty string.
|
In that case the prompt that is displayed is the empty string.
|
||||||
2. When the user is entering 'commands' for a breakpoint, or
|
2. When the user is entering 'commands' for a breakpoint, or
|
||||||
actions for a tracepoint. In this case the prompt will be '>'
|
actions for a tracepoint. In this case the prompt will be '>'
|
||||||
3. Other????
|
3. Other????
|
||||||
FIXME: 2. & 3. not implemented yet for async. */
|
FIXME: 2. & 3. not implemented yet for async. */
|
||||||
void
|
void
|
||||||
display_gdb_prompt (char *new_prompt)
|
display_gdb_prompt (char *new_prompt)
|
||||||
{
|
{
|
||||||
|
@ -276,15 +275,15 @@ display_gdb_prompt (char *new_prompt)
|
||||||
function, readline still tries to do its own display if we
|
function, readline still tries to do its own display if we
|
||||||
don't call rl_callback_handler_install and
|
don't call rl_callback_handler_install and
|
||||||
rl_callback_handler_remove (which readline detects because a
|
rl_callback_handler_remove (which readline detects because a
|
||||||
global variable is not set). If readline did that, it could
|
global variable is not set). If readline did that, it could
|
||||||
mess up gdb signal handlers for SIGINT. Readline assumes
|
mess up gdb signal handlers for SIGINT. Readline assumes
|
||||||
that between calls to rl_set_signals and rl_clear_signals gdb
|
that between calls to rl_set_signals and rl_clear_signals gdb
|
||||||
doesn't do anything with the signal handlers. Well, that's
|
doesn't do anything with the signal handlers. Well, that's
|
||||||
not the case, because when the target executes we change the
|
not the case, because when the target executes we change the
|
||||||
SIGINT signal handler. If we allowed readline to display the
|
SIGINT signal handler. If we allowed readline to display the
|
||||||
prompt, the signal handler change would happen exactly
|
prompt, the signal handler change would happen exactly
|
||||||
between the calls to the above two functions.
|
between the calls to the above two functions.
|
||||||
Calling rl_callback_handler_remove(), does the job. */
|
Calling rl_callback_handler_remove(), does the job. */
|
||||||
|
|
||||||
rl_callback_handler_remove ();
|
rl_callback_handler_remove ();
|
||||||
return;
|
return;
|
||||||
|
@ -292,18 +291,18 @@ display_gdb_prompt (char *new_prompt)
|
||||||
|
|
||||||
if (!new_prompt)
|
if (!new_prompt)
|
||||||
{
|
{
|
||||||
/* Just use the top of the prompt stack. */
|
/* Just use the top of the prompt stack. */
|
||||||
prompt_length = strlen (PREFIX (0)) +
|
prompt_length = strlen (PREFIX (0)) +
|
||||||
strlen (SUFFIX (0)) +
|
strlen (SUFFIX (0)) +
|
||||||
strlen (gdb_prompt) + 1;
|
strlen (gdb_prompt) + 1;
|
||||||
|
|
||||||
new_prompt = (char *) alloca (prompt_length);
|
new_prompt = (char *) alloca (prompt_length);
|
||||||
|
|
||||||
/* Prefix needs to have new line at end. */
|
/* Prefix needs to have new line at end. */
|
||||||
strcpy (new_prompt, PREFIX (0));
|
strcpy (new_prompt, PREFIX (0));
|
||||||
strcat (new_prompt, gdb_prompt);
|
strcat (new_prompt, gdb_prompt);
|
||||||
/* Suffix needs to have a new line at end and \032 \032 at
|
/* Suffix needs to have a new line at end and \032 \032 at
|
||||||
beginning. */
|
beginning. */
|
||||||
strcat (new_prompt, SUFFIX (0));
|
strcat (new_prompt, SUFFIX (0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -312,7 +311,8 @@ display_gdb_prompt (char *new_prompt)
|
||||||
rl_callback_handler_remove ();
|
rl_callback_handler_remove ();
|
||||||
rl_callback_handler_install (new_prompt, input_handler);
|
rl_callback_handler_install (new_prompt, input_handler);
|
||||||
}
|
}
|
||||||
/* new_prompt at this point can be the top of the stack or the one passed in */
|
/* new_prompt at this point can be the top of the stack or the one
|
||||||
|
passed in. */
|
||||||
else if (new_prompt)
|
else if (new_prompt)
|
||||||
{
|
{
|
||||||
/* Don't use a _filtered function here. It causes the assumed
|
/* Don't use a _filtered function here. It causes the assumed
|
||||||
|
@ -324,10 +324,10 @@ display_gdb_prompt (char *new_prompt)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Used when the user requests a different annotation level, with
|
/* Used when the user requests a different annotation level, with
|
||||||
'set annotate'. It pushes a new prompt (with prefix and suffix) on top
|
'set annotate'. It pushes a new prompt (with prefix and suffix) on top
|
||||||
of the prompt stack, if the annotation level desired is 2, otherwise
|
of the prompt stack, if the annotation level desired is 2, otherwise
|
||||||
it pops the top of the prompt stack when we want the annotation level
|
it pops the top of the prompt stack when we want the annotation level
|
||||||
to be the normal ones (1 or 0). */
|
to be the normal ones (1 or 0). */
|
||||||
static void
|
static void
|
||||||
change_annotation_level (void)
|
change_annotation_level (void)
|
||||||
{
|
{
|
||||||
|
@ -336,7 +336,7 @@ change_annotation_level (void)
|
||||||
if (!PREFIX (0) || !PROMPT (0) || !SUFFIX (0))
|
if (!PREFIX (0) || !PROMPT (0) || !SUFFIX (0))
|
||||||
{
|
{
|
||||||
/* The prompt stack has not been initialized to "", we are
|
/* The prompt stack has not been initialized to "", we are
|
||||||
using gdb w/o the --async switch */
|
using gdb w/o the --async switch. */
|
||||||
warning (_("Command has same effect as set annotate"));
|
warning (_("Command has same effect as set annotate"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -345,7 +345,7 @@ change_annotation_level (void)
|
||||||
{
|
{
|
||||||
if (!strcmp (PREFIX (0), "") && !strcmp (SUFFIX (0), ""))
|
if (!strcmp (PREFIX (0), "") && !strcmp (SUFFIX (0), ""))
|
||||||
{
|
{
|
||||||
/* Push a new prompt if the previous annotation_level was not >1. */
|
/* Push a new prompt if the previous annotation_level was not >1. */
|
||||||
prefix = (char *) alloca (strlen (async_annotation_suffix) + 10);
|
prefix = (char *) alloca (strlen (async_annotation_suffix) + 10);
|
||||||
strcpy (prefix, "\n\032\032pre-");
|
strcpy (prefix, "\n\032\032pre-");
|
||||||
strcat (prefix, async_annotation_suffix);
|
strcat (prefix, async_annotation_suffix);
|
||||||
|
@ -363,16 +363,16 @@ change_annotation_level (void)
|
||||||
{
|
{
|
||||||
if (strcmp (PREFIX (0), "") && strcmp (SUFFIX (0), ""))
|
if (strcmp (PREFIX (0), "") && strcmp (SUFFIX (0), ""))
|
||||||
{
|
{
|
||||||
/* Pop the top of the stack, we are going back to annotation < 1. */
|
/* Pop the top of the stack, we are going back to annotation < 1. */
|
||||||
pop_prompt ();
|
pop_prompt ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pushes a new prompt on the prompt stack. Each prompt has three
|
/* Pushes a new prompt on the prompt stack. Each prompt has three
|
||||||
parts: prefix, prompt, suffix. Usually prefix and suffix are empty
|
parts: prefix, prompt, suffix. Usually prefix and suffix are empty
|
||||||
strings, except when the annotation level is 2. Memory is allocated
|
strings, except when the annotation level is 2. Memory is allocated
|
||||||
within xstrdup for the new prompt. */
|
within xstrdup for the new prompt. */
|
||||||
void
|
void
|
||||||
push_prompt (char *prefix, char *prompt, char *suffix)
|
push_prompt (char *prefix, char *prompt, char *suffix)
|
||||||
{
|
{
|
||||||
|
@ -380,8 +380,8 @@ push_prompt (char *prefix, char *prompt, char *suffix)
|
||||||
PREFIX (0) = xstrdup (prefix);
|
PREFIX (0) = xstrdup (prefix);
|
||||||
|
|
||||||
/* Note that this function is used by the set annotate 2
|
/* Note that this function is used by the set annotate 2
|
||||||
command. This is why we take care of saving the old prompt
|
command. This is why we take care of saving the old prompt
|
||||||
in case a new one is not specified. */
|
in case a new one is not specified. */
|
||||||
if (prompt)
|
if (prompt)
|
||||||
PROMPT (0) = xstrdup (prompt);
|
PROMPT (0) = xstrdup (prompt);
|
||||||
else
|
else
|
||||||
|
@ -390,17 +390,18 @@ push_prompt (char *prefix, char *prompt, char *suffix)
|
||||||
SUFFIX (0) = xstrdup (suffix);
|
SUFFIX (0) = xstrdup (suffix);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pops the top of the prompt stack, and frees the memory allocated for it. */
|
/* Pops the top of the prompt stack, and frees the memory allocated
|
||||||
|
for it. */
|
||||||
void
|
void
|
||||||
pop_prompt (void)
|
pop_prompt (void)
|
||||||
{
|
{
|
||||||
/* If we are not during a 'synchronous' execution command, in which
|
/* If we are not during a 'synchronous' execution command, in which
|
||||||
case, the top prompt would be empty. */
|
case, the top prompt would be empty. */
|
||||||
if (strcmp (PROMPT (0), ""))
|
if (strcmp (PROMPT (0), ""))
|
||||||
/* This is for the case in which the prompt is set while the
|
/* This is for the case in which the prompt is set while the
|
||||||
annotation level is 2. The top prompt will be changed, but when
|
annotation level is 2. The top prompt will be changed, but when
|
||||||
we return to annotation level < 2, we want that new prompt to be
|
we return to annotation level < 2, we want that new prompt to be
|
||||||
in effect, until the user does another 'set prompt'. */
|
in effect, until the user does another 'set prompt'. */
|
||||||
if (strcmp (PROMPT (0), PROMPT (-1)))
|
if (strcmp (PROMPT (0), PROMPT (-1)))
|
||||||
{
|
{
|
||||||
xfree (PROMPT (-1));
|
xfree (PROMPT (-1));
|
||||||
|
@ -416,7 +417,7 @@ pop_prompt (void)
|
||||||
/* When there is an event ready on the stdin file desriptor, instead
|
/* When there is an event ready on the stdin file desriptor, instead
|
||||||
of calling readline directly throught the callback function, or
|
of calling readline directly throught the callback function, or
|
||||||
instead of calling gdb_readline2, give gdb a chance to detect
|
instead of calling gdb_readline2, give gdb a chance to detect
|
||||||
errors and do something. */
|
errors and do something. */
|
||||||
void
|
void
|
||||||
stdin_event_handler (int error, gdb_client_data client_data)
|
stdin_event_handler (int error, gdb_client_data client_data)
|
||||||
{
|
{
|
||||||
|
@ -426,7 +427,7 @@ stdin_event_handler (int error, gdb_client_data client_data)
|
||||||
delete_file_handler (input_fd);
|
delete_file_handler (input_fd);
|
||||||
discard_all_continuations ();
|
discard_all_continuations ();
|
||||||
discard_all_intermediate_continuations ();
|
discard_all_intermediate_continuations ();
|
||||||
/* If stdin died, we may as well kill gdb. */
|
/* If stdin died, we may as well kill gdb. */
|
||||||
quit_command ((char *) 0, stdin == instream);
|
quit_command ((char *) 0, stdin == instream);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -435,17 +436,17 @@ stdin_event_handler (int error, gdb_client_data client_data)
|
||||||
|
|
||||||
/* Re-enable stdin after the end of an execution command in
|
/* Re-enable stdin after the end of an execution command in
|
||||||
synchronous mode, or after an error from the target, and we aborted
|
synchronous mode, or after an error from the target, and we aborted
|
||||||
the exec operation. */
|
the exec operation. */
|
||||||
|
|
||||||
void
|
void
|
||||||
async_enable_stdin (void)
|
async_enable_stdin (void)
|
||||||
{
|
{
|
||||||
if (sync_execution)
|
if (sync_execution)
|
||||||
{
|
{
|
||||||
/* See NOTE in async_disable_stdin() */
|
/* See NOTE in async_disable_stdin(). */
|
||||||
/* FIXME: cagney/1999-09-27: Call this before clearing
|
/* FIXME: cagney/1999-09-27: Call this before clearing
|
||||||
sync_execution. Current target_terminal_ours() implementations
|
sync_execution. Current target_terminal_ours() implementations
|
||||||
check for sync_execution before switching the terminal. */
|
check for sync_execution before switching the terminal. */
|
||||||
target_terminal_ours ();
|
target_terminal_ours ();
|
||||||
pop_prompt ();
|
pop_prompt ();
|
||||||
sync_execution = 0;
|
sync_execution = 0;
|
||||||
|
@ -453,7 +454,7 @@ async_enable_stdin (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disable reads from stdin (the console) marking the command as
|
/* Disable reads from stdin (the console) marking the command as
|
||||||
synchronous. */
|
synchronous. */
|
||||||
|
|
||||||
void
|
void
|
||||||
async_disable_stdin (void)
|
async_disable_stdin (void)
|
||||||
|
@ -466,12 +467,12 @@ async_disable_stdin (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Handles a gdb command. This function is called by
|
/* Handles a gdb command. This function is called by
|
||||||
command_line_handler, which has processed one or more input lines
|
command_line_handler, which has processed one or more input lines
|
||||||
into COMMAND. */
|
into COMMAND. */
|
||||||
/* NOTE: 1999-04-30 This is the asynchronous version of the command_loop
|
/* NOTE: 1999-04-30 This is the asynchronous version of the command_loop
|
||||||
function. The command_loop function will be obsolete when we
|
function. The command_loop function will be obsolete when we
|
||||||
switch to use the event loop at every execution of gdb. */
|
switch to use the event loop at every execution of gdb. */
|
||||||
static void
|
static void
|
||||||
command_handler (char *command)
|
command_handler (char *command)
|
||||||
{
|
{
|
||||||
|
@ -482,11 +483,11 @@ command_handler (char *command)
|
||||||
if (instream == stdin && stdin_is_tty)
|
if (instream == stdin && stdin_is_tty)
|
||||||
reinitialize_more_filter ();
|
reinitialize_more_filter ();
|
||||||
|
|
||||||
/* If readline returned a NULL command, it means that the
|
/* If readline returned a NULL command, it means that the connection
|
||||||
connection with the terminal is gone. This happens at the
|
with the terminal is gone. This happens at the end of a
|
||||||
end of a testsuite run, after Expect has hung up
|
testsuite run, after Expect has hung up but GDB is still alive.
|
||||||
but GDB is still alive. In such a case, we just quit gdb
|
In such a case, we just quit gdb killing the inferior program
|
||||||
killing the inferior program too. */
|
too. */
|
||||||
if (command == 0)
|
if (command == 0)
|
||||||
{
|
{
|
||||||
printf_unfiltered ("quit\n");
|
printf_unfiltered ("quit\n");
|
||||||
|
@ -503,14 +504,15 @@ command_handler (char *command)
|
||||||
do_cleanups (stat_chain);
|
do_cleanups (stat_chain);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle a complete line of input. This is called by the callback
|
/* Handle a complete line of input. This is called by the callback
|
||||||
mechanism within the readline library. Deal with incomplete commands
|
mechanism within the readline library. Deal with incomplete
|
||||||
as well, by saving the partial input in a global buffer. */
|
commands as well, by saving the partial input in a global
|
||||||
|
buffer. */
|
||||||
|
|
||||||
/* NOTE: 1999-04-30 This is the asynchronous version of the
|
/* NOTE: 1999-04-30 This is the asynchronous version of the
|
||||||
command_line_input function. command_line_input will become
|
command_line_input function; command_line_input will become
|
||||||
obsolete once we use the event loop as the default mechanism in
|
obsolete once we use the event loop as the default mechanism in
|
||||||
GDB. */
|
GDB. */
|
||||||
static void
|
static void
|
||||||
command_line_handler (char *rl)
|
command_line_handler (char *rl)
|
||||||
{
|
{
|
||||||
|
@ -555,7 +557,8 @@ command_line_handler (char *rl)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Make sure that all output has been output. Some machines may let
|
/* Make sure that all output has been output. Some machines may let
|
||||||
you get away with leaving out some of the gdb_flush, but not all. */
|
you get away with leaving out some of the gdb_flush, but not
|
||||||
|
all. */
|
||||||
wrap_here ("");
|
wrap_here ("");
|
||||||
gdb_flush (gdb_stdout);
|
gdb_flush (gdb_stdout);
|
||||||
gdb_flush (gdb_stderr);
|
gdb_flush (gdb_stderr);
|
||||||
|
@ -564,12 +567,12 @@ command_line_handler (char *rl)
|
||||||
++source_line_number;
|
++source_line_number;
|
||||||
|
|
||||||
/* If we are in this case, then command_handler will call quit
|
/* If we are in this case, then command_handler will call quit
|
||||||
and exit from gdb. */
|
and exit from gdb. */
|
||||||
if (!rl || rl == (char *) EOF)
|
if (!rl || rl == (char *) EOF)
|
||||||
{
|
{
|
||||||
got_eof = 1;
|
got_eof = 1;
|
||||||
command_handler (0);
|
command_handler (0);
|
||||||
return; /* Lint. */
|
return; /* Lint. */
|
||||||
}
|
}
|
||||||
if (strlen (rl) + 1 + (p - linebuffer) > linelength)
|
if (strlen (rl) + 1 + (p - linebuffer) > linelength)
|
||||||
{
|
{
|
||||||
|
@ -580,7 +583,7 @@ command_line_handler (char *rl)
|
||||||
}
|
}
|
||||||
p1 = rl;
|
p1 = rl;
|
||||||
/* Copy line. Don't copy null at end. (Leaves line alone
|
/* Copy line. Don't copy null at end. (Leaves line alone
|
||||||
if this was just a newline) */
|
if this was just a newline). */
|
||||||
while (*p1)
|
while (*p1)
|
||||||
*p++ = *p1++;
|
*p++ = *p1++;
|
||||||
|
|
||||||
|
@ -595,8 +598,8 @@ command_line_handler (char *rl)
|
||||||
readline_input_state.linebuffer_ptr = p;
|
readline_input_state.linebuffer_ptr = p;
|
||||||
|
|
||||||
/* We will not invoke a execute_command if there is more
|
/* We will not invoke a execute_command if there is more
|
||||||
input expected to complete the command. So, we need to
|
input expected to complete the command. So, we need to
|
||||||
print an empty prompt here. */
|
print an empty prompt here. */
|
||||||
more_to_come = 1;
|
more_to_come = 1;
|
||||||
push_prompt ("", "", "");
|
push_prompt ("", "", "");
|
||||||
display_gdb_prompt (0);
|
display_gdb_prompt (0);
|
||||||
|
@ -654,9 +657,8 @@ command_line_handler (char *rl)
|
||||||
xfree (history_value);
|
xfree (history_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we just got an empty line, and that is supposed
|
/* If we just got an empty line, and that is supposed to repeat the
|
||||||
to repeat the previous command, return the value in the
|
previous command, return the value in the global buffer. */
|
||||||
global buffer. */
|
|
||||||
if (repeat && p == linebuffer && *p != '\\')
|
if (repeat && p == linebuffer && *p != '\\')
|
||||||
{
|
{
|
||||||
command_handler (line);
|
command_handler (line);
|
||||||
|
@ -686,7 +688,7 @@ command_line_handler (char *rl)
|
||||||
and remove the '#'. The kill ring is probably better, but some
|
and remove the '#'. The kill ring is probably better, but some
|
||||||
people are in the habit of commenting things out. */
|
people are in the habit of commenting things out. */
|
||||||
if (*p1 == '#')
|
if (*p1 == '#')
|
||||||
*p1 = '\0'; /* Found a comment. */
|
*p1 = '\0'; /* Found a comment. */
|
||||||
|
|
||||||
/* Save into global buffer if appropriate. */
|
/* Save into global buffer if appropriate. */
|
||||||
if (repeat)
|
if (repeat)
|
||||||
|
@ -711,11 +713,11 @@ command_line_handler (char *rl)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Does reading of input from terminal w/o the editing features
|
/* Does reading of input from terminal w/o the editing features
|
||||||
provided by the readline library. */
|
provided by the readline library. */
|
||||||
|
|
||||||
/* NOTE: 1999-04-30 Asynchronous version of gdb_readline. gdb_readline
|
/* NOTE: 1999-04-30 Asynchronous version of gdb_readline; gdb_readline
|
||||||
will become obsolete when the event loop is made the default
|
will become obsolete when the event loop is made the default
|
||||||
execution for gdb. */
|
execution for gdb. */
|
||||||
void
|
void
|
||||||
gdb_readline2 (gdb_client_data client_data)
|
gdb_readline2 (gdb_client_data client_data)
|
||||||
{
|
{
|
||||||
|
@ -726,11 +728,11 @@ gdb_readline2 (gdb_client_data client_data)
|
||||||
static int done_once = 0;
|
static int done_once = 0;
|
||||||
|
|
||||||
/* Unbuffer the input stream, so that, later on, the calls to fgetc
|
/* Unbuffer the input stream, so that, later on, the calls to fgetc
|
||||||
fetch only one char at the time from the stream. The fgetc's will
|
fetch only one char at the time from the stream. The fgetc's will
|
||||||
get up to the first newline, but there may be more chars in the
|
get up to the first newline, but there may be more chars in the
|
||||||
stream after '\n'. If we buffer the input and fgetc drains the
|
stream after '\n'. If we buffer the input and fgetc drains the
|
||||||
stream, getting stuff beyond the newline as well, a select, done
|
stream, getting stuff beyond the newline as well, a select, done
|
||||||
afterwards will not trigger. */
|
afterwards will not trigger. */
|
||||||
if (!done_once && !ISATTY (instream))
|
if (!done_once && !ISATTY (instream))
|
||||||
{
|
{
|
||||||
setbuf (instream, NULL);
|
setbuf (instream, NULL);
|
||||||
|
@ -742,9 +744,9 @@ gdb_readline2 (gdb_client_data client_data)
|
||||||
/* We still need the while loop here, even though it would seem
|
/* We still need the while loop here, even though it would seem
|
||||||
obvious to invoke gdb_readline2 at every character entered. If
|
obvious to invoke gdb_readline2 at every character entered. If
|
||||||
not using the readline library, the terminal is in cooked mode,
|
not using the readline library, the terminal is in cooked mode,
|
||||||
which sends the characters all at once. Poll will notice that the
|
which sends the characters all at once. Poll will notice that the
|
||||||
input fd has changed state only after enter is pressed. At this
|
input fd has changed state only after enter is pressed. At this
|
||||||
point we still need to fetch all the chars entered. */
|
point we still need to fetch all the chars entered. */
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
|
@ -755,9 +757,9 @@ gdb_readline2 (gdb_client_data client_data)
|
||||||
if (c == EOF)
|
if (c == EOF)
|
||||||
{
|
{
|
||||||
if (input_index > 0)
|
if (input_index > 0)
|
||||||
/* The last line does not end with a newline. Return it, and
|
/* The last line does not end with a newline. Return it,
|
||||||
if we are called again fgetc will still return EOF and
|
and if we are called again fgetc will still return EOF
|
||||||
we'll return NULL then. */
|
and we'll return NULL then. */
|
||||||
break;
|
break;
|
||||||
xfree (result);
|
xfree (result);
|
||||||
(*input_handler) (0);
|
(*input_handler) (0);
|
||||||
|
@ -785,17 +787,17 @@ gdb_readline2 (gdb_client_data client_data)
|
||||||
|
|
||||||
|
|
||||||
/* Initialization of signal handlers and tokens. There is a function
|
/* Initialization of signal handlers and tokens. There is a function
|
||||||
handle_sig* for each of the signals GDB cares about. Specifically:
|
handle_sig* for each of the signals GDB cares about. Specifically:
|
||||||
SIGINT, SIGFPE, SIGQUIT, SIGTSTP, SIGHUP, SIGWINCH. These
|
SIGINT, SIGFPE, SIGQUIT, SIGTSTP, SIGHUP, SIGWINCH. These
|
||||||
functions are the actual signal handlers associated to the signals
|
functions are the actual signal handlers associated to the signals
|
||||||
via calls to signal(). The only job for these functions is to
|
via calls to signal(). The only job for these functions is to
|
||||||
enqueue the appropriate event/procedure with the event loop. Such
|
enqueue the appropriate event/procedure with the event loop. Such
|
||||||
procedures are the old signal handlers. The event loop will take
|
procedures are the old signal handlers. The event loop will take
|
||||||
care of invoking the queued procedures to perform the usual tasks
|
care of invoking the queued procedures to perform the usual tasks
|
||||||
associated with the reception of the signal. */
|
associated with the reception of the signal. */
|
||||||
/* NOTE: 1999-04-30 This is the asynchronous version of init_signals.
|
/* NOTE: 1999-04-30 This is the asynchronous version of init_signals.
|
||||||
init_signals will become obsolete as we move to have to event loop
|
init_signals will become obsolete as we move to have to event loop
|
||||||
as the default for gdb. */
|
as the default for gdb. */
|
||||||
void
|
void
|
||||||
async_init_signals (void)
|
async_init_signals (void)
|
||||||
{
|
{
|
||||||
|
@ -854,7 +856,7 @@ mark_async_signal_handler_wrapper (void *token)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tell the event loop what to do if SIGINT is received.
|
/* Tell the event loop what to do if SIGINT is received.
|
||||||
See event-signal.c. */
|
See event-signal.c. */
|
||||||
void
|
void
|
||||||
handle_sigint (int sig)
|
handle_sigint (int sig)
|
||||||
{
|
{
|
||||||
|
@ -862,19 +864,19 @@ handle_sigint (int sig)
|
||||||
|
|
||||||
/* We could be running in a loop reading in symfiles or something so
|
/* We could be running in a loop reading in symfiles or something so
|
||||||
it may be quite a while before we get back to the event loop. So
|
it may be quite a while before we get back to the event loop. So
|
||||||
set quit_flag to 1 here. Then if QUIT is called before we get to
|
set quit_flag to 1 here. Then if QUIT is called before we get to
|
||||||
the event loop, we will unwind as expected. */
|
the event loop, we will unwind as expected. */
|
||||||
|
|
||||||
quit_flag = 1;
|
quit_flag = 1;
|
||||||
|
|
||||||
/* If immediate_quit is set, we go ahead and process the SIGINT right
|
/* If immediate_quit is set, we go ahead and process the SIGINT right
|
||||||
away, even if we usually would defer this to the event loop. The
|
away, even if we usually would defer this to the event loop. The
|
||||||
assumption here is that it is safe to process ^C immediately if
|
assumption here is that it is safe to process ^C immediately if
|
||||||
immediate_quit is set. If we didn't, SIGINT would be really
|
immediate_quit is set. If we didn't, SIGINT would be really
|
||||||
processed only the next time through the event loop. To get to
|
processed only the next time through the event loop. To get to
|
||||||
that point, though, the command that we want to interrupt needs to
|
that point, though, the command that we want to interrupt needs to
|
||||||
finish first, which is unacceptable. If immediate quit is not set,
|
finish first, which is unacceptable. If immediate quit is not set,
|
||||||
we process SIGINT the next time through the loop, which is fine. */
|
we process SIGINT the next time through the loop, which is fine. */
|
||||||
gdb_call_async_signal_handler (sigint_token, immediate_quit);
|
gdb_call_async_signal_handler (sigint_token, immediate_quit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -887,7 +889,7 @@ handle_sigterm (int sig)
|
||||||
quit_force ((char *) 0, stdin == instream);
|
quit_force ((char *) 0, stdin == instream);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do the quit. All the checks have been done by the caller. */
|
/* Do the quit. All the checks have been done by the caller. */
|
||||||
void
|
void
|
||||||
async_request_quit (gdb_client_data arg)
|
async_request_quit (gdb_client_data arg)
|
||||||
{
|
{
|
||||||
|
@ -895,7 +897,7 @@ async_request_quit (gdb_client_data arg)
|
||||||
back here, that means that an exception was thrown to unwind the
|
back here, that means that an exception was thrown to unwind the
|
||||||
current command before we got back to the event loop. So there
|
current command before we got back to the event loop. So there
|
||||||
is no reason to call quit again here, unless immediate_quit is
|
is no reason to call quit again here, unless immediate_quit is
|
||||||
set.*/
|
set. */
|
||||||
|
|
||||||
if (quit_flag || immediate_quit)
|
if (quit_flag || immediate_quit)
|
||||||
quit ();
|
quit ();
|
||||||
|
@ -903,7 +905,7 @@ async_request_quit (gdb_client_data arg)
|
||||||
|
|
||||||
#ifdef SIGQUIT
|
#ifdef SIGQUIT
|
||||||
/* Tell the event loop what to do if SIGQUIT is received.
|
/* Tell the event loop what to do if SIGQUIT is received.
|
||||||
See event-signal.c. */
|
See event-signal.c. */
|
||||||
static void
|
static void
|
||||||
handle_sigquit (int sig)
|
handle_sigquit (int sig)
|
||||||
{
|
{
|
||||||
|
@ -918,13 +920,13 @@ handle_sigquit (int sig)
|
||||||
static void
|
static void
|
||||||
async_do_nothing (gdb_client_data arg)
|
async_do_nothing (gdb_client_data arg)
|
||||||
{
|
{
|
||||||
/* Empty function body. */
|
/* Empty function body. */
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef SIGHUP
|
#ifdef SIGHUP
|
||||||
/* Tell the event loop what to do if SIGHUP is received.
|
/* Tell the event loop what to do if SIGHUP is received.
|
||||||
See event-signal.c. */
|
See event-signal.c. */
|
||||||
static void
|
static void
|
||||||
handle_sighup (int sig)
|
handle_sighup (int sig)
|
||||||
{
|
{
|
||||||
|
@ -932,14 +934,14 @@ handle_sighup (int sig)
|
||||||
signal (sig, handle_sighup);
|
signal (sig, handle_sighup);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called by the event loop to process a SIGHUP */
|
/* Called by the event loop to process a SIGHUP. */
|
||||||
static void
|
static void
|
||||||
async_disconnect (gdb_client_data arg)
|
async_disconnect (gdb_client_data arg)
|
||||||
{
|
{
|
||||||
catch_errors (quit_cover, NULL,
|
catch_errors (quit_cover, NULL,
|
||||||
"Could not kill the program being debugged",
|
"Could not kill the program being debugged",
|
||||||
RETURN_MASK_ALL);
|
RETURN_MASK_ALL);
|
||||||
signal (SIGHUP, SIG_DFL); /*FIXME: ??????????? */
|
signal (SIGHUP, SIG_DFL); /*FIXME: ??????????? */
|
||||||
raise (SIGHUP);
|
raise (SIGHUP);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -977,13 +979,14 @@ async_stop_sig (gdb_client_data arg)
|
||||||
printf_unfiltered ("%s", prompt);
|
printf_unfiltered ("%s", prompt);
|
||||||
gdb_flush (gdb_stdout);
|
gdb_flush (gdb_stdout);
|
||||||
|
|
||||||
/* Forget about any previous command -- null line now will do nothing. */
|
/* Forget about any previous command -- null line now will do
|
||||||
|
nothing. */
|
||||||
dont_repeat ();
|
dont_repeat ();
|
||||||
}
|
}
|
||||||
#endif /* STOP_SIGNAL */
|
#endif /* STOP_SIGNAL */
|
||||||
|
|
||||||
/* Tell the event loop what to do if SIGFPE is received.
|
/* Tell the event loop what to do if SIGFPE is received.
|
||||||
See event-signal.c. */
|
See event-signal.c. */
|
||||||
static void
|
static void
|
||||||
handle_sigfpe (int sig)
|
handle_sigfpe (int sig)
|
||||||
{
|
{
|
||||||
|
@ -991,17 +994,17 @@ handle_sigfpe (int sig)
|
||||||
signal (sig, handle_sigfpe);
|
signal (sig, handle_sigfpe);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Event loop will call this functin to process a SIGFPE. */
|
/* Event loop will call this functin to process a SIGFPE. */
|
||||||
static void
|
static void
|
||||||
async_float_handler (gdb_client_data arg)
|
async_float_handler (gdb_client_data arg)
|
||||||
{
|
{
|
||||||
/* This message is based on ANSI C, section 4.7. Note that integer
|
/* This message is based on ANSI C, section 4.7. Note that integer
|
||||||
divide by zero causes this, so "float" is a misnomer. */
|
divide by zero causes this, so "float" is a misnomer. */
|
||||||
error (_("Erroneous arithmetic operation."));
|
error (_("Erroneous arithmetic operation."));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tell the event loop what to do if SIGWINCH is received.
|
/* Tell the event loop what to do if SIGWINCH is received.
|
||||||
See event-signal.c. */
|
See event-signal.c. */
|
||||||
#if defined(SIGWINCH) && defined(SIGWINCH_HANDLER)
|
#if defined(SIGWINCH) && defined(SIGWINCH_HANDLER)
|
||||||
static void
|
static void
|
||||||
handle_sigwinch (int sig)
|
handle_sigwinch (int sig)
|
||||||
|
@ -1014,14 +1017,16 @@ handle_sigwinch (int sig)
|
||||||
|
|
||||||
/* Called by do_setshow_command. */
|
/* Called by do_setshow_command. */
|
||||||
void
|
void
|
||||||
set_async_editing_command (char *args, int from_tty, struct cmd_list_element *c)
|
set_async_editing_command (char *args, int from_tty,
|
||||||
|
struct cmd_list_element *c)
|
||||||
{
|
{
|
||||||
change_line_handler ();
|
change_line_handler ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called by do_setshow_command. */
|
/* Called by do_setshow_command. */
|
||||||
void
|
void
|
||||||
set_async_annotation_level (char *args, int from_tty, struct cmd_list_element *c)
|
set_async_annotation_level (char *args, int from_tty,
|
||||||
|
struct cmd_list_element *c)
|
||||||
{
|
{
|
||||||
change_annotation_level ();
|
change_annotation_level ();
|
||||||
}
|
}
|
||||||
|
@ -1035,7 +1040,7 @@ set_async_prompt (char *args, int from_tty, struct cmd_list_element *c)
|
||||||
|
|
||||||
/* Set things up for readline to be invoked via the alternate
|
/* Set things up for readline to be invoked via the alternate
|
||||||
interface, i.e. via a callback function (rl_callback_read_char),
|
interface, i.e. via a callback function (rl_callback_read_char),
|
||||||
and hook up instream to the event loop. */
|
and hook up instream to the event loop. */
|
||||||
void
|
void
|
||||||
gdb_setup_readline (void)
|
gdb_setup_readline (void)
|
||||||
{
|
{
|
||||||
|
@ -1054,7 +1059,7 @@ gdb_setup_readline (void)
|
||||||
editing. */
|
editing. */
|
||||||
if (ISATTY (instream))
|
if (ISATTY (instream))
|
||||||
{
|
{
|
||||||
/* Tell gdb that we will be using the readline library. This
|
/* Tell gdb that we will be using the readline library. This
|
||||||
could be overwritten by a command in .gdbinit like 'set
|
could be overwritten by a command in .gdbinit like 'set
|
||||||
editing on' or 'off'. */
|
editing on' or 'off'. */
|
||||||
async_command_editing_p = 1;
|
async_command_editing_p = 1;
|
||||||
|
@ -1070,11 +1075,11 @@ gdb_setup_readline (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* When readline has read an end-of-line character, it passes the
|
/* When readline has read an end-of-line character, it passes the
|
||||||
complete line to gdb for processing. command_line_handler is the
|
complete line to gdb for processing; command_line_handler is the
|
||||||
function that does this. */
|
function that does this. */
|
||||||
input_handler = command_line_handler;
|
input_handler = command_line_handler;
|
||||||
|
|
||||||
/* Tell readline to use the same input stream that gdb uses. */
|
/* Tell readline to use the same input stream that gdb uses. */
|
||||||
rl_instream = instream;
|
rl_instream = instream;
|
||||||
|
|
||||||
/* Get a file descriptor for the input stream, so that we can
|
/* Get a file descriptor for the input stream, so that we can
|
||||||
|
@ -1084,7 +1089,7 @@ gdb_setup_readline (void)
|
||||||
/* Now we need to create the event sources for the input file
|
/* Now we need to create the event sources for the input file
|
||||||
descriptor. */
|
descriptor. */
|
||||||
/* At this point in time, this is the only event source that we
|
/* At this point in time, this is the only event source that we
|
||||||
register with the even loop. Another source is going to be the
|
register with the even loop. Another source is going to be the
|
||||||
target program (inferior), but that must be registered only when
|
target program (inferior), but that must be registered only when
|
||||||
it actually exists (I.e. after we say 'run' or after we connect
|
it actually exists (I.e. after we say 'run' or after we connect
|
||||||
to a remote target. */
|
to a remote target. */
|
||||||
|
|
|
@ -20,16 +20,21 @@
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "gdb_string.h"
|
#include "gdb_string.h"
|
||||||
#include "interps.h"
|
#include "interps.h"
|
||||||
|
#include <mcheck.h>
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
struct captured_main_args args;
|
struct captured_main_args args;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
mtrace ();
|
||||||
memset (&args, 0, sizeof args);
|
memset (&args, 0, sizeof args);
|
||||||
args.argc = argc;
|
args.argc = argc;
|
||||||
args.argv = argv;
|
args.argv = argv;
|
||||||
args.use_windows = 0;
|
args.use_windows = 0;
|
||||||
args.interpreter_p = INTERP_CONSOLE;
|
args.interpreter_p = INTERP_CONSOLE;
|
||||||
return gdb_main (&args);
|
ret = gdb_main (&args);
|
||||||
|
muntrace();
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
18
gdb/gdb.h
18
gdb/gdb.h
|
@ -32,27 +32,27 @@ enum gdb_rc {
|
||||||
set to a freshly allocated copy of the error message. */
|
set to a freshly allocated copy of the error message. */
|
||||||
/* NOTE: Since ``defs.h:catch_errors()'' does not return an error /
|
/* NOTE: Since ``defs.h:catch_errors()'' does not return an error /
|
||||||
internal / quit indication it is not possible to return that
|
internal / quit indication it is not possible to return that
|
||||||
here. */
|
here. */
|
||||||
GDB_RC_FAIL = 0,
|
GDB_RC_FAIL = 0,
|
||||||
/* No error occured but nothing happened. Due to the catch_errors()
|
/* No error occured but nothing happened. Due to the catch_errors()
|
||||||
interface, this must be non-zero. */
|
interface, this must be non-zero. */
|
||||||
GDB_RC_NONE = 1,
|
GDB_RC_NONE = 1,
|
||||||
/* The operation was successful. Due to the catch_errors()
|
/* The operation was successful. Due to the catch_errors()
|
||||||
interface, this must be non-zero. */
|
interface, this must be non-zero. */
|
||||||
GDB_RC_OK = 2
|
GDB_RC_OK = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Print the specified breakpoint on GDB_STDOUT. (Eventually this
|
/* Print the specified breakpoint on GDB_STDOUT. (Eventually this
|
||||||
function will ``print'' the object on ``output''). */
|
function will ``print'' the object on ``output''). */
|
||||||
enum gdb_rc gdb_breakpoint_query (struct ui_out *uiout, int bnum,
|
enum gdb_rc gdb_breakpoint_query (struct ui_out *uiout, int bnum,
|
||||||
char **error_message);
|
char **error_message);
|
||||||
|
|
||||||
/* Switch thread and print notification. */
|
/* Switch thread and print notification. */
|
||||||
enum gdb_rc gdb_thread_select (struct ui_out *uiout, char *tidstr,
|
enum gdb_rc gdb_thread_select (struct ui_out *uiout, char *tidstr,
|
||||||
char **error_message);
|
char **error_message);
|
||||||
|
|
||||||
/* Print a list of known thread ids. */
|
/* Print a list of known thread ids. */
|
||||||
enum gdb_rc gdb_list_thread_ids (struct ui_out *uiout,
|
enum gdb_rc gdb_list_thread_ids (struct ui_out *uiout,
|
||||||
char **error_message);
|
char **error_message);
|
||||||
|
|
||||||
|
|
92
gdb/main.c
92
gdb/main.c
|
@ -46,13 +46,13 @@
|
||||||
|
|
||||||
/* The selected interpreter. This will be used as a set command
|
/* The selected interpreter. This will be used as a set command
|
||||||
variable, so it should always be malloc'ed - since
|
variable, so it should always be malloc'ed - since
|
||||||
do_setshow_command will free it. */
|
do_setshow_command will free it. */
|
||||||
char *interpreter_p;
|
char *interpreter_p;
|
||||||
|
|
||||||
/* Whether xdb commands will be handled */
|
/* Whether xdb commands will be handled. */
|
||||||
int xdb_commands = 0;
|
int xdb_commands = 0;
|
||||||
|
|
||||||
/* Whether dbx commands will be handled */
|
/* Whether dbx commands will be handled. */
|
||||||
int dbx_commands = 0;
|
int dbx_commands = 0;
|
||||||
|
|
||||||
/* System root path, used to find libraries etc. */
|
/* System root path, used to find libraries etc. */
|
||||||
|
@ -69,7 +69,7 @@ struct ui_file *gdb_stdout;
|
||||||
struct ui_file *gdb_stderr;
|
struct ui_file *gdb_stderr;
|
||||||
struct ui_file *gdb_stdlog;
|
struct ui_file *gdb_stdlog;
|
||||||
struct ui_file *gdb_stdin;
|
struct ui_file *gdb_stdin;
|
||||||
/* target IO streams */
|
/* Target IO streams. */
|
||||||
struct ui_file *gdb_stdtargin;
|
struct ui_file *gdb_stdtargin;
|
||||||
struct ui_file *gdb_stdtarg;
|
struct ui_file *gdb_stdtarg;
|
||||||
struct ui_file *gdb_stdtargerr;
|
struct ui_file *gdb_stdtargerr;
|
||||||
|
@ -86,7 +86,7 @@ int batch_silent = 0;
|
||||||
int return_child_result = 0;
|
int return_child_result = 0;
|
||||||
int return_child_result_value = -1;
|
int return_child_result_value = -1;
|
||||||
|
|
||||||
/* Whether to enable writing into executable and core files */
|
/* Whether to enable writing into executable and core files. */
|
||||||
extern int write_files;
|
extern int write_files;
|
||||||
|
|
||||||
/* GDB as it has been invoked from the command line (i.e. argv[0]). */
|
/* GDB as it has been invoked from the command line (i.e. argv[0]). */
|
||||||
|
@ -94,8 +94,8 @@ static char *gdb_program_name;
|
||||||
|
|
||||||
static void print_gdb_help (struct ui_file *);
|
static void print_gdb_help (struct ui_file *);
|
||||||
|
|
||||||
/* These two are used to set the external editor commands when gdb is farming
|
/* These two are used to set the external editor commands when gdb is
|
||||||
out files to be edited by another program. */
|
farming out files to be edited by another program. */
|
||||||
|
|
||||||
extern char *external_editor_command;
|
extern char *external_editor_command;
|
||||||
|
|
||||||
|
@ -151,11 +151,11 @@ relocate_directory (const char *progname, const char *initial, int flag)
|
||||||
return dir;
|
return dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compute the locations of init files that GDB should source and return
|
/* Compute the locations of init files that GDB should source and
|
||||||
them in SYSTEM_GDBINIT, HOME_GDBINIT, LOCAL_GDBINIT. If there is
|
return them in SYSTEM_GDBINIT, HOME_GDBINIT, LOCAL_GDBINIT. If
|
||||||
no system gdbinit (resp. home gdbinit and local gdbinit) to be loaded,
|
there is no system gdbinit (resp. home gdbinit and local gdbinit)
|
||||||
then SYSTEM_GDBINIT (resp. HOME_GDBINIT and LOCAL_GDBINIT) is set to
|
to be loaded, then SYSTEM_GDBINIT (resp. HOME_GDBINIT and
|
||||||
NULL. */
|
LOCAL_GDBINIT) is set to NULL. */
|
||||||
static void
|
static void
|
||||||
get_init_files (char **system_gdbinit,
|
get_init_files (char **system_gdbinit,
|
||||||
char **home_gdbinit,
|
char **home_gdbinit,
|
||||||
|
@ -220,7 +220,7 @@ get_init_files (char **system_gdbinit,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Call command_loop. If it happens to return, pass that through as a
|
/* Call command_loop. If it happens to return, pass that through as a
|
||||||
non-zero return status. */
|
non-zero return status. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
captured_command_loop (void *data)
|
captured_command_loop (void *data)
|
||||||
|
@ -232,12 +232,12 @@ captured_command_loop (void *data)
|
||||||
the do_cleanups() below is redundant. Unfortunately, many FUNCs
|
the do_cleanups() below is redundant. Unfortunately, many FUNCs
|
||||||
are not that well behaved. do_cleanups should either be replaced
|
are not that well behaved. do_cleanups should either be replaced
|
||||||
with a do_cleanups call (to cover the problem) or an assertion
|
with a do_cleanups call (to cover the problem) or an assertion
|
||||||
check to detect bad FUNCs code. */
|
check to detect bad FUNCs code. */
|
||||||
do_cleanups (ALL_CLEANUPS);
|
do_cleanups (ALL_CLEANUPS);
|
||||||
/* If the command_loop returned, normally (rather than threw an
|
/* If the command_loop returned, normally (rather than threw an
|
||||||
error) we try to quit. If the quit is aborted, catch_errors()
|
error) we try to quit. If the quit is aborted, catch_errors()
|
||||||
which called this catch the signal and restart the command
|
which called this catch the signal and restart the command
|
||||||
loop. */
|
loop. */
|
||||||
quit_command (NULL, instream == stdin);
|
quit_command (NULL, instream == stdin);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -260,7 +260,8 @@ captured_main (void *data)
|
||||||
char *cdarg = NULL;
|
char *cdarg = NULL;
|
||||||
char *ttyarg = NULL;
|
char *ttyarg = NULL;
|
||||||
|
|
||||||
/* These are static so that we can take their address in an initializer. */
|
/* These are static so that we can take their address in an
|
||||||
|
initializer. */
|
||||||
static int print_help;
|
static int print_help;
|
||||||
static int print_version;
|
static int print_version;
|
||||||
|
|
||||||
|
@ -317,7 +318,7 @@ captured_main (void *data)
|
||||||
|
|
||||||
quit_flag = 0;
|
quit_flag = 0;
|
||||||
line = (char *) xmalloc (linesize);
|
line = (char *) xmalloc (linesize);
|
||||||
line[0] = '\0'; /* Terminate saved (now empty) cmd line */
|
line[0] = '\0'; /* Terminate saved (now empty) cmd line. */
|
||||||
instream = stdin;
|
instream = stdin;
|
||||||
|
|
||||||
gdb_stdout = stdio_fileopen (stdout);
|
gdb_stdout = stdio_fileopen (stdout);
|
||||||
|
@ -332,7 +333,7 @@ captured_main (void *data)
|
||||||
|
|
||||||
if (! getcwd (gdb_dirbuf, sizeof (gdb_dirbuf)))
|
if (! getcwd (gdb_dirbuf, sizeof (gdb_dirbuf)))
|
||||||
/* Don't use *_filtered or warning() (which relies on
|
/* Don't use *_filtered or warning() (which relies on
|
||||||
current_target) until after initialize_all_files(). */
|
current_target) until after initialize_all_files(). */
|
||||||
fprintf_unfiltered (gdb_stderr,
|
fprintf_unfiltered (gdb_stderr,
|
||||||
_("%s: warning: error finding working directory: %s\n"),
|
_("%s: warning: error finding working directory: %s\n"),
|
||||||
argv[0], safe_strerror (errno));
|
argv[0], safe_strerror (errno));
|
||||||
|
@ -400,9 +401,9 @@ captured_main (void *data)
|
||||||
{"batch", no_argument, &batch_flag, 1},
|
{"batch", no_argument, &batch_flag, 1},
|
||||||
{"epoch", no_argument, &epoch_interface, 1},
|
{"epoch", no_argument, &epoch_interface, 1},
|
||||||
|
|
||||||
/* This is a synonym for "--annotate=1". --annotate is now preferred,
|
/* This is a synonym for "--annotate=1". --annotate is now
|
||||||
but keep this here for a long time because people will be running
|
preferred, but keep this here for a long time because people
|
||||||
emacses which use --fullname. */
|
will be running emacses which use --fullname. */
|
||||||
{"fullname", no_argument, 0, 'f'},
|
{"fullname", no_argument, 0, 'f'},
|
||||||
{"f", no_argument, 0, 'f'},
|
{"f", no_argument, 0, 'f'},
|
||||||
|
|
||||||
|
@ -559,10 +560,12 @@ captured_main (void *data)
|
||||||
#ifdef GDBTK
|
#ifdef GDBTK
|
||||||
case 'z':
|
case 'z':
|
||||||
{
|
{
|
||||||
extern int gdbtk_test (char *);
|
extern int gdbtk_test (char *);
|
||||||
|
|
||||||
if (!gdbtk_test (optarg))
|
if (!gdbtk_test (optarg))
|
||||||
{
|
{
|
||||||
fprintf_unfiltered (gdb_stderr, _("%s: unable to load tclcommand file \"%s\""),
|
fprintf_unfiltered (gdb_stderr,
|
||||||
|
_("%s: unable to load tclcommand file \"%s\""),
|
||||||
argv[0], optarg);
|
argv[0], optarg);
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
@ -605,7 +608,7 @@ extern int gdbtk_test (char *);
|
||||||
if (i == 0 && p == optarg)
|
if (i == 0 && p == optarg)
|
||||||
|
|
||||||
/* Don't use *_filtered or warning() (which relies on
|
/* Don't use *_filtered or warning() (which relies on
|
||||||
current_target) until after initialize_all_files(). */
|
current_target) until after initialize_all_files(). */
|
||||||
|
|
||||||
fprintf_unfiltered
|
fprintf_unfiltered
|
||||||
(gdb_stderr,
|
(gdb_stderr,
|
||||||
|
@ -623,7 +626,7 @@ extern int gdbtk_test (char *);
|
||||||
if (i == 0 && p == optarg)
|
if (i == 0 && p == optarg)
|
||||||
|
|
||||||
/* Don't use *_filtered or warning() (which relies on
|
/* Don't use *_filtered or warning() (which relies on
|
||||||
current_target) until after initialize_all_files(). */
|
current_target) until after initialize_all_files(). */
|
||||||
|
|
||||||
fprintf_unfiltered
|
fprintf_unfiltered
|
||||||
(gdb_stderr,
|
(gdb_stderr,
|
||||||
|
@ -655,8 +658,8 @@ extern int gdbtk_test (char *);
|
||||||
control of the console via the deprecated_init_ui_hook (). */
|
control of the console via the deprecated_init_ui_hook (). */
|
||||||
gdb_init (argv[0]);
|
gdb_init (argv[0]);
|
||||||
|
|
||||||
/* Now that gdb_init has created the initial inferior, we're in position
|
/* Now that gdb_init has created the initial inferior, we're in
|
||||||
to set args for that inferior. */
|
position to set args for that inferior. */
|
||||||
if (set_args)
|
if (set_args)
|
||||||
{
|
{
|
||||||
/* The remaining options are the command-line options for the
|
/* The remaining options are the command-line options for the
|
||||||
|
@ -706,9 +709,9 @@ Excess command line arguments ignored. (%s%s)\n"),
|
||||||
(optind == argc - 1) ? "" : " ...");
|
(optind == argc - 1) ? "" : " ...");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Lookup gdbinit files. Note that the gdbinit file name may be overriden
|
/* Lookup gdbinit files. Note that the gdbinit file name may be
|
||||||
during file initialization, so get_init_files should be called after
|
overriden during file initialization, so get_init_files should be
|
||||||
gdb_init. */
|
called after gdb_init. */
|
||||||
get_init_files (&system_gdbinit, &home_gdbinit, &local_gdbinit);
|
get_init_files (&system_gdbinit, &home_gdbinit, &local_gdbinit);
|
||||||
|
|
||||||
/* Do these (and anything which might call wrap_here or *_filtered)
|
/* Do these (and anything which might call wrap_here or *_filtered)
|
||||||
|
@ -737,19 +740,19 @@ Excess command line arguments ignored. (%s%s)\n"),
|
||||||
it isn't encapsulated in MI output. */
|
it isn't encapsulated in MI output. */
|
||||||
if (!quiet && strcmp (interpreter_p, INTERP_MI1) == 0)
|
if (!quiet && strcmp (interpreter_p, INTERP_MI1) == 0)
|
||||||
{
|
{
|
||||||
/* Print all the junk at the top, with trailing "..." if we are about
|
/* Print all the junk at the top, with trailing "..." if we are
|
||||||
to read a symbol file (possibly slowly). */
|
about to read a symbol file (possibly slowly). */
|
||||||
print_gdb_version (gdb_stdout);
|
print_gdb_version (gdb_stdout);
|
||||||
if (symarg)
|
if (symarg)
|
||||||
printf_filtered ("..");
|
printf_filtered ("..");
|
||||||
wrap_here ("");
|
wrap_here ("");
|
||||||
printf_filtered ("\n");
|
printf_filtered ("\n");
|
||||||
gdb_flush (gdb_stdout); /* Force to screen during slow operations */
|
gdb_flush (gdb_stdout); /* Force to screen during slow
|
||||||
|
operations. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Install the default UI. All the interpreters should have had a
|
/* Install the default UI. All the interpreters should have had a
|
||||||
look at things by now. Initialize the default interpreter. */
|
look at things by now. Initialize the default interpreter. */
|
||||||
|
|
||||||
{
|
{
|
||||||
/* Find it. */
|
/* Find it. */
|
||||||
|
@ -773,14 +776,15 @@ Excess command line arguments ignored. (%s%s)\n"),
|
||||||
any sane interpreter. */
|
any sane interpreter. */
|
||||||
if (!quiet && !current_interp_named_p (INTERP_MI1))
|
if (!quiet && !current_interp_named_p (INTERP_MI1))
|
||||||
{
|
{
|
||||||
/* Print all the junk at the top, with trailing "..." if we are about
|
/* Print all the junk at the top, with trailing "..." if we are
|
||||||
to read a symbol file (possibly slowly). */
|
about to read a symbol file (possibly slowly). */
|
||||||
print_gdb_version (gdb_stdout);
|
print_gdb_version (gdb_stdout);
|
||||||
if (symarg)
|
if (symarg)
|
||||||
printf_filtered ("..");
|
printf_filtered ("..");
|
||||||
wrap_here ("");
|
wrap_here ("");
|
||||||
printf_filtered ("\n");
|
printf_filtered ("\n");
|
||||||
gdb_flush (gdb_stdout); /* Force to screen during slow operations */
|
gdb_flush (gdb_stdout); /* Force to screen during slow
|
||||||
|
operations. */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set off error and warning messages with a blank line. */
|
/* Set off error and warning messages with a blank line. */
|
||||||
|
@ -814,7 +818,8 @@ Excess command line arguments ignored. (%s%s)\n"),
|
||||||
xfree (dirarg);
|
xfree (dirarg);
|
||||||
|
|
||||||
/* Skip auto-loading section-specified scripts until we've sourced
|
/* Skip auto-loading section-specified scripts until we've sourced
|
||||||
local_gdbinit (which is often used to augment the source search path). */
|
local_gdbinit (which is often used to augment the source search
|
||||||
|
path). */
|
||||||
save_auto_load = gdbpy_global_auto_load;
|
save_auto_load = gdbpy_global_auto_load;
|
||||||
gdbpy_global_auto_load = 0;
|
gdbpy_global_auto_load = 0;
|
||||||
|
|
||||||
|
@ -824,7 +829,7 @@ Excess command line arguments ignored. (%s%s)\n"),
|
||||||
{
|
{
|
||||||
/* The exec file and the symbol-file are the same. If we can't
|
/* The exec file and the symbol-file are the same. If we can't
|
||||||
open it, better only print one error message.
|
open it, better only print one error message.
|
||||||
catch_command_errors returns non-zero on success! */
|
catch_command_errors returns non-zero on success! */
|
||||||
if (catch_command_errors (exec_file_attach, execarg, !batch_flag, RETURN_MASK_ALL))
|
if (catch_command_errors (exec_file_attach, execarg, !batch_flag, RETURN_MASK_ALL))
|
||||||
catch_command_errors (symbol_file_add_main, symarg, !batch_flag, RETURN_MASK_ALL);
|
catch_command_errors (symbol_file_add_main, symarg, !batch_flag, RETURN_MASK_ALL);
|
||||||
}
|
}
|
||||||
|
@ -867,7 +872,7 @@ Can't attach to process and specify a core file at the same time."));
|
||||||
if (ttyarg != NULL)
|
if (ttyarg != NULL)
|
||||||
set_inferior_io_terminal (ttyarg);
|
set_inferior_io_terminal (ttyarg);
|
||||||
|
|
||||||
/* Error messages should no longer be distinguished with extra output. */
|
/* Error messages should no longer be distinguished with extra output. */
|
||||||
error_pre_print = NULL;
|
error_pre_print = NULL;
|
||||||
quit_pre_print = NULL;
|
quit_pre_print = NULL;
|
||||||
warning_pre_print = _("warning: ");
|
warning_pre_print = _("warning: ");
|
||||||
|
@ -896,7 +901,8 @@ Can't attach to process and specify a core file at the same time."));
|
||||||
}
|
}
|
||||||
xfree (cmdarg);
|
xfree (cmdarg);
|
||||||
|
|
||||||
/* Read in the old history after all the command files have been read. */
|
/* Read in the old history after all the command files have been
|
||||||
|
read. */
|
||||||
init_history ();
|
init_history ();
|
||||||
|
|
||||||
if (batch_flag)
|
if (batch_flag)
|
||||||
|
@ -911,7 +917,7 @@ Can't attach to process and specify a core file at the same time."));
|
||||||
/* NOTE: cagney/1999-11-07: There is probably no reason for not
|
/* NOTE: cagney/1999-11-07: There is probably no reason for not
|
||||||
moving this loop and the code found in captured_command_loop()
|
moving this loop and the code found in captured_command_loop()
|
||||||
into the command_loop() proper. The main thing holding back that
|
into the command_loop() proper. The main thing holding back that
|
||||||
change - SET_TOP_LEVEL() - has been eliminated. */
|
change - SET_TOP_LEVEL() - has been eliminated. */
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
catch_errors (captured_command_loop, 0, "", RETURN_MASK_ALL);
|
catch_errors (captured_command_loop, 0, "", RETURN_MASK_ALL);
|
||||||
|
|
157
gdb/top.c
157
gdb/top.c
|
@ -49,7 +49,7 @@
|
||||||
#include "gdbthread.h"
|
#include "gdbthread.h"
|
||||||
#include "python/python.h"
|
#include "python/python.h"
|
||||||
|
|
||||||
/* readline include files */
|
/* readline include files. */
|
||||||
#include "readline/readline.h"
|
#include "readline/readline.h"
|
||||||
#include "readline/history.h"
|
#include "readline/history.h"
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@
|
||||||
#include "ui-out.h"
|
#include "ui-out.h"
|
||||||
#include "cli-out.h"
|
#include "cli-out.h"
|
||||||
|
|
||||||
/* Default command line prompt. This is overriden in some configs. */
|
/* Default command line prompt. This is overriden in some configs. */
|
||||||
|
|
||||||
#ifndef DEFAULT_PROMPT
|
#ifndef DEFAULT_PROMPT
|
||||||
#define DEFAULT_PROMPT "(gdb) "
|
#define DEFAULT_PROMPT "(gdb) "
|
||||||
|
@ -97,7 +97,7 @@ extern char lang_frame_mismatch_warn[]; /* language.c */
|
||||||
|
|
||||||
/* Flag for whether we want all the "from_tty" gubbish printed. */
|
/* Flag for whether we want all the "from_tty" gubbish printed. */
|
||||||
|
|
||||||
int caution = 1; /* Default is yes, sigh. */
|
int caution = 1; /* Default is yes, sigh. */
|
||||||
static void
|
static void
|
||||||
show_caution (struct ui_file *file, int from_tty,
|
show_caution (struct ui_file *file, int from_tty,
|
||||||
struct cmd_list_element *c, const char *value)
|
struct cmd_list_element *c, const char *value)
|
||||||
|
@ -107,9 +107,10 @@ Whether to confirm potentially dangerous operations is %s.\n"),
|
||||||
value);
|
value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* stdio stream that command input is being read from. Set to stdin normally.
|
/* stdio stream that command input is being read from. Set to stdin
|
||||||
Set by source_command to the file we are sourcing. Set to NULL if we are
|
normally. Set by source_command to the file we are sourcing. Set
|
||||||
executing a user-defined command or interacting via a GUI. */
|
to NULL if we are executing a user-defined command or interacting
|
||||||
|
via a GUI. */
|
||||||
|
|
||||||
FILE *instream;
|
FILE *instream;
|
||||||
|
|
||||||
|
@ -149,12 +150,12 @@ int server_command;
|
||||||
|
|
||||||
/* Baud rate specified for talking to serial target systems. Default
|
/* Baud rate specified for talking to serial target systems. Default
|
||||||
is left as -1, so targets can choose their own defaults. */
|
is left as -1, so targets can choose their own defaults. */
|
||||||
/* FIXME: This means that "show remotebaud" and gr_files_info can print -1
|
/* FIXME: This means that "show remotebaud" and gr_files_info can
|
||||||
or (unsigned int)-1. This is a Bad User Interface. */
|
print -1 or (unsigned int)-1. This is a Bad User Interface. */
|
||||||
|
|
||||||
int baud_rate = -1;
|
int baud_rate = -1;
|
||||||
|
|
||||||
/* Timeout limit for response from target. */
|
/* Timeout limit for response from target. */
|
||||||
|
|
||||||
/* The default value has been changed many times over the years. It
|
/* The default value has been changed many times over the years. It
|
||||||
was originally 5 seconds. But that was thought to be a long time
|
was originally 5 seconds. But that was thought to be a long time
|
||||||
|
@ -172,7 +173,7 @@ int baud_rate = -1;
|
||||||
a single variable for all protocol timeouts.
|
a single variable for all protocol timeouts.
|
||||||
|
|
||||||
As remote.c is used much more than remote-e7000.c, it was changed
|
As remote.c is used much more than remote-e7000.c, it was changed
|
||||||
back to 2 seconds in 1999. */
|
back to 2 seconds in 1999. */
|
||||||
|
|
||||||
int remote_timeout = 2;
|
int remote_timeout = 2;
|
||||||
|
|
||||||
|
@ -187,17 +188,18 @@ char *lim_at_start;
|
||||||
|
|
||||||
/* Hooks for alternate command interfaces. */
|
/* Hooks for alternate command interfaces. */
|
||||||
|
|
||||||
/* Called after most modules have been initialized, but before taking users
|
/* Called after most modules have been initialized, but before taking
|
||||||
command file.
|
users command file.
|
||||||
|
|
||||||
If the UI fails to initialize and it wants GDB to continue
|
If the UI fails to initialize and it wants GDB to continue using
|
||||||
using the default UI, then it should clear this hook before returning. */
|
the default UI, then it should clear this hook before returning. */
|
||||||
|
|
||||||
void (*deprecated_init_ui_hook) (char *argv0);
|
void (*deprecated_init_ui_hook) (char *argv0);
|
||||||
|
|
||||||
/* This hook is called from within gdb's many mini-event loops which could
|
/* This hook is called from within gdb's many mini-event loops which
|
||||||
steal control from a real user interface's event loop. It returns
|
could steal control from a real user interface's event loop. It
|
||||||
non-zero if the user is requesting a detach, zero otherwise. */
|
returns non-zero if the user is requesting a detach, zero
|
||||||
|
otherwise. */
|
||||||
|
|
||||||
int (*deprecated_ui_loop_hook) (int);
|
int (*deprecated_ui_loop_hook) (int);
|
||||||
|
|
||||||
|
@ -209,8 +211,10 @@ void (*deprecated_command_loop_hook) (void);
|
||||||
|
|
||||||
/* Called from print_frame_info to list the line we stopped in. */
|
/* Called from print_frame_info to list the line we stopped in. */
|
||||||
|
|
||||||
void (*deprecated_print_frame_info_listing_hook) (struct symtab * s, int line,
|
void (*deprecated_print_frame_info_listing_hook) (struct symtab * s,
|
||||||
int stopline, int noerror);
|
int line,
|
||||||
|
int stopline,
|
||||||
|
int noerror);
|
||||||
/* Replaces most of query. */
|
/* Replaces most of query. */
|
||||||
|
|
||||||
int (*deprecated_query_hook) (const char *, va_list);
|
int (*deprecated_query_hook) (const char *, va_list);
|
||||||
|
@ -236,33 +240,33 @@ char *(*deprecated_readline_hook) (char *);
|
||||||
void (*deprecated_readline_end_hook) (void);
|
void (*deprecated_readline_end_hook) (void);
|
||||||
|
|
||||||
/* Called as appropriate to notify the interface that we have attached
|
/* Called as appropriate to notify the interface that we have attached
|
||||||
to or detached from an already running process. */
|
to or detached from an already running process. */
|
||||||
|
|
||||||
void (*deprecated_attach_hook) (void);
|
void (*deprecated_attach_hook) (void);
|
||||||
void (*deprecated_detach_hook) (void);
|
void (*deprecated_detach_hook) (void);
|
||||||
|
|
||||||
/* Called during long calculations to allow GUI to repair window damage, and to
|
/* Called during long calculations to allow GUI to repair window
|
||||||
check for stop buttons, etc... */
|
damage, and to check for stop buttons, etc... */
|
||||||
|
|
||||||
void (*deprecated_interactive_hook) (void);
|
void (*deprecated_interactive_hook) (void);
|
||||||
|
|
||||||
/* Tell the GUI someone changed the register REGNO. -1 means
|
/* Tell the GUI someone changed the register REGNO. -1 means
|
||||||
that the caller does not know which register changed or
|
that the caller does not know which register changed or
|
||||||
that several registers have changed (see value_assign). */
|
that several registers have changed (see value_assign). */
|
||||||
void (*deprecated_register_changed_hook) (int regno);
|
void (*deprecated_register_changed_hook) (int regno);
|
||||||
|
|
||||||
/* Called when going to wait for the target. Usually allows the GUI to run
|
/* Called when going to wait for the target. Usually allows the GUI
|
||||||
while waiting for target events. */
|
to run while waiting for target events. */
|
||||||
|
|
||||||
ptid_t (*deprecated_target_wait_hook) (ptid_t ptid,
|
ptid_t (*deprecated_target_wait_hook) (ptid_t ptid,
|
||||||
struct target_waitstatus *status,
|
struct target_waitstatus *status,
|
||||||
int options);
|
int options);
|
||||||
|
|
||||||
/* Used by UI as a wrapper around command execution. May do various things
|
/* Used by UI as a wrapper around command execution. May do various
|
||||||
like enabling/disabling buttons, etc... */
|
things like enabling/disabling buttons, etc... */
|
||||||
|
|
||||||
void (*deprecated_call_command_hook) (struct cmd_list_element * c, char *cmd,
|
void (*deprecated_call_command_hook) (struct cmd_list_element * c,
|
||||||
int from_tty);
|
char *cmd, int from_tty);
|
||||||
|
|
||||||
/* Called after a `set' command has finished. Is only run if the
|
/* Called after a `set' command has finished. Is only run if the
|
||||||
`set' command succeeded. */
|
`set' command succeeded. */
|
||||||
|
@ -283,7 +287,8 @@ void (*deprecated_context_hook) (int id);
|
||||||
quit_cover (void *s)
|
quit_cover (void *s)
|
||||||
{
|
{
|
||||||
caution = 0; /* Throw caution to the wind -- we're exiting.
|
caution = 0; /* Throw caution to the wind -- we're exiting.
|
||||||
This prevents asking the user dumb questions. */
|
This prevents asking the user dumb
|
||||||
|
questions. */
|
||||||
quit_command ((char *) 0, 0);
|
quit_command ((char *) 0, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -339,10 +344,10 @@ prepare_execute_command (void)
|
||||||
{
|
{
|
||||||
free_all_values ();
|
free_all_values ();
|
||||||
|
|
||||||
/* With multiple threads running while the one we're examining is stopped,
|
/* With multiple threads running while the one we're examining is
|
||||||
the dcache can get stale without us being able to detect it.
|
stopped, the dcache can get stale without us being able to detect
|
||||||
For the duration of the command, though, use the dcache to help
|
it. For the duration of the command, though, use the dcache to
|
||||||
things like backtrace. */
|
help things like backtrace. */
|
||||||
if (non_stop)
|
if (non_stop)
|
||||||
target_dcache_invalidate ();
|
target_dcache_invalidate ();
|
||||||
}
|
}
|
||||||
|
@ -405,7 +410,7 @@ execute_command (char *p, int from_tty)
|
||||||
*(p + 1) = '\0';
|
*(p + 1) = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If this command has been pre-hooked, run the hook first. */
|
/* If this command has been pre-hooked, run the hook first. */
|
||||||
execute_cmd_pre_hook (c);
|
execute_cmd_pre_hook (c);
|
||||||
|
|
||||||
if (c->flags & DEPRECATED_WARN_USER)
|
if (c->flags & DEPRECATED_WARN_USER)
|
||||||
|
@ -422,7 +427,7 @@ execute_command (char *p, int from_tty)
|
||||||
else
|
else
|
||||||
cmd_func (c, arg, from_tty & caution);
|
cmd_func (c, arg, from_tty & caution);
|
||||||
|
|
||||||
/* If this command has been post-hooked, run the hook last. */
|
/* If this command has been post-hooked, run the hook last. */
|
||||||
execute_cmd_post_hook (c);
|
execute_cmd_post_hook (c);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -442,7 +447,7 @@ execute_command (char *p, int from_tty)
|
||||||
|
|
||||||
/* Warn the user if the working language does not match the
|
/* Warn the user if the working language does not match the
|
||||||
language of the current frame. Only warn the user if we are
|
language of the current frame. Only warn the user if we are
|
||||||
actually running the program, i.e. there is a stack. */
|
actually running the program, i.e. there is a stack. */
|
||||||
/* FIXME: This should be cacheing the frame and only running when
|
/* FIXME: This should be cacheing the frame and only running when
|
||||||
the frame changes. */
|
the frame changes. */
|
||||||
|
|
||||||
|
@ -523,7 +528,7 @@ command_loop (void)
|
||||||
reinitialize_more_filter ();
|
reinitialize_more_filter ();
|
||||||
old_chain = make_cleanup (null_cleanup, 0);
|
old_chain = make_cleanup (null_cleanup, 0);
|
||||||
|
|
||||||
/* Get a command-line. This calls the readline package. */
|
/* Get a command-line. This calls the readline package. */
|
||||||
command = command_line_input (instream == stdin ?
|
command = command_line_input (instream == stdin ?
|
||||||
get_prompt () : (char *) NULL,
|
get_prompt () : (char *) NULL,
|
||||||
instream == stdin, "prompt");
|
instream == stdin, "prompt");
|
||||||
|
@ -550,8 +555,8 @@ dont_repeat (void)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* If we aren't reading from standard input, we are saving the last
|
/* If we aren't reading from standard input, we are saving the last
|
||||||
thing read from stdin in line and don't want to delete it. Null lines
|
thing read from stdin in line and don't want to delete it. Null
|
||||||
won't repeat here in any case. */
|
lines won't repeat here in any case. */
|
||||||
if (instream == stdin)
|
if (instream == stdin)
|
||||||
*line = 0;
|
*line = 0;
|
||||||
}
|
}
|
||||||
|
@ -880,8 +885,9 @@ command_line_input (char *prompt_arg, int repeat, char *annotation_suffix)
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
/* Make sure that all output has been output. Some machines may let
|
/* Make sure that all output has been output. Some machines may
|
||||||
you get away with leaving out some of the gdb_flush, but not all. */
|
let you get away with leaving out some of the gdb_flush, but
|
||||||
|
not all. */
|
||||||
wrap_here ("");
|
wrap_here ("");
|
||||||
gdb_flush (gdb_stdout);
|
gdb_flush (gdb_stdout);
|
||||||
gdb_flush (gdb_stderr);
|
gdb_flush (gdb_stderr);
|
||||||
|
@ -931,7 +937,7 @@ command_line_input (char *prompt_arg, int repeat, char *annotation_suffix)
|
||||||
}
|
}
|
||||||
p1 = rl;
|
p1 = rl;
|
||||||
/* Copy line. Don't copy null at end. (Leaves line alone
|
/* Copy line. Don't copy null at end. (Leaves line alone
|
||||||
if this was just a newline) */
|
if this was just a newline). */
|
||||||
while (*p1)
|
while (*p1)
|
||||||
*p++ = *p1++;
|
*p++ = *p1++;
|
||||||
|
|
||||||
|
@ -997,9 +1003,8 @@ command_line_input (char *prompt_arg, int repeat, char *annotation_suffix)
|
||||||
xfree (history_value);
|
xfree (history_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we just got an empty line, and that is supposed
|
/* If we just got an empty line, and that is supposed to repeat the
|
||||||
to repeat the previous command, return the value in the
|
previous command, return the value in the global buffer. */
|
||||||
global buffer. */
|
|
||||||
if (repeat && p == linebuffer)
|
if (repeat && p == linebuffer)
|
||||||
return line;
|
return line;
|
||||||
for (p1 = linebuffer; *p1 == ' ' || *p1 == '\t'; p1++);
|
for (p1 = linebuffer; *p1 == ' ' || *p1 == '\t'; p1++);
|
||||||
|
@ -1020,7 +1025,7 @@ command_line_input (char *prompt_arg, int repeat, char *annotation_suffix)
|
||||||
and remove the '#'. The kill ring is probably better, but some
|
and remove the '#'. The kill ring is probably better, but some
|
||||||
people are in the habit of commenting things out. */
|
people are in the habit of commenting things out. */
|
||||||
if (*p1 == '#')
|
if (*p1 == '#')
|
||||||
*p1 = '\0'; /* Found a comment. */
|
*p1 = '\0'; /* Found a comment. */
|
||||||
|
|
||||||
/* Save into global buffer if appropriate. */
|
/* Save into global buffer if appropriate. */
|
||||||
if (repeat)
|
if (repeat)
|
||||||
|
@ -1037,24 +1042,24 @@ command_line_input (char *prompt_arg, int repeat, char *annotation_suffix)
|
||||||
return linebuffer;
|
return linebuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Print the GDB banner. */
|
/* Print the GDB banner. */
|
||||||
void
|
void
|
||||||
print_gdb_version (struct ui_file *stream)
|
print_gdb_version (struct ui_file *stream)
|
||||||
{
|
{
|
||||||
/* From GNU coding standards, first line is meant to be easy for a
|
/* From GNU coding standards, first line is meant to be easy for a
|
||||||
program to parse, and is just canonical program name and version
|
program to parse, and is just canonical program name and version
|
||||||
number, which starts after last space. */
|
number, which starts after last space. */
|
||||||
|
|
||||||
fprintf_filtered (stream, "GNU gdb %s%s\n", PKGVERSION, version);
|
fprintf_filtered (stream, "GNU gdb %s%s\n", PKGVERSION, version);
|
||||||
|
|
||||||
/* Second line is a copyright notice. */
|
/* Second line is a copyright notice. */
|
||||||
|
|
||||||
fprintf_filtered (stream, "Copyright (C) 2010 Free Software Foundation, Inc.\n");
|
fprintf_filtered (stream, "Copyright (C) 2010 Free Software Foundation, Inc.\n");
|
||||||
|
|
||||||
/* Following the copyright is a brief statement that the program is
|
/* Following the copyright is a brief statement that the program is
|
||||||
free software, that users are free to copy and change it on
|
free software, that users are free to copy and change it on
|
||||||
certain conditions, that it is covered by the GNU GPL, and that
|
certain conditions, that it is covered by the GNU GPL, and that
|
||||||
there is no warranty. */
|
there is no warranty. */
|
||||||
|
|
||||||
fprintf_filtered (stream, "\
|
fprintf_filtered (stream, "\
|
||||||
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\n\
|
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\n\
|
||||||
|
@ -1062,7 +1067,7 @@ This is free software: you are free to change and redistribute it.\n\
|
||||||
There is NO WARRANTY, to the extent permitted by law. Type \"show copying\"\n\
|
There is NO WARRANTY, to the extent permitted by law. Type \"show copying\"\n\
|
||||||
and \"show warranty\" for details.\n");
|
and \"show warranty\" for details.\n");
|
||||||
|
|
||||||
/* After the required info we print the configuration information. */
|
/* After the required info we print the configuration information. */
|
||||||
|
|
||||||
fprintf_filtered (stream, "This GDB was configured as \"");
|
fprintf_filtered (stream, "This GDB was configured as \"");
|
||||||
if (strcmp (host_name, target_name) != 0)
|
if (strcmp (host_name, target_name) != 0)
|
||||||
|
@ -1097,7 +1102,7 @@ set_prompt (char *s)
|
||||||
/* ??rehrauer: I don't know why this fails, since it looks as though
|
/* ??rehrauer: I don't know why this fails, since it looks as though
|
||||||
assignments to prompt are wrapped in calls to xstrdup...
|
assignments to prompt are wrapped in calls to xstrdup...
|
||||||
if (prompt != NULL)
|
if (prompt != NULL)
|
||||||
xfree (prompt);
|
xfree (prompt);
|
||||||
*/
|
*/
|
||||||
PROMPT (0) = xstrdup (s);
|
PROMPT (0) = xstrdup (s);
|
||||||
}
|
}
|
||||||
|
@ -1221,8 +1226,8 @@ quit_target (void *arg)
|
||||||
if (write_history_p && history_filename)
|
if (write_history_p && history_filename)
|
||||||
write_history (history_filename);
|
write_history (history_filename);
|
||||||
|
|
||||||
do_final_cleanups (ALL_CLEANUPS); /* Do any final cleanups before exiting */
|
do_final_cleanups (ALL_CLEANUPS); /* Do any final cleanups before
|
||||||
|
exiting. */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1235,7 +1240,7 @@ quit_force (char *args, int from_tty)
|
||||||
struct qt_args qt;
|
struct qt_args qt;
|
||||||
|
|
||||||
/* An optional expression may be used to cause gdb to terminate with the
|
/* An optional expression may be used to cause gdb to terminate with the
|
||||||
value of that expression. */
|
value of that expression. */
|
||||||
if (args)
|
if (args)
|
||||||
{
|
{
|
||||||
struct value *val = parse_and_eval (args);
|
struct value *val = parse_and_eval (args);
|
||||||
|
@ -1305,8 +1310,8 @@ input_from_terminal_p (void)
|
||||||
static void
|
static void
|
||||||
dont_repeat_command (char *ignored, int from_tty)
|
dont_repeat_command (char *ignored, int from_tty)
|
||||||
{
|
{
|
||||||
*line = 0; /* Can't call dont_repeat here because we're not
|
*line = 0; /* Can't call dont_repeat here because we're
|
||||||
necessarily reading from stdin. */
|
not necessarily reading from stdin. */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Functions to manipulate command line editing control variables. */
|
/* Functions to manipulate command line editing control variables. */
|
||||||
|
@ -1414,7 +1419,7 @@ show_history (char *args, int from_tty)
|
||||||
cmd_show_list (showhistlist, from_tty, "");
|
cmd_show_list (showhistlist, from_tty, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
int info_verbose = 0; /* Default verbose msgs off */
|
int info_verbose = 0; /* Default verbose msgs off. */
|
||||||
|
|
||||||
/* Called by do_setshow_command. An elaborate joke. */
|
/* Called by do_setshow_command. An elaborate joke. */
|
||||||
void
|
void
|
||||||
|
@ -1438,10 +1443,9 @@ set_verbose (char *args, int from_tty, struct cmd_list_element *c)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Init the history buffer. Note that we are called after the init file(s)
|
/* Init the history buffer. Note that we are called after the init file(s)
|
||||||
* have been read so that the user can change the history file via his
|
have been read so that the user can change the history file via his
|
||||||
* .gdbinit file (for instance). The GDBHISTFILE environment variable
|
.gdbinit file (for instance). The GDBHISTFILE environment variable
|
||||||
* overrides all of this.
|
overrides all of this. */
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
void
|
||||||
init_history (void)
|
init_history (void)
|
||||||
|
@ -1647,7 +1651,7 @@ gdb_init (char *argv0)
|
||||||
if (pre_init_ui_hook)
|
if (pre_init_ui_hook)
|
||||||
pre_init_ui_hook ();
|
pre_init_ui_hook ();
|
||||||
|
|
||||||
/* Run the init function of each source file */
|
/* Run the init function of each source file. */
|
||||||
|
|
||||||
#ifdef __MSDOS__
|
#ifdef __MSDOS__
|
||||||
/* Make sure we return to the original directory upon exit, come
|
/* Make sure we return to the original directory upon exit, come
|
||||||
|
@ -1655,9 +1659,9 @@ gdb_init (char *argv0)
|
||||||
make_final_cleanup (do_chdir_cleanup, xstrdup (current_directory));
|
make_final_cleanup (do_chdir_cleanup, xstrdup (current_directory));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
init_cmd_lists (); /* This needs to be done first */
|
init_cmd_lists (); /* This needs to be done first. */
|
||||||
initialize_targets (); /* Setup target_terminal macros for utils.c */
|
initialize_targets (); /* Setup target_terminal macros for utils.c. */
|
||||||
initialize_utils (); /* Make errors and warnings possible */
|
initialize_utils (); /* Make errors and warnings possible. */
|
||||||
|
|
||||||
/* Here is where we call all the _initialize_foo routines. */
|
/* Here is where we call all the _initialize_foo routines. */
|
||||||
initialize_all_files ();
|
initialize_all_files ();
|
||||||
|
@ -1671,17 +1675,18 @@ gdb_init (char *argv0)
|
||||||
initialize_inferiors ();
|
initialize_inferiors ();
|
||||||
initialize_current_architecture ();
|
initialize_current_architecture ();
|
||||||
init_cli_cmds();
|
init_cli_cmds();
|
||||||
init_main (); /* But that omits this file! Do it now */
|
init_main (); /* But that omits this file! Do it now. */
|
||||||
|
|
||||||
initialize_stdin_serial ();
|
initialize_stdin_serial ();
|
||||||
|
|
||||||
async_init_signals ();
|
async_init_signals ();
|
||||||
|
|
||||||
/* We need a default language for parsing expressions, so simple things like
|
/* We need a default language for parsing expressions, so simple
|
||||||
"set width 0" won't fail if no language is explicitly set in a config file
|
things like "set width 0" won't fail if no language is explicitly
|
||||||
or implicitly set by reading an executable during startup. */
|
set in a config file or implicitly set by reading an executable
|
||||||
|
during startup. */
|
||||||
set_language (language_c);
|
set_language (language_c);
|
||||||
expected_language = current_language; /* don't warn about the change. */
|
expected_language = current_language; /* Don't warn about the change. */
|
||||||
|
|
||||||
/* Allow another UI to initialize. If the UI fails to initialize,
|
/* Allow another UI to initialize. If the UI fails to initialize,
|
||||||
and it wants GDB to revert to the CLI, it should clear
|
and it wants GDB to revert to the CLI, it should clear
|
||||||
|
@ -1690,10 +1695,10 @@ gdb_init (char *argv0)
|
||||||
deprecated_init_ui_hook (argv0);
|
deprecated_init_ui_hook (argv0);
|
||||||
|
|
||||||
#ifdef HAVE_PYTHON
|
#ifdef HAVE_PYTHON
|
||||||
/* Python initialization can require various commands to be installed.
|
/* Python initialization can require various commands to be
|
||||||
For example "info pretty-printer" needs the "info" prefix to be
|
installed. For example "info pretty-printer" needs the "info"
|
||||||
installed. Keep things simple and just do final python initialization
|
prefix to be installed. Keep things simple and just do final
|
||||||
here. */
|
python initialization here. */
|
||||||
finish_python_initialization ();
|
finish_python_initialization ();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
10
gdb/top.h
10
gdb/top.h
|
@ -52,21 +52,21 @@ extern void execute_command (char *, int);
|
||||||
extern void prepare_execute_command (void);
|
extern void prepare_execute_command (void);
|
||||||
|
|
||||||
/* This function returns a pointer to the string that is used
|
/* This function returns a pointer to the string that is used
|
||||||
by gdb for its command prompt. */
|
by gdb for its command prompt. */
|
||||||
extern char *get_prompt (void);
|
extern char *get_prompt (void);
|
||||||
|
|
||||||
/* This function copies the specified string into the string that
|
/* This function copies the specified string into the string that
|
||||||
is used by gdb for its command prompt. */
|
is used by gdb for its command prompt. */
|
||||||
extern void set_prompt (char *);
|
extern void set_prompt (char *);
|
||||||
|
|
||||||
/* From random places. */
|
/* From random places. */
|
||||||
extern int readnow_symbol_files;
|
extern int readnow_symbol_files;
|
||||||
|
|
||||||
/* Perform _initialize initialization */
|
/* Perform _initialize initialization. */
|
||||||
extern void gdb_init (char *);
|
extern void gdb_init (char *);
|
||||||
|
|
||||||
/* For use by event-top.c */
|
/* For use by event-top.c. */
|
||||||
/* Variables from top.c. */
|
/* Variables from top.c. */
|
||||||
extern int source_line_number;
|
extern int source_line_number;
|
||||||
extern const char *source_file_name;
|
extern const char *source_file_name;
|
||||||
extern int history_expansion_p;
|
extern int history_expansion_p;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue