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>
|
||||
|
||||
* ax-gdb.c (gen_expr) <OP_REGISTER>: Error out if trying to
|
||||
|
|
328
gdb/event-loop.c
328
gdb/event-loop.c
|
@ -16,7 +16,7 @@
|
|||
GNU General Public License for more details.
|
||||
|
||||
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 "event-loop.h"
|
||||
|
@ -38,8 +38,8 @@
|
|||
#include "gdb_assert.h"
|
||||
#include "gdb_select.h"
|
||||
|
||||
/* Tell create_file_handler what events we are interested in.
|
||||
This is used by the select version of the event loop. */
|
||||
/* Tell create_file_handler what events we are interested in.
|
||||
This is used by the select version of the event loop. */
|
||||
|
||||
#define GDB_READABLE (1<<1)
|
||||
#define GDB_WRITABLE (1<<2)
|
||||
|
@ -56,12 +56,12 @@ typedef struct gdb_event gdb_event;
|
|||
typedef void (event_handler_func) (event_data);
|
||||
|
||||
/* 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
|
||||
read. Servicing an event simply means that the procedure PROC will
|
||||
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
|
||||
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
|
||||
is always the same (handle_file_event). Its duty is to invoke the
|
||||
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
|
||||
loop. */
|
||||
loop. */
|
||||
|
||||
typedef struct file_handler
|
||||
{
|
||||
int fd; /* File descriptor. */
|
||||
int mask; /* Events we want to monitor: POLLIN, etc. */
|
||||
int fd; /* File descriptor. */
|
||||
int mask; /* Events we want to monitor: POLLIN, etc. */
|
||||
int ready_mask; /* Events that have been seen since
|
||||
the last time. */
|
||||
handler_func *proc; /* Procedure to call when fd is ready. */
|
||||
gdb_client_data client_data; /* Argument to pass to proc. */
|
||||
int error; /* Was an error detected on this fd? */
|
||||
struct file_handler *next_file; /* Next registered file descriptor. */
|
||||
the last time. */
|
||||
handler_func *proc; /* Procedure to call when fd is ready. */
|
||||
gdb_client_data client_data; /* Argument to pass to proc. */
|
||||
int error; /* Was an error detected on this fd? */
|
||||
struct file_handler *next_file; /* Next registered file descriptor. */
|
||||
}
|
||||
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
|
||||
handler has 'triggered' this async_signal_handler for
|
||||
execution. The actual work to be done in response to a signal will
|
||||
be carried out by PROC at a later time, within process_event. This
|
||||
provides a deferred execution of signal handlers.
|
||||
handler has 'triggered' this async_signal_handler for execution.
|
||||
The actual work to be done in response to a signal will be carried
|
||||
out by PROC at a later time, within process_event. This provides a
|
||||
deferred execution of signal handlers.
|
||||
|
||||
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
|
||||
{
|
||||
int ready; /* If ready, call this handler from the main event loop,
|
||||
using invoke_async_handler. */
|
||||
struct async_signal_handler *next_handler; /* Ptr to next handler */
|
||||
sig_handler_func *proc; /* Function to call to do the work */
|
||||
gdb_client_data client_data; /* Argument to async_handler_func */
|
||||
int ready; /* If ready, call this handler
|
||||
from the main event loop, using
|
||||
invoke_async_handler. */
|
||||
struct async_signal_handler *next_handler; /* Ptr to next handler. */
|
||||
sig_handler_func *proc; /* Function to call to do the work. */
|
||||
gdb_client_data client_data; /* Argument to async_handler_func. */
|
||||
}
|
||||
async_signal_handler;
|
||||
|
||||
|
@ -140,7 +143,7 @@ async_event_handler;
|
|||
|
||||
|
||||
/* Event queue:
|
||||
- the first event in the queue is the head of the queue.
|
||||
- the first event in the queue is the head of the queue.
|
||||
It will be the next to be serviced.
|
||||
- the last event in the queue
|
||||
|
||||
|
@ -150,25 +153,25 @@ async_event_handler;
|
|||
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
|
||||
in first out manner. All the fields are NULL if the queue is
|
||||
empty. */
|
||||
empty. */
|
||||
|
||||
static struct
|
||||
{
|
||||
gdb_event *first_event; /* First pending event */
|
||||
gdb_event *last_event; /* Last pending event */
|
||||
gdb_event *first_event; /* First pending event. */
|
||||
gdb_event *last_event; /* Last pending event. */
|
||||
}
|
||||
event_queue;
|
||||
|
||||
/* Gdb_notifier is just a list of file descriptors gdb is interested in.
|
||||
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
|
||||
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
|
||||
in, for each fd. */
|
||||
in, for each fd. */
|
||||
|
||||
/* As of 1999-04-30 only the input file descriptor is registered with the
|
||||
event loop. */
|
||||
event loop. */
|
||||
|
||||
/* Do we use poll or select ? */
|
||||
#ifdef HAVE_POLL
|
||||
|
@ -186,79 +189,79 @@ static unsigned char use_poll = USE_POLL;
|
|||
|
||||
static struct
|
||||
{
|
||||
/* Ptr to head of file handler list. */
|
||||
/* Ptr to head of file handler list. */
|
||||
file_handler *first_file_handler;
|
||||
|
||||
#ifdef HAVE_POLL
|
||||
/* Ptr to array of pollfd structures. */
|
||||
/* Ptr to array of pollfd structures. */
|
||||
struct pollfd *poll_fds;
|
||||
|
||||
/* Timeout in milliseconds for calls to poll(). */
|
||||
/* Timeout in milliseconds for calls to poll(). */
|
||||
int poll_timeout;
|
||||
#endif
|
||||
|
||||
/* 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];
|
||||
|
||||
/* What file descriptors were found ready by select. */
|
||||
/* What file descriptors were found ready by select. */
|
||||
fd_set ready_masks[3];
|
||||
|
||||
/* Number of file descriptors to monitor. (for poll) */
|
||||
/* Number of valid bits (highest fd value + 1). (for select) */
|
||||
/* Number of file descriptors to monitor (for poll). */
|
||||
/* Number of valid bits (highest fd value + 1) (for select). */
|
||||
int num_fds;
|
||||
|
||||
/* Time structure for calls to select(). */
|
||||
/* Time structure for calls to select(). */
|
||||
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;
|
||||
}
|
||||
gdb_notifier;
|
||||
|
||||
/* Structure associated with a timer. PROC will be executed at the
|
||||
first occasion after WHEN. */
|
||||
/* Structure associated with a timer. PROC will be executed at the
|
||||
first occasion after WHEN. */
|
||||
struct gdb_timer
|
||||
{
|
||||
struct timeval when;
|
||||
int timer_id;
|
||||
struct gdb_timer *next;
|
||||
timer_handler_func *proc; /* Function to call to do the work */
|
||||
gdb_client_data client_data; /* Argument to async_handler_func */
|
||||
timer_handler_func *proc; /* Function to call to do the work. */
|
||||
gdb_client_data client_data; /* Argument to async_handler_func. */
|
||||
};
|
||||
|
||||
/* List of currently active timers. It is sorted in order of
|
||||
increasing timers. */
|
||||
/* List of currently active timers. It is sorted in order of
|
||||
increasing timers. */
|
||||
static struct
|
||||
{
|
||||
/* Pointer to first in timer list. */
|
||||
/* Pointer to first in timer list. */
|
||||
struct gdb_timer *first_timer;
|
||||
|
||||
/* Id of the last timer created. */
|
||||
/* Id of the last timer created. */
|
||||
int num_timers;
|
||||
}
|
||||
timer_list;
|
||||
|
||||
/* All the async_signal_handlers gdb is interested in are kept onto
|
||||
this list. */
|
||||
this list. */
|
||||
static struct
|
||||
{
|
||||
/* Pointer to first in handler list. */
|
||||
/* Pointer to first in handler list. */
|
||||
async_signal_handler *first_handler;
|
||||
|
||||
/* Pointer to last in handler list. */
|
||||
/* Pointer to last in handler list. */
|
||||
async_signal_handler *last_handler;
|
||||
}
|
||||
sighandler_list;
|
||||
|
||||
/* All the async_event_handlers gdb is interested in are kept onto
|
||||
this list. */
|
||||
this list. */
|
||||
static struct
|
||||
{
|
||||
/* Pointer to first in handler list. */
|
||||
/* Pointer to first in handler list. */
|
||||
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_list;
|
||||
|
@ -276,18 +279,18 @@ static void poll_timers (void);
|
|||
the specified position.
|
||||
POSITION can be head or tail, with values TAIL, HEAD.
|
||||
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.
|
||||
Events in the queue will be processed head to tail, therefore,
|
||||
events inserted at the head of the queue will be processed
|
||||
as last in first out. Event appended at the tail of the queue
|
||||
will be processed first in first out. */
|
||||
as last in first out. Event appended at the tail of the queue
|
||||
will be processed first in first out. */
|
||||
static void
|
||||
async_queue_event (gdb_event * event_ptr, queue_position position)
|
||||
{
|
||||
if (position == TAIL)
|
||||
{
|
||||
/* The event will become the new last_event. */
|
||||
/* The event will become the new last_event. */
|
||||
|
||||
event_ptr->next_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)
|
||||
{
|
||||
/* The event becomes the new first_event. */
|
||||
/* The event becomes the new first_event. */
|
||||
|
||||
event_ptr->next_event = event_queue.first_event;
|
||||
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
|
||||
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
|
||||
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 *
|
||||
create_file_event (int fd)
|
||||
{
|
||||
|
@ -344,7 +347,7 @@ create_file_event (int fd)
|
|||
0 is returned.
|
||||
Scan the queue from head to tail, processing therefore the high
|
||||
priority events first, by invoking the associated event handler
|
||||
procedure. */
|
||||
procedure. */
|
||||
static int
|
||||
process_event (void)
|
||||
{
|
||||
|
@ -353,19 +356,19 @@ process_event (void)
|
|||
event_data data;
|
||||
|
||||
/* First let's see if there are any asynchronous event handlers that
|
||||
are ready. These would be the result of invoking any of the
|
||||
signal handlers. */
|
||||
are ready. These would be the result of invoking any of the
|
||||
signal handlers. */
|
||||
|
||||
if (invoke_async_signal_handlers ())
|
||||
return 1;
|
||||
|
||||
/* 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;
|
||||
event_ptr = event_ptr->next_event)
|
||||
{
|
||||
/* Call the handler for the event. */
|
||||
/* Call the handler for the event. */
|
||||
|
||||
proc = event_ptr->proc;
|
||||
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
|
||||
do this now because while processing the event, the proc
|
||||
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
|
||||
processed, but not deleted. */
|
||||
processed, but not deleted. */
|
||||
|
||||
if (event_queue.first_event == event_ptr)
|
||||
{
|
||||
|
@ -395,12 +398,12 @@ process_event (void)
|
|||
}
|
||||
xfree (event_ptr);
|
||||
|
||||
/* Now call the procedure associated with the event. */
|
||||
/* Now call the procedure associated with the event. */
|
||||
(*proc) (data);
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -408,7 +411,7 @@ process_event (void)
|
|||
wait for something to happen (via gdb_wait_for_event), then process
|
||||
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
|
||||
occurs catch_errors() which calls this function returns zero. */
|
||||
occurs catch_errors() which calls this function returns zero. */
|
||||
|
||||
int
|
||||
gdb_do_one_event (void *data)
|
||||
|
@ -429,7 +432,7 @@ gdb_do_one_event (void *data)
|
|||
{
|
||||
case 0:
|
||||
/* Are any timers that are ready? If so, put an event on the
|
||||
queue. */
|
||||
queue. */
|
||||
poll_timers ();
|
||||
break;
|
||||
case 1:
|
||||
|
@ -469,18 +472,18 @@ gdb_do_one_event (void *data)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* Start up the event loop. This is the entry point to the event loop
|
||||
from the command loop. */
|
||||
/* Start up the event loop. This is the entry point to the event loop
|
||||
from the command loop. */
|
||||
|
||||
void
|
||||
start_event_loop (void)
|
||||
{
|
||||
/* 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()
|
||||
/* 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()
|
||||
will process one event for each invocation. It blocks waits for
|
||||
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
|
||||
longer any event sources registered. */
|
||||
longer any event sources registered. */
|
||||
while (1)
|
||||
{
|
||||
int gdb_result;
|
||||
|
@ -491,7 +494,7 @@ start_event_loop (void)
|
|||
|
||||
/* If we long-jumped out of do_one_event, we probably
|
||||
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)
|
||||
{
|
||||
|
@ -501,7 +504,7 @@ start_event_loop (void)
|
|||
async_enable_stdin ();
|
||||
/* FIXME: this should really be a call to a hook that is
|
||||
interface specific, because interfaces can display the
|
||||
prompt in their own way. */
|
||||
prompt in their own way. */
|
||||
display_gdb_prompt (0);
|
||||
/* This call looks bizarre, but it is required. If the user
|
||||
entered a command that caused an error,
|
||||
|
@ -512,19 +515,19 @@ start_event_loop (void)
|
|||
if (after_char_processing_hook)
|
||||
(*after_char_processing_hook) ();
|
||||
/* 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
|
||||
to listen to. So we exit GDB. */
|
||||
/* We are done with the event loop. There are no more event sources
|
||||
to listen to. So we exit GDB. */
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Wrapper function for create_file_handler, so that the caller
|
||||
doesn't have to know implementation details about the use of poll
|
||||
vs. select. */
|
||||
vs. select. */
|
||||
void
|
||||
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)
|
||||
{
|
||||
#ifdef HAVE_POLL
|
||||
/* Check to see if poll () is usable. If not, we'll switch to
|
||||
use select. This can happen on systems like
|
||||
/* Check to see if poll () is usable. If not, we'll switch to
|
||||
use select. This can happen on systems like
|
||||
m68k-motorola-sys, `poll' cannot be used to wait for `stdin'.
|
||||
On m68k-motorola-sysv, tty's are not stream-based and not
|
||||
`poll'able. */
|
||||
`poll'able. */
|
||||
fds.fd = fd;
|
||||
fds.events = POLLIN;
|
||||
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
|
||||
}
|
||||
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
|
||||
interested in.
|
||||
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,
|
||||
POLLWRBAND: these are the events we are interested in. If any of them
|
||||
occurs, proc should be called.
|
||||
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. */
|
||||
interested in.
|
||||
|
||||
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, POLLWRBAND:
|
||||
these are the events we are interested in. If any of them occurs,
|
||||
proc should be called.
|
||||
|
||||
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
|
||||
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;
|
||||
|
||||
/* Do we already have a file handler for this file? (We may be
|
||||
changing its associated procedure). */
|
||||
/* Do we already have a file handler for this file? (We may be
|
||||
changing its associated procedure). */
|
||||
for (file_ptr = gdb_notifier.first_file_handler; file_ptr != NULL;
|
||||
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;
|
||||
}
|
||||
|
||||
/* It is a new file descriptor. Add it to the list. Otherwise, just
|
||||
change the data associated with it. */
|
||||
/* It is a new file descriptor. Add it to the list. Otherwise, just
|
||||
change the data associated with it. */
|
||||
if (file_ptr == NULL)
|
||||
{
|
||||
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:
|
||||
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
|
||||
delete_file_handler (int fd)
|
||||
{
|
||||
|
@ -655,7 +664,7 @@ delete_file_handler (int fd)
|
|||
struct pollfd *new_poll_fds;
|
||||
#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;
|
||||
file_ptr = file_ptr->next_file)
|
||||
|
@ -670,11 +679,11 @@ delete_file_handler (int fd)
|
|||
if (use_poll)
|
||||
{
|
||||
#ifdef HAVE_POLL
|
||||
/* Create a new poll_fds array by copying every fd's information but the
|
||||
one we want to get rid of. */
|
||||
/* Create a new poll_fds array by copying every fd's information
|
||||
but the one we want to get rid of. */
|
||||
|
||||
new_poll_fds =
|
||||
(struct pollfd *) xmalloc ((gdb_notifier.num_fds - 1) * sizeof (struct pollfd));
|
||||
new_poll_fds = (struct pollfd *)
|
||||
xmalloc ((gdb_notifier.num_fds - 1) * sizeof (struct pollfd));
|
||||
|
||||
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)
|
||||
FD_CLR (fd, &gdb_notifier.check_masks[2]);
|
||||
|
||||
/* Find current max fd. */
|
||||
/* Find current max fd. */
|
||||
|
||||
if ((fd + 1) == gdb_notifier.num_fds)
|
||||
{
|
||||
|
@ -720,11 +729,11 @@ delete_file_handler (int fd)
|
|||
}
|
||||
|
||||
/* 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;
|
||||
|
||||
/* 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)
|
||||
gdb_notifier.first_file_handler = file_ptr->next_file;
|
||||
else
|
||||
|
@ -741,7 +750,7 @@ delete_file_handler (int fd)
|
|||
/* Handle the given event by calling the procedure associated to the
|
||||
corresponding file handler. Called by process_event indirectly,
|
||||
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
|
||||
handle_file_event (event_data data)
|
||||
{
|
||||
|
@ -754,21 +763,21 @@ handle_file_event (event_data data)
|
|||
int event_file_desc = data.integer;
|
||||
|
||||
/* 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;
|
||||
file_ptr = file_ptr->next_file)
|
||||
{
|
||||
if (file_ptr->fd == event_file_desc)
|
||||
{
|
||||
/* With poll, the ready_mask could have any of three events
|
||||
set to 1: POLLHUP, POLLERR, POLLNVAL. These events cannot
|
||||
be used in the requested event mask (events), but they
|
||||
can be returned in the return mask (revents). We need to
|
||||
check for those event too, and add them to the mask which
|
||||
will be passed to the handler. */
|
||||
set to 1: POLLHUP, POLLERR, POLLNVAL. These events
|
||||
cannot be used in the requested event mask (events), but
|
||||
they can be returned in the return mask (revents). We
|
||||
need to check for those event too, and add them to the
|
||||
mask which will be passed to the handler. */
|
||||
|
||||
/* See if the desired events (mask) match the received
|
||||
events (ready_mask). */
|
||||
events (ready_mask). */
|
||||
|
||||
if (use_poll)
|
||||
{
|
||||
|
@ -780,8 +789,8 @@ handle_file_event (event_data data)
|
|||
|
||||
if (error_mask_returned != 0)
|
||||
{
|
||||
/* Work in progress. We may need to tell somebody what
|
||||
kind of error we had. */
|
||||
/* Work in progress. We may need to tell somebody
|
||||
what kind of error we had. */
|
||||
if (error_mask_returned & POLLHUP)
|
||||
printf_unfiltered (_("Hangup detected on fd %d\n"), file_ptr->fd);
|
||||
if (error_mask_returned & POLLERR)
|
||||
|
@ -809,10 +818,10 @@ handle_file_event (event_data data)
|
|||
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;
|
||||
|
||||
/* If there was a match, then call the handler. */
|
||||
/* If there was a match, then call the handler. */
|
||||
if (mask != 0)
|
||||
(*file_ptr->proc) (file_ptr->error, file_ptr->client_data);
|
||||
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
|
||||
file descriptors. Queue file events as they are detected by the
|
||||
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
|
||||
descriptors to monitor, otherwise return 0. */
|
||||
block in the call to poll. Return -1 if there are no file
|
||||
descriptors to monitor, otherwise return 0. */
|
||||
static int
|
||||
gdb_wait_for_event (int block)
|
||||
{
|
||||
|
@ -833,7 +842,7 @@ gdb_wait_for_event (int block)
|
|||
int num_found = 0;
|
||||
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_stderr);
|
||||
|
||||
|
@ -885,7 +894,7 @@ gdb_wait_for_event (int block)
|
|||
&gdb_notifier.ready_masks[2],
|
||||
timeout_p);
|
||||
|
||||
/* Clear the masks after an error from select. */
|
||||
/* Clear the masks after an error from select. */
|
||||
if (num_found == -1)
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
@ -922,7 +931,7 @@ gdb_wait_for_event (int block)
|
|||
if (file_ptr)
|
||||
{
|
||||
/* Enqueue an event only if this is still a new event for
|
||||
this fd. */
|
||||
this fd. */
|
||||
if (file_ptr->ready_mask == 0)
|
||||
{
|
||||
file_event_ptr = create_file_event (file_ptr->fd);
|
||||
|
@ -957,7 +966,7 @@ gdb_wait_for_event (int block)
|
|||
num_found--;
|
||||
|
||||
/* Enqueue an event only if this is still a new event for
|
||||
this fd. */
|
||||
this fd. */
|
||||
|
||||
if (file_ptr->ready_mask == 0)
|
||||
{
|
||||
|
@ -971,12 +980,12 @@ gdb_wait_for_event (int block)
|
|||
}
|
||||
|
||||
|
||||
/* Create an asynchronous handler, allocating memory for it.
|
||||
/* Create an asynchronous handler, allocating memory for it.
|
||||
Return a pointer to the newly created handler.
|
||||
This pointer will be used to invoke the handler by
|
||||
invoke_async_signal_handler.
|
||||
PROC is the function to call with CLIENT_DATA argument
|
||||
whenever the handler is invoked. */
|
||||
whenever the handler is invoked. */
|
||||
async_signal_handler *
|
||||
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);
|
||||
}
|
||||
|
||||
/* Mark the handler (ASYNC_HANDLER_PTR) as ready. This information will
|
||||
be used when the handlers are invoked, after we have waited for
|
||||
some event. The caller of this function is the interrupt handler
|
||||
associated with a signal. */
|
||||
/* Mark the handler (ASYNC_HANDLER_PTR) as ready. This information
|
||||
will be used when the handlers are invoked, after we have waited
|
||||
for some event. The caller of this function is the interrupt
|
||||
handler associated with a signal. */
|
||||
void
|
||||
mark_async_signal_handler (async_signal_handler * async_handler_ptr)
|
||||
{
|
||||
|
@ -1044,7 +1053,7 @@ invoke_async_signal_handlers (void)
|
|||
return any_ready;
|
||||
}
|
||||
|
||||
/* Delete an asynchronous handler (ASYNC_HANDLER_PTR).
|
||||
/* Delete an asynchronous handler (ASYNC_HANDLER_PTR).
|
||||
Free the space allocated for it. */
|
||||
void
|
||||
delete_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;
|
||||
}
|
||||
|
||||
/* Create a timer that will expire in MILLISECONDS from now. When the
|
||||
timer is ready, PROC will be executed. At creation, the timer is
|
||||
/* Create a timer that will expire in MILLISECONDS from now. When the
|
||||
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
|
||||
increasing timers. Return a handle to the timer struct. */
|
||||
increasing timers. Return a handle to the timer struct. */
|
||||
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 timeval time_now, delta;
|
||||
|
||||
/* compute seconds */
|
||||
/* Compute seconds. */
|
||||
delta.tv_sec = milliseconds / 1000;
|
||||
/* compute microseconds */
|
||||
/* Compute microseconds. */
|
||||
delta.tv_usec = (milliseconds % 1000) * 1000;
|
||||
|
||||
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->when.tv_sec = time_now.tv_sec + delta.tv_sec;
|
||||
timer_ptr->when.tv_usec = time_now.tv_usec + delta.tv_usec;
|
||||
/* carry? */
|
||||
/* Carry? */
|
||||
if (timer_ptr->when.tv_usec >= 1000000)
|
||||
{
|
||||
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;
|
||||
|
||||
/* 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;
|
||||
timer_index != NULL;
|
||||
timer_index = timer_index->next)
|
||||
{
|
||||
/* 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)
|
||||
|| ((timer_index->when.tv_sec == timer_ptr->when.tv_sec)
|
||||
&& (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
|
||||
it before it expires. */
|
||||
it before it expires. */
|
||||
void
|
||||
delete_timer (int id)
|
||||
{
|
||||
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;
|
||||
timer_ptr = timer_ptr->next)
|
||||
|
@ -1262,7 +1272,7 @@ delete_timer (int id)
|
|||
|
||||
if (timer_ptr == NULL)
|
||||
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)
|
||||
timer_list.first_timer = timer_ptr->next;
|
||||
else
|
||||
|
@ -1298,11 +1308,11 @@ handle_timer_event (event_data dummy)
|
|||
&& (timer_ptr->when.tv_usec > time_now.tv_usec)))
|
||||
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;
|
||||
saved_timer = timer_ptr;
|
||||
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);
|
||||
xfree (saved_timer);
|
||||
}
|
||||
|
@ -1310,12 +1320,12 @@ handle_timer_event (event_data dummy)
|
|||
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
|
||||
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
|
||||
procedures associated with all that have expired. Update the
|
||||
timeout for the select() or poll() as well. */
|
||||
procedures associated with all that have expired.l Update the
|
||||
timeout for the select() or poll() as well. */
|
||||
static void
|
||||
poll_timers (void)
|
||||
{
|
||||
|
@ -1327,15 +1337,15 @@ poll_timers (void)
|
|||
gettimeofday (&time_now, NULL);
|
||||
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;
|
||||
/* borrow? */
|
||||
/* Borrow? */
|
||||
if (delta.tv_usec < 0)
|
||||
{
|
||||
delta.tv_sec -= 1;
|
||||
delta.tv_usec += 1000000;
|
||||
}
|
||||
|
||||
/* Oops it expired already. Tell select / poll to return
|
||||
immediately. (Cannot simply test if delta.tv_sec is negative
|
||||
/* Oops it expired already. Tell select / poll to return
|
||||
immediately. (Cannot simply test if delta.tv_sec is negative
|
||||
because time_t might be unsigned.) */
|
||||
if (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);
|
||||
}
|
||||
|
||||
/* Now we need to update the timeout for select/ poll, because we
|
||||
don't want to sit there while this timer is expiring. */
|
||||
/* Now we need to update the timeout for select/ poll, because
|
||||
we don't want to sit there while this timer is expiring. */
|
||||
if (use_poll)
|
||||
{
|
||||
#ifdef HAVE_POLL
|
||||
|
|
|
@ -18,18 +18,18 @@
|
|||
You should have received a copy of the GNU General Public License
|
||||
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
|
||||
appropriate event handler. The event loop then continues to listen
|
||||
for more events. An event loop completes when there are no event
|
||||
appropriate event handler. The event loop then continues to listen
|
||||
for more events. An event loop completes when there are no event
|
||||
sources to listen on. External event sources can be plugged into
|
||||
the loop.
|
||||
|
||||
There are 4 main components:
|
||||
- a list of file descriptors to be monitored, GDB_NOTIFIER.
|
||||
- a list of file descriptors to be monitored, GDB_NOTIFIER.
|
||||
- a list of asynchronous event sources to be monitored,
|
||||
ASYNC_EVENT_HANDLER_LIST.
|
||||
- a list of events that have occurred, EVENT_QUEUE.
|
||||
- a list of events that have occurred, EVENT_QUEUE.
|
||||
- a list of signal handling functions, SIGHANDLER_LIST.
|
||||
|
||||
GDB_NOTIFIER keeps track of the file descriptor based event
|
||||
|
@ -64,9 +64,9 @@
|
|||
functions that are invoked through traditional signal handlers.
|
||||
The actions to be taken is response to such events will be executed
|
||||
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;
|
||||
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 (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
|
||||
{
|
||||
/* Add at tail of queue. It will be processed in first in first
|
||||
out order. */
|
||||
/* Add at tail of queue. It will be processed in first in first
|
||||
out order. */
|
||||
TAIL,
|
||||
/* Add at head of queue. It will be processed in last in first out
|
||||
order. */
|
||||
/* Add at head of queue. It will be processed in last in first
|
||||
out order. */
|
||||
HEAD
|
||||
}
|
||||
queue_position;
|
||||
|
@ -93,11 +93,15 @@ queue_position;
|
|||
extern void start_event_loop (void);
|
||||
extern int gdb_do_one_event (void *data);
|
||||
extern void delete_file_handler (int fd);
|
||||
extern void add_file_handler (int fd, handler_func * proc, gdb_client_data client_data);
|
||||
extern void add_file_handler (int fd, handler_func *proc,
|
||||
gdb_client_data client_data);
|
||||
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 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);
|
||||
|
||||
/* Call the handler from HANDLER immediately. This function
|
||||
|
|
297
gdb/event-top.c
297
gdb/event-top.c
|
@ -18,7 +18,7 @@
|
|||
GNU General Public License for more details.
|
||||
|
||||
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 "top.h"
|
||||
|
@ -34,10 +34,9 @@
|
|||
#include "main.h"
|
||||
#include "gdbthread.h"
|
||||
|
||||
/* For dont_repeat() */
|
||||
#include "gdbcmd.h"
|
||||
#include "gdbcmd.h" /* for dont_repeat() */
|
||||
|
||||
/* readline include files */
|
||||
/* readline include files. */
|
||||
#include "readline/readline.h"
|
||||
#include "readline/history.h"
|
||||
|
||||
|
@ -50,7 +49,7 @@ static void change_line_handler (void);
|
|||
static void change_annotation_level (void);
|
||||
static void command_handler (char *command);
|
||||
|
||||
/* Signal handlers. */
|
||||
/* Signal handlers. */
|
||||
#ifdef SIGQUIT
|
||||
static void handle_sigquit (int sig);
|
||||
#endif
|
||||
|
@ -63,7 +62,7 @@ static void handle_sigwinch (int sig);
|
|||
#endif
|
||||
|
||||
/* Functions to be invoked by the event loop in response to
|
||||
signals. */
|
||||
signals. */
|
||||
#if defined (SIGQUIT) || defined (SIGHUP)
|
||||
static void async_do_nothing (gdb_client_data);
|
||||
#endif
|
||||
|
@ -76,65 +75,65 @@ static void async_stop_sig (gdb_client_data);
|
|||
#endif
|
||||
|
||||
/* 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
|
||||
the event loop uses as callback (i.e. event handler) whenever an event
|
||||
is detected on the standard input file descriptor.
|
||||
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
|
||||
accumulates the line read up to the point of invocation. In the
|
||||
special case in which the character read is newline, the function
|
||||
invokes a GDB supplied callback routine, which does the processing of
|
||||
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
|
||||
command_loop for processing, the new command_line_handler function has
|
||||
the command line already available as its parameter. INPUT_HANDLER is
|
||||
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
|
||||
that readline offers as callback to the event_loop. */
|
||||
that readline offers as callback to the event_loop. */
|
||||
|
||||
void (*input_handler) (char *);
|
||||
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
|
||||
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.
|
||||
ezannoni: as of 1999-04-29 I expect that this
|
||||
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;
|
||||
|
||||
/* This variable contains the new prompt that the user sets with the
|
||||
set prompt command. */
|
||||
set prompt command. */
|
||||
char *new_async_prompt;
|
||||
|
||||
/* This is the annotation suffix that will be used when the
|
||||
annotation_level is 2. */
|
||||
annotation_level is 2. */
|
||||
char *async_annotation_suffix;
|
||||
|
||||
/* This is used to display the notification of the completion of an
|
||||
asynchronous execution command. */
|
||||
asynchronous execution command. */
|
||||
int exec_done_display_p = 0;
|
||||
|
||||
/* This is the file descriptor for the input stream that GDB uses to
|
||||
read commands from. */
|
||||
read commands from. */
|
||||
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
|
||||
for. See event-loop.h. */
|
||||
for. See event-loop.h. */
|
||||
struct prompts the_prompts;
|
||||
|
||||
/* signal handling variables */
|
||||
/* Signal handling variables. */
|
||||
/* 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
|
||||
loop, in a later iteration, calls them. See the function
|
||||
invoke_async_signal_handler. */
|
||||
loop, in a later iteration, calls them. See the function
|
||||
invoke_async_signal_handler. */
|
||||
void *sigint_token;
|
||||
#ifdef SIGHUP
|
||||
void *sighup_token;
|
||||
|
@ -151,10 +150,10 @@ void *sigtstp_token;
|
|||
#endif
|
||||
|
||||
/* 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
|
||||
command_line_handler, and normally there is no state retained
|
||||
between different calls. */
|
||||
between different calls. */
|
||||
int more_to_come = 0;
|
||||
|
||||
struct readline_input_state
|
||||
|
@ -169,9 +168,9 @@ readline_input_state;
|
|||
void (*after_char_processing_hook) ();
|
||||
|
||||
|
||||
/* Wrapper function for calling into the readline library. The event
|
||||
loop expects the callback function to have a paramter, while readline
|
||||
expects none. */
|
||||
/* Wrapper function for calling into the readline library. The event
|
||||
loop expects the callback function to have a paramter, while
|
||||
readline expects none. */
|
||||
static void
|
||||
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,
|
||||
register readline, and stdin, start the loop. */
|
||||
register readline, and stdin, start the loop. */
|
||||
void
|
||||
cli_command_loop (void)
|
||||
{
|
||||
/* 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)
|
||||
{
|
||||
int length;
|
||||
char *a_prompt;
|
||||
char *gdb_prompt = get_prompt ();
|
||||
|
||||
/* Tell readline what the prompt to display is and what function it
|
||||
will need to call after a whole line is read. This also displays
|
||||
the first prompt. */
|
||||
/* Tell readline what the prompt to display is and what function
|
||||
it will need to call after a whole line is read. This also
|
||||
displays the first prompt. */
|
||||
length = strlen (PREFIX (0))
|
||||
+ strlen (gdb_prompt) + strlen (SUFFIX (0)) + 1;
|
||||
a_prompt = (char *) alloca (length);
|
||||
|
@ -207,54 +206,54 @@ cli_command_loop (void)
|
|||
else
|
||||
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 ();
|
||||
}
|
||||
|
||||
/* 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
|
||||
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
|
||||
handling of the input. */
|
||||
handling of the input. */
|
||||
static void
|
||||
change_line_handler (void)
|
||||
{
|
||||
/* NOTE: this operates on input_fd, not instream. If we are reading
|
||||
commands from a file, instream will point to the file. However in
|
||||
/* NOTE: this operates on input_fd, not instream. If we are reading
|
||||
commands from a file, instream will point to the file. However in
|
||||
async mode, we always read commands from a file with editing
|
||||
off. This means that the 'set editing on/off' will have effect
|
||||
only on the interactive session. */
|
||||
off. This means that the 'set editing on/off' will have effect
|
||||
only on the interactive session. */
|
||||
|
||||
if (async_command_editing_p)
|
||||
{
|
||||
/* Turn on editing by using readline. */
|
||||
/* Turn on editing by using readline. */
|
||||
call_readline = rl_callback_read_char_wrapper;
|
||||
input_handler = command_line_handler;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Turn off editing by using gdb_readline2. */
|
||||
/* Turn off editing by using gdb_readline2. */
|
||||
rl_callback_handler_remove ();
|
||||
call_readline = gdb_readline2;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
/* Displays the prompt. The prompt that is displayed is the current
|
||||
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:
|
||||
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.
|
||||
In that case the prompt that is displayed is the empty string.
|
||||
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????
|
||||
FIXME: 2. & 3. not implemented yet for async. */
|
||||
FIXME: 2. & 3. not implemented yet for async. */
|
||||
void
|
||||
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
|
||||
don't call rl_callback_handler_install and
|
||||
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
|
||||
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
|
||||
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
|
||||
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 ();
|
||||
return;
|
||||
|
@ -292,18 +291,18 @@ display_gdb_prompt (char *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)) +
|
||||
strlen (SUFFIX (0)) +
|
||||
strlen (gdb_prompt) + 1;
|
||||
|
||||
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));
|
||||
strcat (new_prompt, gdb_prompt);
|
||||
/* Suffix needs to have a new line at end and \032 \032 at
|
||||
beginning. */
|
||||
beginning. */
|
||||
strcat (new_prompt, SUFFIX (0));
|
||||
}
|
||||
|
||||
|
@ -312,7 +311,8 @@ display_gdb_prompt (char *new_prompt)
|
|||
rl_callback_handler_remove ();
|
||||
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)
|
||||
{
|
||||
/* 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
|
||||
'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
|
||||
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
|
||||
change_annotation_level (void)
|
||||
{
|
||||
|
@ -336,7 +336,7 @@ change_annotation_level (void)
|
|||
if (!PREFIX (0) || !PROMPT (0) || !SUFFIX (0))
|
||||
{
|
||||
/* 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"));
|
||||
return;
|
||||
}
|
||||
|
@ -345,7 +345,7 @@ change_annotation_level (void)
|
|||
{
|
||||
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);
|
||||
strcpy (prefix, "\n\032\032pre-");
|
||||
strcat (prefix, async_annotation_suffix);
|
||||
|
@ -363,16 +363,16 @@ change_annotation_level (void)
|
|||
{
|
||||
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 ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Pushes a new prompt on the prompt stack. Each prompt has three
|
||||
parts: prefix, prompt, suffix. Usually prefix and suffix are empty
|
||||
strings, except when the annotation level is 2. Memory is allocated
|
||||
within xstrdup for the new prompt. */
|
||||
/* Pushes a new prompt on the prompt stack. Each prompt has three
|
||||
parts: prefix, prompt, suffix. Usually prefix and suffix are empty
|
||||
strings, except when the annotation level is 2. Memory is allocated
|
||||
within xstrdup for the new prompt. */
|
||||
void
|
||||
push_prompt (char *prefix, char *prompt, char *suffix)
|
||||
{
|
||||
|
@ -380,8 +380,8 @@ push_prompt (char *prefix, char *prompt, char *suffix)
|
|||
PREFIX (0) = xstrdup (prefix);
|
||||
|
||||
/* Note that this function is used by the set annotate 2
|
||||
command. This is why we take care of saving the old prompt
|
||||
in case a new one is not specified. */
|
||||
command. This is why we take care of saving the old prompt
|
||||
in case a new one is not specified. */
|
||||
if (prompt)
|
||||
PROMPT (0) = xstrdup (prompt);
|
||||
else
|
||||
|
@ -390,17 +390,18 @@ push_prompt (char *prefix, char *prompt, char *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
|
||||
pop_prompt (void)
|
||||
{
|
||||
/* 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), ""))
|
||||
/* 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
|
||||
in effect, until the user does another 'set prompt'. */
|
||||
in effect, until the user does another 'set prompt'. */
|
||||
if (strcmp (PROMPT (0), PROMPT (-1)))
|
||||
{
|
||||
xfree (PROMPT (-1));
|
||||
|
@ -416,7 +417,7 @@ pop_prompt (void)
|
|||
/* When there is an event ready on the stdin file desriptor, instead
|
||||
of calling readline directly throught the callback function, or
|
||||
instead of calling gdb_readline2, give gdb a chance to detect
|
||||
errors and do something. */
|
||||
errors and do something. */
|
||||
void
|
||||
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);
|
||||
discard_all_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);
|
||||
}
|
||||
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
|
||||
synchronous mode, or after an error from the target, and we aborted
|
||||
the exec operation. */
|
||||
the exec operation. */
|
||||
|
||||
void
|
||||
async_enable_stdin (void)
|
||||
{
|
||||
if (sync_execution)
|
||||
{
|
||||
/* See NOTE in async_disable_stdin() */
|
||||
/* See NOTE in async_disable_stdin(). */
|
||||
/* FIXME: cagney/1999-09-27: Call this before clearing
|
||||
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 ();
|
||||
pop_prompt ();
|
||||
sync_execution = 0;
|
||||
|
@ -453,7 +454,7 @@ async_enable_stdin (void)
|
|||
}
|
||||
|
||||
/* Disable reads from stdin (the console) marking the command as
|
||||
synchronous. */
|
||||
synchronous. */
|
||||
|
||||
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
|
||||
into COMMAND. */
|
||||
into COMMAND. */
|
||||
/* NOTE: 1999-04-30 This is the asynchronous version of the command_loop
|
||||
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
|
||||
command_handler (char *command)
|
||||
{
|
||||
|
@ -482,11 +483,11 @@ command_handler (char *command)
|
|||
if (instream == stdin && stdin_is_tty)
|
||||
reinitialize_more_filter ();
|
||||
|
||||
/* If readline returned a NULL command, it means that the
|
||||
connection with the terminal is gone. This happens at the
|
||||
end of a testsuite run, after Expect has hung up
|
||||
but GDB is still alive. In such a case, we just quit gdb
|
||||
killing the inferior program too. */
|
||||
/* If readline returned a NULL command, it means that the connection
|
||||
with the terminal is gone. This happens at the end of a
|
||||
testsuite run, after Expect has hung up but GDB is still alive.
|
||||
In such a case, we just quit gdb killing the inferior program
|
||||
too. */
|
||||
if (command == 0)
|
||||
{
|
||||
printf_unfiltered ("quit\n");
|
||||
|
@ -503,14 +504,15 @@ command_handler (char *command)
|
|||
do_cleanups (stat_chain);
|
||||
}
|
||||
|
||||
/* Handle a complete line of input. This is called by the callback
|
||||
mechanism within the readline library. Deal with incomplete commands
|
||||
as well, by saving the partial input in a global buffer. */
|
||||
/* Handle a complete line of input. This is called by the callback
|
||||
mechanism within the readline library. Deal with incomplete
|
||||
commands as well, by saving the partial input in a global
|
||||
buffer. */
|
||||
|
||||
/* 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
|
||||
GDB. */
|
||||
GDB. */
|
||||
static void
|
||||
command_line_handler (char *rl)
|
||||
{
|
||||
|
@ -555,7 +557,8 @@ command_line_handler (char *rl)
|
|||
#endif
|
||||
|
||||
/* 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 ("");
|
||||
gdb_flush (gdb_stdout);
|
||||
gdb_flush (gdb_stderr);
|
||||
|
@ -564,12 +567,12 @@ command_line_handler (char *rl)
|
|||
++source_line_number;
|
||||
|
||||
/* 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)
|
||||
{
|
||||
got_eof = 1;
|
||||
command_handler (0);
|
||||
return; /* Lint. */
|
||||
return; /* Lint. */
|
||||
}
|
||||
if (strlen (rl) + 1 + (p - linebuffer) > linelength)
|
||||
{
|
||||
|
@ -580,7 +583,7 @@ command_line_handler (char *rl)
|
|||
}
|
||||
p1 = rl;
|
||||
/* 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)
|
||||
*p++ = *p1++;
|
||||
|
||||
|
@ -595,8 +598,8 @@ command_line_handler (char *rl)
|
|||
readline_input_state.linebuffer_ptr = p;
|
||||
|
||||
/* We will not invoke a execute_command if there is more
|
||||
input expected to complete the command. So, we need to
|
||||
print an empty prompt here. */
|
||||
input expected to complete the command. So, we need to
|
||||
print an empty prompt here. */
|
||||
more_to_come = 1;
|
||||
push_prompt ("", "", "");
|
||||
display_gdb_prompt (0);
|
||||
|
@ -654,9 +657,8 @@ command_line_handler (char *rl)
|
|||
xfree (history_value);
|
||||
}
|
||||
|
||||
/* If we just got an empty line, and that is supposed
|
||||
to repeat the previous command, return the value in the
|
||||
global buffer. */
|
||||
/* If we just got an empty line, and that is supposed to repeat the
|
||||
previous command, return the value in the global buffer. */
|
||||
if (repeat && p == linebuffer && *p != '\\')
|
||||
{
|
||||
command_handler (line);
|
||||
|
@ -686,7 +688,7 @@ command_line_handler (char *rl)
|
|||
and remove the '#'. The kill ring is probably better, but some
|
||||
people are in the habit of commenting things out. */
|
||||
if (*p1 == '#')
|
||||
*p1 = '\0'; /* Found a comment. */
|
||||
*p1 = '\0'; /* Found a comment. */
|
||||
|
||||
/* Save into global buffer if appropriate. */
|
||||
if (repeat)
|
||||
|
@ -711,11 +713,11 @@ command_line_handler (char *rl)
|
|||
}
|
||||
|
||||
/* 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
|
||||
execution for gdb. */
|
||||
execution for gdb. */
|
||||
void
|
||||
gdb_readline2 (gdb_client_data client_data)
|
||||
{
|
||||
|
@ -726,11 +728,11 @@ gdb_readline2 (gdb_client_data client_data)
|
|||
static int done_once = 0;
|
||||
|
||||
/* 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
|
||||
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
|
||||
afterwards will not trigger. */
|
||||
afterwards will not trigger. */
|
||||
if (!done_once && !ISATTY (instream))
|
||||
{
|
||||
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
|
||||
obvious to invoke gdb_readline2 at every character entered. If
|
||||
not using the readline library, the terminal is in cooked mode,
|
||||
which sends the characters all at once. Poll will notice that the
|
||||
input fd has changed state only after enter is pressed. At this
|
||||
point we still need to fetch all the chars entered. */
|
||||
which sends the characters all at once. Poll will notice that the
|
||||
input fd has changed state only after enter is pressed. At this
|
||||
point we still need to fetch all the chars entered. */
|
||||
|
||||
while (1)
|
||||
{
|
||||
|
@ -755,9 +757,9 @@ gdb_readline2 (gdb_client_data client_data)
|
|||
if (c == EOF)
|
||||
{
|
||||
if (input_index > 0)
|
||||
/* The last line does not end with a newline. Return it, and
|
||||
if we are called again fgetc will still return EOF and
|
||||
we'll return NULL then. */
|
||||
/* The last line does not end with a newline. Return it,
|
||||
and if we are called again fgetc will still return EOF
|
||||
and we'll return NULL then. */
|
||||
break;
|
||||
xfree (result);
|
||||
(*input_handler) (0);
|
||||
|
@ -785,17 +787,17 @@ gdb_readline2 (gdb_client_data client_data)
|
|||
|
||||
|
||||
/* 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
|
||||
functions are the actual signal handlers associated to the signals
|
||||
via calls to signal(). The only job for these functions is to
|
||||
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
|
||||
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.
|
||||
init_signals will become obsolete as we move to have to event loop
|
||||
as the default for gdb. */
|
||||
as the default for gdb. */
|
||||
void
|
||||
async_init_signals (void)
|
||||
{
|
||||
|
@ -853,8 +855,8 @@ mark_async_signal_handler_wrapper (void *token)
|
|||
mark_async_signal_handler ((struct async_signal_handler *) token);
|
||||
}
|
||||
|
||||
/* Tell the event loop what to do if SIGINT is received.
|
||||
See event-signal.c. */
|
||||
/* Tell the event loop what to do if SIGINT is received.
|
||||
See event-signal.c. */
|
||||
void
|
||||
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
|
||||
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. */
|
||||
|
||||
quit_flag = 1;
|
||||
|
||||
/* 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
|
||||
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
|
||||
that point, though, the command that we want to interrupt needs to
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -887,7 +889,7 @@ handle_sigterm (int sig)
|
|||
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
|
||||
async_request_quit (gdb_client_data arg)
|
||||
{
|
||||
|
@ -895,15 +897,15 @@ async_request_quit (gdb_client_data arg)
|
|||
back here, that means that an exception was thrown to unwind the
|
||||
current command before we got back to the event loop. So there
|
||||
is no reason to call quit again here, unless immediate_quit is
|
||||
set.*/
|
||||
set. */
|
||||
|
||||
if (quit_flag || immediate_quit)
|
||||
quit ();
|
||||
}
|
||||
|
||||
#ifdef SIGQUIT
|
||||
/* Tell the event loop what to do if SIGQUIT is received.
|
||||
See event-signal.c. */
|
||||
/* Tell the event loop what to do if SIGQUIT is received.
|
||||
See event-signal.c. */
|
||||
static void
|
||||
handle_sigquit (int sig)
|
||||
{
|
||||
|
@ -918,13 +920,13 @@ handle_sigquit (int sig)
|
|||
static void
|
||||
async_do_nothing (gdb_client_data arg)
|
||||
{
|
||||
/* Empty function body. */
|
||||
/* Empty function body. */
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SIGHUP
|
||||
/* Tell the event loop what to do if SIGHUP is received.
|
||||
See event-signal.c. */
|
||||
/* Tell the event loop what to do if SIGHUP is received.
|
||||
See event-signal.c. */
|
||||
static void
|
||||
handle_sighup (int sig)
|
||||
{
|
||||
|
@ -932,14 +934,14 @@ handle_sighup (int sig)
|
|||
signal (sig, handle_sighup);
|
||||
}
|
||||
|
||||
/* Called by the event loop to process a SIGHUP */
|
||||
/* Called by the event loop to process a SIGHUP. */
|
||||
static void
|
||||
async_disconnect (gdb_client_data arg)
|
||||
{
|
||||
catch_errors (quit_cover, NULL,
|
||||
"Could not kill the program being debugged",
|
||||
RETURN_MASK_ALL);
|
||||
signal (SIGHUP, SIG_DFL); /*FIXME: ??????????? */
|
||||
signal (SIGHUP, SIG_DFL); /*FIXME: ??????????? */
|
||||
raise (SIGHUP);
|
||||
}
|
||||
#endif
|
||||
|
@ -977,13 +979,14 @@ async_stop_sig (gdb_client_data arg)
|
|||
printf_unfiltered ("%s", prompt);
|
||||
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 ();
|
||||
}
|
||||
#endif /* STOP_SIGNAL */
|
||||
|
||||
/* Tell the event loop what to do if SIGFPE is received.
|
||||
See event-signal.c. */
|
||||
/* Tell the event loop what to do if SIGFPE is received.
|
||||
See event-signal.c. */
|
||||
static void
|
||||
handle_sigfpe (int sig)
|
||||
{
|
||||
|
@ -991,17 +994,17 @@ handle_sigfpe (int sig)
|
|||
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
|
||||
async_float_handler (gdb_client_data arg)
|
||||
{
|
||||
/* This message is based on ANSI C, section 4.7. Note that integer
|
||||
divide by zero causes this, so "float" is a misnomer. */
|
||||
/* This message is based on ANSI C, section 4.7. Note that integer
|
||||
divide by zero causes this, so "float" is a misnomer. */
|
||||
error (_("Erroneous arithmetic operation."));
|
||||
}
|
||||
|
||||
/* Tell the event loop what to do if SIGWINCH is received.
|
||||
See event-signal.c. */
|
||||
/* Tell the event loop what to do if SIGWINCH is received.
|
||||
See event-signal.c. */
|
||||
#if defined(SIGWINCH) && defined(SIGWINCH_HANDLER)
|
||||
static void
|
||||
handle_sigwinch (int sig)
|
||||
|
@ -1014,14 +1017,16 @@ handle_sigwinch (int sig)
|
|||
|
||||
/* Called by do_setshow_command. */
|
||||
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 ();
|
||||
}
|
||||
|
||||
/* Called by do_setshow_command. */
|
||||
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 ();
|
||||
}
|
||||
|
@ -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
|
||||
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
|
||||
gdb_setup_readline (void)
|
||||
{
|
||||
|
@ -1054,7 +1059,7 @@ gdb_setup_readline (void)
|
|||
editing. */
|
||||
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
|
||||
editing on' or 'off'. */
|
||||
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
|
||||
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. */
|
||||
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;
|
||||
|
||||
/* 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
|
||||
descriptor. */
|
||||
/* 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
|
||||
it actually exists (I.e. after we say 'run' or after we connect
|
||||
to a remote target. */
|
||||
|
|
|
@ -20,16 +20,21 @@
|
|||
#include "main.h"
|
||||
#include "gdb_string.h"
|
||||
#include "interps.h"
|
||||
#include <mcheck.h>
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
struct captured_main_args args;
|
||||
int ret;
|
||||
|
||||
mtrace ();
|
||||
memset (&args, 0, sizeof args);
|
||||
args.argc = argc;
|
||||
args.argv = argv;
|
||||
args.use_windows = 0;
|
||||
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. */
|
||||
/* NOTE: Since ``defs.h:catch_errors()'' does not return an error /
|
||||
internal / quit indication it is not possible to return that
|
||||
here. */
|
||||
here. */
|
||||
GDB_RC_FAIL = 0,
|
||||
/* No error occured but nothing happened. Due to the catch_errors()
|
||||
interface, this must be non-zero. */
|
||||
/* No error occured but nothing happened. Due to the catch_errors()
|
||||
interface, this must be non-zero. */
|
||||
GDB_RC_NONE = 1,
|
||||
/* The operation was successful. Due to the catch_errors()
|
||||
interface, this must be non-zero. */
|
||||
/* The operation was successful. Due to the catch_errors()
|
||||
interface, this must be non-zero. */
|
||||
GDB_RC_OK = 2
|
||||
};
|
||||
|
||||
|
||||
/* Print the specified breakpoint on GDB_STDOUT. (Eventually this
|
||||
function will ``print'' the object on ``output''). */
|
||||
/* Print the specified breakpoint on GDB_STDOUT. (Eventually this
|
||||
function will ``print'' the object on ``output''). */
|
||||
enum gdb_rc gdb_breakpoint_query (struct ui_out *uiout, int bnum,
|
||||
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,
|
||||
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,
|
||||
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
|
||||
variable, so it should always be malloc'ed - since
|
||||
do_setshow_command will free it. */
|
||||
do_setshow_command will free it. */
|
||||
char *interpreter_p;
|
||||
|
||||
/* Whether xdb commands will be handled */
|
||||
/* Whether xdb commands will be handled. */
|
||||
int xdb_commands = 0;
|
||||
|
||||
/* Whether dbx commands will be handled */
|
||||
/* Whether dbx commands will be handled. */
|
||||
int dbx_commands = 0;
|
||||
|
||||
/* 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_stdlog;
|
||||
struct ui_file *gdb_stdin;
|
||||
/* target IO streams */
|
||||
/* Target IO streams. */
|
||||
struct ui_file *gdb_stdtargin;
|
||||
struct ui_file *gdb_stdtarg;
|
||||
struct ui_file *gdb_stdtargerr;
|
||||
|
@ -86,7 +86,7 @@ int batch_silent = 0;
|
|||
int return_child_result = 0;
|
||||
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;
|
||||
|
||||
/* 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 *);
|
||||
|
||||
/* These two are used to set the external editor commands when gdb is farming
|
||||
out files to be edited by another program. */
|
||||
/* These two are used to set the external editor commands when gdb is
|
||||
farming out files to be edited by another program. */
|
||||
|
||||
extern char *external_editor_command;
|
||||
|
||||
|
@ -151,11 +151,11 @@ relocate_directory (const char *progname, const char *initial, int flag)
|
|||
return dir;
|
||||
}
|
||||
|
||||
/* Compute the locations of init files that GDB should source and return
|
||||
them in SYSTEM_GDBINIT, HOME_GDBINIT, LOCAL_GDBINIT. If there is
|
||||
no system gdbinit (resp. home gdbinit and local gdbinit) to be loaded,
|
||||
then SYSTEM_GDBINIT (resp. HOME_GDBINIT and LOCAL_GDBINIT) is set to
|
||||
NULL. */
|
||||
/* Compute the locations of init files that GDB should source and
|
||||
return them in SYSTEM_GDBINIT, HOME_GDBINIT, LOCAL_GDBINIT. If
|
||||
there is no system gdbinit (resp. home gdbinit and local gdbinit)
|
||||
to be loaded, then SYSTEM_GDBINIT (resp. HOME_GDBINIT and
|
||||
LOCAL_GDBINIT) is set to NULL. */
|
||||
static void
|
||||
get_init_files (char **system_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
|
||||
non-zero return status. */
|
||||
non-zero return status. */
|
||||
|
||||
static int
|
||||
captured_command_loop (void *data)
|
||||
|
@ -232,12 +232,12 @@ captured_command_loop (void *data)
|
|||
the do_cleanups() below is redundant. Unfortunately, many FUNCs
|
||||
are not that well behaved. do_cleanups should either be replaced
|
||||
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);
|
||||
/* If the command_loop returned, normally (rather than threw an
|
||||
error) we try to quit. If the quit is aborted, catch_errors()
|
||||
which called this catch the signal and restart the command
|
||||
loop. */
|
||||
loop. */
|
||||
quit_command (NULL, instream == stdin);
|
||||
return 1;
|
||||
}
|
||||
|
@ -260,7 +260,8 @@ captured_main (void *data)
|
|||
char *cdarg = 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_version;
|
||||
|
||||
|
@ -317,7 +318,7 @@ captured_main (void *data)
|
|||
|
||||
quit_flag = 0;
|
||||
line = (char *) xmalloc (linesize);
|
||||
line[0] = '\0'; /* Terminate saved (now empty) cmd line */
|
||||
line[0] = '\0'; /* Terminate saved (now empty) cmd line. */
|
||||
instream = stdin;
|
||||
|
||||
gdb_stdout = stdio_fileopen (stdout);
|
||||
|
@ -332,7 +333,7 @@ captured_main (void *data)
|
|||
|
||||
if (! getcwd (gdb_dirbuf, sizeof (gdb_dirbuf)))
|
||||
/* 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,
|
||||
_("%s: warning: error finding working directory: %s\n"),
|
||||
argv[0], safe_strerror (errno));
|
||||
|
@ -400,9 +401,9 @@ captured_main (void *data)
|
|||
{"batch", no_argument, &batch_flag, 1},
|
||||
{"epoch", no_argument, &epoch_interface, 1},
|
||||
|
||||
/* This is a synonym for "--annotate=1". --annotate is now preferred,
|
||||
but keep this here for a long time because people will be running
|
||||
emacses which use --fullname. */
|
||||
/* This is a synonym for "--annotate=1". --annotate is now
|
||||
preferred, but keep this here for a long time because people
|
||||
will be running emacses which use --fullname. */
|
||||
{"fullname", no_argument, 0, 'f'},
|
||||
{"f", no_argument, 0, 'f'},
|
||||
|
||||
|
@ -559,10 +560,12 @@ captured_main (void *data)
|
|||
#ifdef GDBTK
|
||||
case 'z':
|
||||
{
|
||||
extern int gdbtk_test (char *);
|
||||
extern int gdbtk_test (char *);
|
||||
|
||||
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);
|
||||
exit (1);
|
||||
}
|
||||
|
@ -605,7 +608,7 @@ extern int gdbtk_test (char *);
|
|||
if (i == 0 && p == optarg)
|
||||
|
||||
/* 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,
|
||||
|
@ -623,7 +626,7 @@ extern int gdbtk_test (char *);
|
|||
if (i == 0 && p == optarg)
|
||||
|
||||
/* 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,
|
||||
|
@ -655,8 +658,8 @@ extern int gdbtk_test (char *);
|
|||
control of the console via the deprecated_init_ui_hook (). */
|
||||
gdb_init (argv[0]);
|
||||
|
||||
/* Now that gdb_init has created the initial inferior, we're in position
|
||||
to set args for that inferior. */
|
||||
/* Now that gdb_init has created the initial inferior, we're in
|
||||
position to set args for that inferior. */
|
||||
if (set_args)
|
||||
{
|
||||
/* 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) ? "" : " ...");
|
||||
}
|
||||
|
||||
/* Lookup gdbinit files. Note that the gdbinit file name may be overriden
|
||||
during file initialization, so get_init_files should be called after
|
||||
gdb_init. */
|
||||
/* Lookup gdbinit files. Note that the gdbinit file name may be
|
||||
overriden during file initialization, so get_init_files should be
|
||||
called after gdb_init. */
|
||||
get_init_files (&system_gdbinit, &home_gdbinit, &local_gdbinit);
|
||||
|
||||
/* 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. */
|
||||
if (!quiet && strcmp (interpreter_p, INTERP_MI1) == 0)
|
||||
{
|
||||
/* Print all the junk at the top, with trailing "..." if we are about
|
||||
to read a symbol file (possibly slowly). */
|
||||
/* Print all the junk at the top, with trailing "..." if we are
|
||||
about to read a symbol file (possibly slowly). */
|
||||
print_gdb_version (gdb_stdout);
|
||||
if (symarg)
|
||||
printf_filtered ("..");
|
||||
wrap_here ("");
|
||||
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
|
||||
look at things by now. Initialize the default interpreter. */
|
||||
look at things by now. Initialize the default interpreter. */
|
||||
|
||||
{
|
||||
/* Find it. */
|
||||
|
@ -773,14 +776,15 @@ Excess command line arguments ignored. (%s%s)\n"),
|
|||
any sane interpreter. */
|
||||
if (!quiet && !current_interp_named_p (INTERP_MI1))
|
||||
{
|
||||
/* Print all the junk at the top, with trailing "..." if we are about
|
||||
to read a symbol file (possibly slowly). */
|
||||
/* Print all the junk at the top, with trailing "..." if we are
|
||||
about to read a symbol file (possibly slowly). */
|
||||
print_gdb_version (gdb_stdout);
|
||||
if (symarg)
|
||||
printf_filtered ("..");
|
||||
wrap_here ("");
|
||||
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. */
|
||||
|
@ -814,7 +818,8 @@ Excess command line arguments ignored. (%s%s)\n"),
|
|||
xfree (dirarg);
|
||||
|
||||
/* 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;
|
||||
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
|
||||
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))
|
||||
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)
|
||||
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;
|
||||
quit_pre_print = NULL;
|
||||
warning_pre_print = _("warning: ");
|
||||
|
@ -896,7 +901,8 @@ Can't attach to process and specify a core file at the same time."));
|
|||
}
|
||||
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 ();
|
||||
|
||||
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
|
||||
moving this loop and the code found in captured_command_loop()
|
||||
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)
|
||||
{
|
||||
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 "python/python.h"
|
||||
|
||||
/* readline include files */
|
||||
/* readline include files. */
|
||||
#include "readline/readline.h"
|
||||
#include "readline/history.h"
|
||||
|
||||
|
@ -65,7 +65,7 @@
|
|||
#include "ui-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
|
||||
#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. */
|
||||
|
||||
int caution = 1; /* Default is yes, sigh. */
|
||||
int caution = 1; /* Default is yes, sigh. */
|
||||
static void
|
||||
show_caution (struct ui_file *file, int from_tty,
|
||||
struct cmd_list_element *c, const char *value)
|
||||
|
@ -107,9 +107,10 @@ Whether to confirm potentially dangerous operations is %s.\n"),
|
|||
value);
|
||||
}
|
||||
|
||||
/* stdio stream that command input is being read from. Set to stdin normally.
|
||||
Set by source_command to the file we are sourcing. Set to NULL if we are
|
||||
executing a user-defined command or interacting via a GUI. */
|
||||
/* stdio stream that command input is being read from. Set to stdin
|
||||
normally. Set by source_command to the file we are sourcing. Set
|
||||
to NULL if we are executing a user-defined command or interacting
|
||||
via a GUI. */
|
||||
|
||||
FILE *instream;
|
||||
|
||||
|
@ -149,12 +150,12 @@ int server_command;
|
|||
|
||||
/* Baud rate specified for talking to serial target systems. Default
|
||||
is left as -1, so targets can choose their own defaults. */
|
||||
/* FIXME: This means that "show remotebaud" and gr_files_info can print -1
|
||||
or (unsigned int)-1. This is a Bad User Interface. */
|
||||
/* FIXME: This means that "show remotebaud" and gr_files_info can
|
||||
print -1 or (unsigned int)-1. This is a Bad User Interface. */
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
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;
|
||||
|
||||
|
@ -187,17 +188,18 @@ char *lim_at_start;
|
|||
|
||||
/* Hooks for alternate command interfaces. */
|
||||
|
||||
/* Called after most modules have been initialized, but before taking users
|
||||
command file.
|
||||
/* Called after most modules have been initialized, but before taking
|
||||
users command file.
|
||||
|
||||
If the UI fails to initialize and it wants GDB to continue
|
||||
using the default UI, then it should clear this hook before returning. */
|
||||
If the UI fails to initialize and it wants GDB to continue using
|
||||
the default UI, then it should clear this hook before returning. */
|
||||
|
||||
void (*deprecated_init_ui_hook) (char *argv0);
|
||||
|
||||
/* This hook is called from within gdb's many mini-event loops which could
|
||||
steal control from a real user interface's event loop. It returns
|
||||
non-zero if the user is requesting a detach, zero otherwise. */
|
||||
/* This hook is called from within gdb's many mini-event loops which
|
||||
could steal control from a real user interface's event loop. It
|
||||
returns non-zero if the user is requesting a detach, zero
|
||||
otherwise. */
|
||||
|
||||
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. */
|
||||
|
||||
void (*deprecated_print_frame_info_listing_hook) (struct symtab * s, int line,
|
||||
int stopline, int noerror);
|
||||
void (*deprecated_print_frame_info_listing_hook) (struct symtab * s,
|
||||
int line,
|
||||
int stopline,
|
||||
int noerror);
|
||||
/* Replaces most of query. */
|
||||
|
||||
int (*deprecated_query_hook) (const char *, va_list);
|
||||
|
@ -236,33 +240,33 @@ char *(*deprecated_readline_hook) (char *);
|
|||
void (*deprecated_readline_end_hook) (void);
|
||||
|
||||
/* 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_detach_hook) (void);
|
||||
|
||||
/* Called during long calculations to allow GUI to repair window damage, and to
|
||||
check for stop buttons, etc... */
|
||||
/* Called during long calculations to allow GUI to repair window
|
||||
damage, and to check for stop buttons, etc... */
|
||||
|
||||
void (*deprecated_interactive_hook) (void);
|
||||
|
||||
/* Tell the GUI someone changed the register REGNO. -1 means
|
||||
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);
|
||||
|
||||
/* Called when going to wait for the target. Usually allows the GUI to run
|
||||
while waiting for target events. */
|
||||
/* Called when going to wait for the target. Usually allows the GUI
|
||||
to run while waiting for target events. */
|
||||
|
||||
ptid_t (*deprecated_target_wait_hook) (ptid_t ptid,
|
||||
struct target_waitstatus *status,
|
||||
int options);
|
||||
|
||||
/* Used by UI as a wrapper around command execution. May do various things
|
||||
like enabling/disabling buttons, etc... */
|
||||
/* Used by UI as a wrapper around command execution. May do various
|
||||
things like enabling/disabling buttons, etc... */
|
||||
|
||||
void (*deprecated_call_command_hook) (struct cmd_list_element * c, char *cmd,
|
||||
int from_tty);
|
||||
void (*deprecated_call_command_hook) (struct cmd_list_element * c,
|
||||
char *cmd, int from_tty);
|
||||
|
||||
/* Called after a `set' command has finished. Is only run if the
|
||||
`set' command succeeded. */
|
||||
|
@ -283,7 +287,8 @@ void (*deprecated_context_hook) (int id);
|
|||
quit_cover (void *s)
|
||||
{
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
|
@ -339,10 +344,10 @@ prepare_execute_command (void)
|
|||
{
|
||||
free_all_values ();
|
||||
|
||||
/* With multiple threads running while the one we're examining is stopped,
|
||||
the dcache can get stale without us being able to detect it.
|
||||
For the duration of the command, though, use the dcache to help
|
||||
things like backtrace. */
|
||||
/* With multiple threads running while the one we're examining is
|
||||
stopped, the dcache can get stale without us being able to detect
|
||||
it. For the duration of the command, though, use the dcache to
|
||||
help things like backtrace. */
|
||||
if (non_stop)
|
||||
target_dcache_invalidate ();
|
||||
}
|
||||
|
@ -405,7 +410,7 @@ execute_command (char *p, int from_tty)
|
|||
*(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);
|
||||
|
||||
if (c->flags & DEPRECATED_WARN_USER)
|
||||
|
@ -422,7 +427,7 @@ execute_command (char *p, int from_tty)
|
|||
else
|
||||
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);
|
||||
|
||||
}
|
||||
|
@ -442,7 +447,7 @@ execute_command (char *p, int from_tty)
|
|||
|
||||
/* Warn the user if the working language does not match the
|
||||
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
|
||||
the frame changes. */
|
||||
|
||||
|
@ -523,7 +528,7 @@ command_loop (void)
|
|||
reinitialize_more_filter ();
|
||||
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 ?
|
||||
get_prompt () : (char *) NULL,
|
||||
instream == stdin, "prompt");
|
||||
|
@ -550,8 +555,8 @@ dont_repeat (void)
|
|||
return;
|
||||
|
||||
/* 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
|
||||
won't repeat here in any case. */
|
||||
thing read from stdin in line and don't want to delete it. Null
|
||||
lines won't repeat here in any case. */
|
||||
if (instream == stdin)
|
||||
*line = 0;
|
||||
}
|
||||
|
@ -880,8 +885,9 @@ command_line_input (char *prompt_arg, int repeat, char *annotation_suffix)
|
|||
|
||||
while (1)
|
||||
{
|
||||
/* 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. */
|
||||
/* 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. */
|
||||
wrap_here ("");
|
||||
gdb_flush (gdb_stdout);
|
||||
gdb_flush (gdb_stderr);
|
||||
|
@ -931,7 +937,7 @@ command_line_input (char *prompt_arg, int repeat, char *annotation_suffix)
|
|||
}
|
||||
p1 = rl;
|
||||
/* 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)
|
||||
*p++ = *p1++;
|
||||
|
||||
|
@ -997,9 +1003,8 @@ command_line_input (char *prompt_arg, int repeat, char *annotation_suffix)
|
|||
xfree (history_value);
|
||||
}
|
||||
|
||||
/* If we just got an empty line, and that is supposed
|
||||
to repeat the previous command, return the value in the
|
||||
global buffer. */
|
||||
/* If we just got an empty line, and that is supposed to repeat the
|
||||
previous command, return the value in the global buffer. */
|
||||
if (repeat && p == linebuffer)
|
||||
return line;
|
||||
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
|
||||
people are in the habit of commenting things out. */
|
||||
if (*p1 == '#')
|
||||
*p1 = '\0'; /* Found a comment. */
|
||||
*p1 = '\0'; /* Found a comment. */
|
||||
|
||||
/* Save into global buffer if appropriate. */
|
||||
if (repeat)
|
||||
|
@ -1037,24 +1042,24 @@ command_line_input (char *prompt_arg, int repeat, char *annotation_suffix)
|
|||
return linebuffer;
|
||||
}
|
||||
|
||||
/* Print the GDB banner. */
|
||||
/* Print the GDB banner. */
|
||||
void
|
||||
print_gdb_version (struct ui_file *stream)
|
||||
{
|
||||
/* From GNU coding standards, first line is meant to be easy for a
|
||||
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);
|
||||
|
||||
/* Second line is a copyright notice. */
|
||||
/* Second line is a copyright notice. */
|
||||
|
||||
fprintf_filtered (stream, "Copyright (C) 2010 Free Software Foundation, Inc.\n");
|
||||
|
||||
/* Following the copyright is a brief statement that the program is
|
||||
free software, that users are free to copy and change it on
|
||||
certain conditions, that it is covered by the GNU GPL, and that
|
||||
there is no warranty. */
|
||||
there is no warranty. */
|
||||
|
||||
fprintf_filtered (stream, "\
|
||||
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\
|
||||
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 \"");
|
||||
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
|
||||
assignments to prompt are wrapped in calls to xstrdup...
|
||||
if (prompt != NULL)
|
||||
xfree (prompt);
|
||||
xfree (prompt);
|
||||
*/
|
||||
PROMPT (0) = xstrdup (s);
|
||||
}
|
||||
|
@ -1221,8 +1226,8 @@ quit_target (void *arg)
|
|||
if (write_history_p && 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;
|
||||
}
|
||||
|
||||
|
@ -1235,7 +1240,7 @@ quit_force (char *args, int from_tty)
|
|||
struct qt_args qt;
|
||||
|
||||
/* An optional expression may be used to cause gdb to terminate with the
|
||||
value of that expression. */
|
||||
value of that expression. */
|
||||
if (args)
|
||||
{
|
||||
struct value *val = parse_and_eval (args);
|
||||
|
@ -1305,8 +1310,8 @@ input_from_terminal_p (void)
|
|||
static void
|
||||
dont_repeat_command (char *ignored, int from_tty)
|
||||
{
|
||||
*line = 0; /* Can't call dont_repeat here because we're not
|
||||
necessarily reading from stdin. */
|
||||
*line = 0; /* Can't call dont_repeat here because we're
|
||||
not necessarily reading from stdin. */
|
||||
}
|
||||
|
||||
/* 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, "");
|
||||
}
|
||||
|
||||
int info_verbose = 0; /* Default verbose msgs off */
|
||||
int info_verbose = 0; /* Default verbose msgs off. */
|
||||
|
||||
/* Called by do_setshow_command. An elaborate joke. */
|
||||
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)
|
||||
* have been read so that the user can change the history file via his
|
||||
* .gdbinit file (for instance). The GDBHISTFILE environment variable
|
||||
* overrides all of this.
|
||||
*/
|
||||
have been read so that the user can change the history file via his
|
||||
.gdbinit file (for instance). The GDBHISTFILE environment variable
|
||||
overrides all of this. */
|
||||
|
||||
void
|
||||
init_history (void)
|
||||
|
@ -1647,7 +1651,7 @@ gdb_init (char *argv0)
|
|||
if (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__
|
||||
/* 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));
|
||||
#endif
|
||||
|
||||
init_cmd_lists (); /* This needs to be done first */
|
||||
initialize_targets (); /* Setup target_terminal macros for utils.c */
|
||||
initialize_utils (); /* Make errors and warnings possible */
|
||||
init_cmd_lists (); /* This needs to be done first. */
|
||||
initialize_targets (); /* Setup target_terminal macros for utils.c. */
|
||||
initialize_utils (); /* Make errors and warnings possible. */
|
||||
|
||||
/* Here is where we call all the _initialize_foo routines. */
|
||||
initialize_all_files ();
|
||||
|
@ -1671,17 +1675,18 @@ gdb_init (char *argv0)
|
|||
initialize_inferiors ();
|
||||
initialize_current_architecture ();
|
||||
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 ();
|
||||
|
||||
async_init_signals ();
|
||||
|
||||
/* We need a default language for parsing expressions, so simple things like
|
||||
"set width 0" won't fail if no language is explicitly set in a config file
|
||||
or implicitly set by reading an executable during startup. */
|
||||
/* We need a default language for parsing expressions, so simple
|
||||
things like "set width 0" won't fail if no language is explicitly
|
||||
set in a config file or implicitly set by reading an executable
|
||||
during startup. */
|
||||
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,
|
||||
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);
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
/* Python initialization can require various commands to be installed.
|
||||
For example "info pretty-printer" needs the "info" prefix to be
|
||||
installed. Keep things simple and just do final python initialization
|
||||
here. */
|
||||
/* Python initialization can require various commands to be
|
||||
installed. For example "info pretty-printer" needs the "info"
|
||||
prefix to be installed. Keep things simple and just do final
|
||||
python initialization here. */
|
||||
finish_python_initialization ();
|
||||
#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);
|
||||
|
||||
/* 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);
|
||||
|
||||
/* 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 *);
|
||||
|
||||
/* From random places. */
|
||||
extern int readnow_symbol_files;
|
||||
|
||||
/* Perform _initialize initialization */
|
||||
/* Perform _initialize initialization. */
|
||||
extern void gdb_init (char *);
|
||||
|
||||
/* For use by event-top.c */
|
||||
/* Variables from top.c. */
|
||||
/* For use by event-top.c. */
|
||||
/* Variables from top.c. */
|
||||
extern int source_line_number;
|
||||
extern const char *source_file_name;
|
||||
extern int history_expansion_p;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue