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:
Michael Snyder 2010-12-29 00:58:14 +00:00
parent 551ce43ca7
commit 371d5dec8e
9 changed files with 500 additions and 454 deletions

View file

@ -1,3 +1,14 @@
2010-12-28 Michael Snyder <msnyder@vmware.com>
* event-loop.c: Comment clean-up.
* event-loop.h: Ditto.
* event-top.c: Ditto.
* gdb.c: Ditto.
* gdb.h: Ditto.
* main.c: Ditto.
* top.c: Ditto.
* top.h: Ditto.
2010-12-28 Pedro Alves <pedro@codesourcery.com> 2010-12-28 Pedro Alves <pedro@codesourcery.com>
* ax-gdb.c (gen_expr) <OP_REGISTER>: Error out if trying to * ax-gdb.c (gen_expr) <OP_REGISTER>: Error out if trying to

View file

@ -99,19 +99,22 @@ file_handler;
/* PROC is a function to be invoked when the READY flag is set. This /* PROC is a function to be invoked when the READY flag is set. This
happens when there has been a signal and the corresponding signal happens when there has been a signal and the corresponding signal
handler has 'triggered' this async_signal_handler for handler has 'triggered' this async_signal_handler for execution.
execution. The actual work to be done in response to a signal will The actual work to be done in response to a signal will be carried
be carried out by PROC at a later time, within process_event. This out by PROC at a later time, within process_event. This provides a
provides a deferred execution of signal handlers. deferred execution of signal handlers.
Async_init_signals takes care of setting up such an Async_init_signals takes care of setting up such an
async_signal_handler for each interesting signal. */ async_signal_handler for each interesting signal. */
typedef struct async_signal_handler typedef struct async_signal_handler
{ {
int ready; /* If ready, call this handler from the main event loop, int ready; /* If ready, call this handler
using invoke_async_handler. */ from the main event loop, using
struct async_signal_handler *next_handler; /* Ptr to next handler */ invoke_async_handler. */
sig_handler_func *proc; /* Function to call to do the work */ struct async_signal_handler *next_handler; /* Ptr to next handler. */
gdb_client_data client_data; /* Argument to async_handler_func */ sig_handler_func *proc; /* Function to call to do the work. */
gdb_client_data client_data; /* Argument to async_handler_func. */
} }
async_signal_handler; async_signal_handler;
@ -154,8 +157,8 @@ async_event_handler;
static struct static struct
{ {
gdb_event *first_event; /* First pending event */ gdb_event *first_event; /* First pending event. */
gdb_event *last_event; /* Last pending event */ gdb_event *last_event; /* Last pending event. */
} }
event_queue; event_queue;
@ -204,8 +207,8 @@ static struct
/* What file descriptors were found ready by select. */ /* What file descriptors were found ready by select. */
fd_set ready_masks[3]; fd_set ready_masks[3];
/* Number of file descriptors to monitor. (for poll) */ /* Number of file descriptors to monitor (for poll). */
/* Number of valid bits (highest fd value + 1). (for select) */ /* Number of valid bits (highest fd value + 1) (for select). */
int num_fds; int num_fds;
/* Time structure for calls to select(). */ /* Time structure for calls to select(). */
@ -223,8 +226,8 @@ struct gdb_timer
struct timeval when; struct timeval when;
int timer_id; int timer_id;
struct gdb_timer *next; struct gdb_timer *next;
timer_handler_func *proc; /* Function to call to do the work */ timer_handler_func *proc; /* Function to call to do the work. */
gdb_client_data client_data; /* Argument to async_handler_func */ gdb_client_data client_data; /* Argument to async_handler_func. */
}; };
/* List of currently active timers. It is sorted in order of /* List of currently active timers. It is sorted in order of
@ -400,7 +403,7 @@ process_event (void)
return 1; return 1;
} }
/* this is the case if there are no event on the event queue. */ /* This is the case if there are no event on the event queue. */
return 0; return 0;
} }
@ -559,21 +562,27 @@ add_file_handler (int fd, handler_func * proc, gdb_client_data client_data)
#endif #endif
} }
else else
create_file_handler (fd, GDB_READABLE | GDB_EXCEPTION, proc, client_data); create_file_handler (fd, GDB_READABLE | GDB_EXCEPTION,
proc, client_data);
} }
/* Add a file handler/descriptor to the list of descriptors we are /* Add a file handler/descriptor to the list of descriptors we are
interested in. interested in.
FD is the file descriptor for the file/stream to be listened to. FD is the file descriptor for the file/stream to be listened to.
For the poll case, MASK is a combination (OR) of
POLLIN, POLLRDNORM, POLLRDBAND, POLLPRI, POLLOUT, POLLWRNORM, For the poll case, MASK is a combination (OR) of POLLIN,
POLLWRBAND: these are the events we are interested in. If any of them POLLRDNORM, POLLRDBAND, POLLPRI, POLLOUT, POLLWRNORM, POLLWRBAND:
occurs, proc should be called. these are the events we are interested in. If any of them occurs,
For the select case, MASK is a combination of READABLE, WRITABLE, EXCEPTION. proc should be called.
PROC is the procedure that will be called when an event occurs for
FD. CLIENT_DATA is the argument to pass to PROC. */ For the select case, MASK is a combination of READABLE, WRITABLE,
EXCEPTION. PROC is the procedure that will be called when an event
occurs for FD. CLIENT_DATA is the argument to pass to PROC. */
static void static void
create_file_handler (int fd, int mask, handler_func * proc, gdb_client_data client_data) create_file_handler (int fd, int mask, handler_func * proc,
gdb_client_data client_data)
{ {
file_handler *file_ptr; file_handler *file_ptr;
@ -670,11 +679,11 @@ delete_file_handler (int fd)
if (use_poll) if (use_poll)
{ {
#ifdef HAVE_POLL #ifdef HAVE_POLL
/* Create a new poll_fds array by copying every fd's information but the /* Create a new poll_fds array by copying every fd's information
one we want to get rid of. */ but the one we want to get rid of. */
new_poll_fds = new_poll_fds = (struct pollfd *)
(struct pollfd *) xmalloc ((gdb_notifier.num_fds - 1) * sizeof (struct pollfd)); xmalloc ((gdb_notifier.num_fds - 1) * sizeof (struct pollfd));
for (i = 0, j = 0; i < gdb_notifier.num_fds; i++) for (i = 0, j = 0; i < gdb_notifier.num_fds; i++)
{ {
@ -761,11 +770,11 @@ handle_file_event (event_data data)
if (file_ptr->fd == event_file_desc) if (file_ptr->fd == event_file_desc)
{ {
/* With poll, the ready_mask could have any of three events /* With poll, the ready_mask could have any of three events
set to 1: POLLHUP, POLLERR, POLLNVAL. These events cannot set to 1: POLLHUP, POLLERR, POLLNVAL. These events
be used in the requested event mask (events), but they cannot be used in the requested event mask (events), but
can be returned in the return mask (revents). We need to they can be returned in the return mask (revents). We
check for those event too, and add them to the mask which need to check for those event too, and add them to the
will be passed to the handler. */ mask which will be passed to the handler. */
/* See if the desired events (mask) match the received /* See if the desired events (mask) match the received
events (ready_mask). */ events (ready_mask). */
@ -780,8 +789,8 @@ handle_file_event (event_data data)
if (error_mask_returned != 0) if (error_mask_returned != 0)
{ {
/* Work in progress. We may need to tell somebody what /* Work in progress. We may need to tell somebody
kind of error we had. */ what kind of error we had. */
if (error_mask_returned & POLLHUP) if (error_mask_returned & POLLHUP)
printf_unfiltered (_("Hangup detected on fd %d\n"), file_ptr->fd); printf_unfiltered (_("Hangup detected on fd %d\n"), file_ptr->fd);
if (error_mask_returned & POLLERR) if (error_mask_returned & POLLERR)
@ -823,7 +832,7 @@ handle_file_event (event_data data)
/* Called by gdb_do_one_event to wait for new events on the monitored /* Called by gdb_do_one_event to wait for new events on the monitored
file descriptors. Queue file events as they are detected by the file descriptors. Queue file events as they are detected by the
poll. If BLOCK and if there are no events, this function will poll. If BLOCK and if there are no events, this function will
block in the call to poll. Return -1 if there are no files block in the call to poll. Return -1 if there are no file
descriptors to monitor, otherwise return 0. */ descriptors to monitor, otherwise return 0. */
static int static int
gdb_wait_for_event (int block) gdb_wait_for_event (int block)
@ -1005,10 +1014,10 @@ call_async_signal_handler (struct async_signal_handler *handler)
(*handler->proc) (handler->client_data); (*handler->proc) (handler->client_data);
} }
/* Mark the handler (ASYNC_HANDLER_PTR) as ready. This information will /* Mark the handler (ASYNC_HANDLER_PTR) as ready. This information
be used when the handlers are invoked, after we have waited for will be used when the handlers are invoked, after we have waited
some event. The caller of this function is the interrupt handler for some event. The caller of this function is the interrupt
associated with a signal. */ handler associated with a signal. */
void void
mark_async_signal_handler (async_signal_handler * async_handler_ptr) mark_async_signal_handler (async_signal_handler * async_handler_ptr)
{ {
@ -1182,14 +1191,15 @@ delete_async_event_handler (async_event_handler **async_handler_ptr)
aded to the timers queue. This queue is kept sorted in order of aded to the timers queue. This queue is kept sorted in order of
increasing timers. Return a handle to the timer struct. */ increasing timers. Return a handle to the timer struct. */
int int
create_timer (int milliseconds, timer_handler_func * proc, gdb_client_data client_data) create_timer (int milliseconds, timer_handler_func * proc,
gdb_client_data client_data)
{ {
struct gdb_timer *timer_ptr, *timer_index, *prev_timer; struct gdb_timer *timer_ptr, *timer_index, *prev_timer;
struct timeval time_now, delta; struct timeval time_now, delta;
/* compute seconds */ /* Compute seconds. */
delta.tv_sec = milliseconds / 1000; delta.tv_sec = milliseconds / 1000;
/* compute microseconds */ /* Compute microseconds. */
delta.tv_usec = (milliseconds % 1000) * 1000; delta.tv_usec = (milliseconds % 1000) * 1000;
gettimeofday (&time_now, NULL); gettimeofday (&time_now, NULL);
@ -1197,7 +1207,7 @@ create_timer (int milliseconds, timer_handler_func * proc, gdb_client_data clien
timer_ptr = (struct gdb_timer *) xmalloc (sizeof (*timer_ptr)); timer_ptr = (struct gdb_timer *) xmalloc (sizeof (*timer_ptr));
timer_ptr->when.tv_sec = time_now.tv_sec + delta.tv_sec; timer_ptr->when.tv_sec = time_now.tv_sec + delta.tv_sec;
timer_ptr->when.tv_usec = time_now.tv_usec + delta.tv_usec; timer_ptr->when.tv_usec = time_now.tv_usec + delta.tv_usec;
/* carry? */ /* Carry? */
if (timer_ptr->when.tv_usec >= 1000000) if (timer_ptr->when.tv_usec >= 1000000)
{ {
timer_ptr->when.tv_sec += 1; timer_ptr->when.tv_sec += 1;
@ -1314,7 +1324,7 @@ handle_timer_event (event_data dummy)
one timer is ready, stick an event onto the event queue. Even in one timer is ready, stick an event onto the event queue. Even in
case more than one timer is ready, one event is enough, because the case more than one timer is ready, one event is enough, because the
handle_timer_event() will go through the timers list and call the handle_timer_event() will go through the timers list and call the
procedures associated with all that have expired. Update the procedures associated with all that have expired.l Update the
timeout for the select() or poll() as well. */ timeout for the select() or poll() as well. */
static void static void
poll_timers (void) poll_timers (void)
@ -1327,7 +1337,7 @@ poll_timers (void)
gettimeofday (&time_now, NULL); gettimeofday (&time_now, NULL);
delta.tv_sec = timer_list.first_timer->when.tv_sec - time_now.tv_sec; delta.tv_sec = timer_list.first_timer->when.tv_sec - time_now.tv_sec;
delta.tv_usec = timer_list.first_timer->when.tv_usec - time_now.tv_usec; delta.tv_usec = timer_list.first_timer->when.tv_usec - time_now.tv_usec;
/* borrow? */ /* Borrow? */
if (delta.tv_usec < 0) if (delta.tv_usec < 0)
{ {
delta.tv_sec -= 1; delta.tv_sec -= 1;
@ -1353,8 +1363,8 @@ poll_timers (void)
async_queue_event (event_ptr, TAIL); async_queue_event (event_ptr, TAIL);
} }
/* Now we need to update the timeout for select/ poll, because we /* Now we need to update the timeout for select/ poll, because
don't want to sit there while this timer is expiring. */ we don't want to sit there while this timer is expiring. */
if (use_poll) if (use_poll)
{ {
#ifdef HAVE_POLL #ifdef HAVE_POLL

View file

@ -82,8 +82,8 @@ typedef enum
/* Add at tail of queue. It will be processed in first in first /* Add at tail of queue. It will be processed in first in first
out order. */ out order. */
TAIL, TAIL,
/* Add at head of queue. It will be processed in last in first out /* Add at head of queue. It will be processed in last in first
order. */ out order. */
HEAD HEAD
} }
queue_position; queue_position;
@ -93,11 +93,15 @@ queue_position;
extern void start_event_loop (void); extern void start_event_loop (void);
extern int gdb_do_one_event (void *data); extern int gdb_do_one_event (void *data);
extern void delete_file_handler (int fd); extern void delete_file_handler (int fd);
extern void add_file_handler (int fd, handler_func * proc, gdb_client_data client_data); extern void add_file_handler (int fd, handler_func *proc,
gdb_client_data client_data);
extern struct async_signal_handler * extern struct async_signal_handler *
create_async_signal_handler (sig_handler_func * proc, gdb_client_data client_data); create_async_signal_handler (sig_handler_func *proc,
gdb_client_data client_data);
extern void delete_async_signal_handler (struct async_signal_handler **async_handler_ptr); extern void delete_async_signal_handler (struct async_signal_handler **async_handler_ptr);
extern int create_timer (int milliseconds, timer_handler_func * proc, gdb_client_data client_data); extern int create_timer (int milliseconds,
timer_handler_func *proc,
gdb_client_data client_data);
extern void delete_timer (int id); extern void delete_timer (int id);
/* Call the handler from HANDLER immediately. This function /* Call the handler from HANDLER immediately. This function

View file

@ -34,10 +34,9 @@
#include "main.h" #include "main.h"
#include "gdbthread.h" #include "gdbthread.h"
/* For dont_repeat() */ #include "gdbcmd.h" /* for dont_repeat() */
#include "gdbcmd.h"
/* readline include files */ /* readline include files. */
#include "readline/readline.h" #include "readline/readline.h"
#include "readline/history.h" #include "readline/history.h"
@ -129,7 +128,7 @@ int input_fd;
for. See event-loop.h. */ for. See event-loop.h. */
struct prompts the_prompts; struct prompts the_prompts;
/* signal handling variables */ /* Signal handling variables. */
/* Each of these is a pointer to a function that the event loop will /* Each of these is a pointer to a function that the event loop will
invoke if the corresponding signal has received. The real signal invoke if the corresponding signal has received. The real signal
handlers mark these functions as ready to be executed and the event handlers mark these functions as ready to be executed and the event
@ -170,8 +169,8 @@ void (*after_char_processing_hook) ();
/* Wrapper function for calling into the readline library. The event /* Wrapper function for calling into the readline library. The event
loop expects the callback function to have a paramter, while readline loop expects the callback function to have a paramter, while
expects none. */ readline expects none. */
static void static void
rl_callback_read_char_wrapper (gdb_client_data client_data) rl_callback_read_char_wrapper (gdb_client_data client_data)
{ {
@ -193,9 +192,9 @@ cli_command_loop (void)
char *a_prompt; char *a_prompt;
char *gdb_prompt = get_prompt (); char *gdb_prompt = get_prompt ();
/* Tell readline what the prompt to display is and what function it /* Tell readline what the prompt to display is and what function
will need to call after a whole line is read. This also displays it will need to call after a whole line is read. This also
the first prompt. */ displays the first prompt. */
length = strlen (PREFIX (0)) length = strlen (PREFIX (0))
+ strlen (gdb_prompt) + strlen (SUFFIX (0)) + 1; + strlen (gdb_prompt) + strlen (SUFFIX (0)) + 1;
a_prompt = (char *) alloca (length); a_prompt = (char *) alloca (length);
@ -248,7 +247,7 @@ change_line_handler (void)
top of the prompt stack, if the argument NEW_PROMPT is top of the prompt stack, if the argument NEW_PROMPT is
0. Otherwise, it displays whatever NEW_PROMPT is. This is used 0. Otherwise, it displays whatever NEW_PROMPT is. This is used
after each gdb command has completed, and in the following cases: after each gdb command has completed, and in the following cases:
1. when the user enters a command line which is ended by '\' 1. When the user enters a command line which is ended by '\'
indicating that the command will continue on the next line. indicating that the command will continue on the next line.
In that case the prompt that is displayed is the empty string. In that case the prompt that is displayed is the empty string.
2. When the user is entering 'commands' for a breakpoint, or 2. When the user is entering 'commands' for a breakpoint, or
@ -312,7 +311,8 @@ display_gdb_prompt (char *new_prompt)
rl_callback_handler_remove (); rl_callback_handler_remove ();
rl_callback_handler_install (new_prompt, input_handler); rl_callback_handler_install (new_prompt, input_handler);
} }
/* new_prompt at this point can be the top of the stack or the one passed in */ /* new_prompt at this point can be the top of the stack or the one
passed in. */
else if (new_prompt) else if (new_prompt)
{ {
/* Don't use a _filtered function here. It causes the assumed /* Don't use a _filtered function here. It causes the assumed
@ -336,7 +336,7 @@ change_annotation_level (void)
if (!PREFIX (0) || !PROMPT (0) || !SUFFIX (0)) if (!PREFIX (0) || !PROMPT (0) || !SUFFIX (0))
{ {
/* The prompt stack has not been initialized to "", we are /* The prompt stack has not been initialized to "", we are
using gdb w/o the --async switch */ using gdb w/o the --async switch. */
warning (_("Command has same effect as set annotate")); warning (_("Command has same effect as set annotate"));
return; return;
} }
@ -390,7 +390,8 @@ push_prompt (char *prefix, char *prompt, char *suffix)
SUFFIX (0) = xstrdup (suffix); SUFFIX (0) = xstrdup (suffix);
} }
/* Pops the top of the prompt stack, and frees the memory allocated for it. */ /* Pops the top of the prompt stack, and frees the memory allocated
for it. */
void void
pop_prompt (void) pop_prompt (void)
{ {
@ -442,7 +443,7 @@ async_enable_stdin (void)
{ {
if (sync_execution) if (sync_execution)
{ {
/* See NOTE in async_disable_stdin() */ /* See NOTE in async_disable_stdin(). */
/* FIXME: cagney/1999-09-27: Call this before clearing /* FIXME: cagney/1999-09-27: Call this before clearing
sync_execution. Current target_terminal_ours() implementations sync_execution. Current target_terminal_ours() implementations
check for sync_execution before switching the terminal. */ check for sync_execution before switching the terminal. */
@ -482,11 +483,11 @@ command_handler (char *command)
if (instream == stdin && stdin_is_tty) if (instream == stdin && stdin_is_tty)
reinitialize_more_filter (); reinitialize_more_filter ();
/* If readline returned a NULL command, it means that the /* If readline returned a NULL command, it means that the connection
connection with the terminal is gone. This happens at the with the terminal is gone. This happens at the end of a
end of a testsuite run, after Expect has hung up testsuite run, after Expect has hung up but GDB is still alive.
but GDB is still alive. In such a case, we just quit gdb In such a case, we just quit gdb killing the inferior program
killing the inferior program too. */ too. */
if (command == 0) if (command == 0)
{ {
printf_unfiltered ("quit\n"); printf_unfiltered ("quit\n");
@ -504,11 +505,12 @@ command_handler (char *command)
} }
/* Handle a complete line of input. This is called by the callback /* Handle a complete line of input. This is called by the callback
mechanism within the readline library. Deal with incomplete commands mechanism within the readline library. Deal with incomplete
as well, by saving the partial input in a global buffer. */ commands as well, by saving the partial input in a global
buffer. */
/* NOTE: 1999-04-30 This is the asynchronous version of the /* NOTE: 1999-04-30 This is the asynchronous version of the
command_line_input function. command_line_input will become command_line_input function; command_line_input will become
obsolete once we use the event loop as the default mechanism in obsolete once we use the event loop as the default mechanism in
GDB. */ GDB. */
static void static void
@ -555,7 +557,8 @@ command_line_handler (char *rl)
#endif #endif
/* Make sure that all output has been output. Some machines may let /* Make sure that all output has been output. Some machines may let
you get away with leaving out some of the gdb_flush, but not all. */ you get away with leaving out some of the gdb_flush, but not
all. */
wrap_here (""); wrap_here ("");
gdb_flush (gdb_stdout); gdb_flush (gdb_stdout);
gdb_flush (gdb_stderr); gdb_flush (gdb_stderr);
@ -580,7 +583,7 @@ command_line_handler (char *rl)
} }
p1 = rl; p1 = rl;
/* Copy line. Don't copy null at end. (Leaves line alone /* Copy line. Don't copy null at end. (Leaves line alone
if this was just a newline) */ if this was just a newline). */
while (*p1) while (*p1)
*p++ = *p1++; *p++ = *p1++;
@ -654,9 +657,8 @@ command_line_handler (char *rl)
xfree (history_value); xfree (history_value);
} }
/* If we just got an empty line, and that is supposed /* If we just got an empty line, and that is supposed to repeat the
to repeat the previous command, return the value in the previous command, return the value in the global buffer. */
global buffer. */
if (repeat && p == linebuffer && *p != '\\') if (repeat && p == linebuffer && *p != '\\')
{ {
command_handler (line); command_handler (line);
@ -713,7 +715,7 @@ command_line_handler (char *rl)
/* Does reading of input from terminal w/o the editing features /* Does reading of input from terminal w/o the editing features
provided by the readline library. */ provided by the readline library. */
/* NOTE: 1999-04-30 Asynchronous version of gdb_readline. gdb_readline /* NOTE: 1999-04-30 Asynchronous version of gdb_readline; gdb_readline
will become obsolete when the event loop is made the default will become obsolete when the event loop is made the default
execution for gdb. */ execution for gdb. */
void void
@ -755,9 +757,9 @@ gdb_readline2 (gdb_client_data client_data)
if (c == EOF) if (c == EOF)
{ {
if (input_index > 0) if (input_index > 0)
/* The last line does not end with a newline. Return it, and /* The last line does not end with a newline. Return it,
if we are called again fgetc will still return EOF and and if we are called again fgetc will still return EOF
we'll return NULL then. */ and we'll return NULL then. */
break; break;
xfree (result); xfree (result);
(*input_handler) (0); (*input_handler) (0);
@ -932,7 +934,7 @@ handle_sighup (int sig)
signal (sig, handle_sighup); signal (sig, handle_sighup);
} }
/* Called by the event loop to process a SIGHUP */ /* Called by the event loop to process a SIGHUP. */
static void static void
async_disconnect (gdb_client_data arg) async_disconnect (gdb_client_data arg)
{ {
@ -977,7 +979,8 @@ async_stop_sig (gdb_client_data arg)
printf_unfiltered ("%s", prompt); printf_unfiltered ("%s", prompt);
gdb_flush (gdb_stdout); gdb_flush (gdb_stdout);
/* Forget about any previous command -- null line now will do nothing. */ /* Forget about any previous command -- null line now will do
nothing. */
dont_repeat (); dont_repeat ();
} }
#endif /* STOP_SIGNAL */ #endif /* STOP_SIGNAL */
@ -1014,14 +1017,16 @@ handle_sigwinch (int sig)
/* Called by do_setshow_command. */ /* Called by do_setshow_command. */
void void
set_async_editing_command (char *args, int from_tty, struct cmd_list_element *c) set_async_editing_command (char *args, int from_tty,
struct cmd_list_element *c)
{ {
change_line_handler (); change_line_handler ();
} }
/* Called by do_setshow_command. */ /* Called by do_setshow_command. */
void void
set_async_annotation_level (char *args, int from_tty, struct cmd_list_element *c) set_async_annotation_level (char *args, int from_tty,
struct cmd_list_element *c)
{ {
change_annotation_level (); change_annotation_level ();
} }
@ -1070,7 +1075,7 @@ gdb_setup_readline (void)
} }
/* When readline has read an end-of-line character, it passes the /* When readline has read an end-of-line character, it passes the
complete line to gdb for processing. command_line_handler is the complete line to gdb for processing; command_line_handler is the
function that does this. */ function that does this. */
input_handler = command_line_handler; input_handler = command_line_handler;

View file

@ -20,16 +20,21 @@
#include "main.h" #include "main.h"
#include "gdb_string.h" #include "gdb_string.h"
#include "interps.h" #include "interps.h"
#include <mcheck.h>
int int
main (int argc, char **argv) main (int argc, char **argv)
{ {
struct captured_main_args args; struct captured_main_args args;
int ret;
mtrace ();
memset (&args, 0, sizeof args); memset (&args, 0, sizeof args);
args.argc = argc; args.argc = argc;
args.argv = argv; args.argv = argv;
args.use_windows = 0; args.use_windows = 0;
args.interpreter_p = INTERP_CONSOLE; args.interpreter_p = INTERP_CONSOLE;
return gdb_main (&args); ret = gdb_main (&args);
muntrace();
return ret;
} }

View file

@ -49,10 +49,10 @@
do_setshow_command will free it. */ do_setshow_command will free it. */
char *interpreter_p; char *interpreter_p;
/* Whether xdb commands will be handled */ /* Whether xdb commands will be handled. */
int xdb_commands = 0; int xdb_commands = 0;
/* Whether dbx commands will be handled */ /* Whether dbx commands will be handled. */
int dbx_commands = 0; int dbx_commands = 0;
/* System root path, used to find libraries etc. */ /* System root path, used to find libraries etc. */
@ -69,7 +69,7 @@ struct ui_file *gdb_stdout;
struct ui_file *gdb_stderr; struct ui_file *gdb_stderr;
struct ui_file *gdb_stdlog; struct ui_file *gdb_stdlog;
struct ui_file *gdb_stdin; struct ui_file *gdb_stdin;
/* target IO streams */ /* Target IO streams. */
struct ui_file *gdb_stdtargin; struct ui_file *gdb_stdtargin;
struct ui_file *gdb_stdtarg; struct ui_file *gdb_stdtarg;
struct ui_file *gdb_stdtargerr; struct ui_file *gdb_stdtargerr;
@ -86,7 +86,7 @@ int batch_silent = 0;
int return_child_result = 0; int return_child_result = 0;
int return_child_result_value = -1; int return_child_result_value = -1;
/* Whether to enable writing into executable and core files */ /* Whether to enable writing into executable and core files. */
extern int write_files; extern int write_files;
/* GDB as it has been invoked from the command line (i.e. argv[0]). */ /* GDB as it has been invoked from the command line (i.e. argv[0]). */
@ -94,8 +94,8 @@ static char *gdb_program_name;
static void print_gdb_help (struct ui_file *); static void print_gdb_help (struct ui_file *);
/* These two are used to set the external editor commands when gdb is farming /* These two are used to set the external editor commands when gdb is
out files to be edited by another program. */ farming out files to be edited by another program. */
extern char *external_editor_command; extern char *external_editor_command;
@ -151,11 +151,11 @@ relocate_directory (const char *progname, const char *initial, int flag)
return dir; return dir;
} }
/* Compute the locations of init files that GDB should source and return /* Compute the locations of init files that GDB should source and
them in SYSTEM_GDBINIT, HOME_GDBINIT, LOCAL_GDBINIT. If there is return them in SYSTEM_GDBINIT, HOME_GDBINIT, LOCAL_GDBINIT. If
no system gdbinit (resp. home gdbinit and local gdbinit) to be loaded, there is no system gdbinit (resp. home gdbinit and local gdbinit)
then SYSTEM_GDBINIT (resp. HOME_GDBINIT and LOCAL_GDBINIT) is set to to be loaded, then SYSTEM_GDBINIT (resp. HOME_GDBINIT and
NULL. */ LOCAL_GDBINIT) is set to NULL. */
static void static void
get_init_files (char **system_gdbinit, get_init_files (char **system_gdbinit,
char **home_gdbinit, char **home_gdbinit,
@ -260,7 +260,8 @@ captured_main (void *data)
char *cdarg = NULL; char *cdarg = NULL;
char *ttyarg = NULL; char *ttyarg = NULL;
/* These are static so that we can take their address in an initializer. */ /* These are static so that we can take their address in an
initializer. */
static int print_help; static int print_help;
static int print_version; static int print_version;
@ -317,7 +318,7 @@ captured_main (void *data)
quit_flag = 0; quit_flag = 0;
line = (char *) xmalloc (linesize); line = (char *) xmalloc (linesize);
line[0] = '\0'; /* Terminate saved (now empty) cmd line */ line[0] = '\0'; /* Terminate saved (now empty) cmd line. */
instream = stdin; instream = stdin;
gdb_stdout = stdio_fileopen (stdout); gdb_stdout = stdio_fileopen (stdout);
@ -400,9 +401,9 @@ captured_main (void *data)
{"batch", no_argument, &batch_flag, 1}, {"batch", no_argument, &batch_flag, 1},
{"epoch", no_argument, &epoch_interface, 1}, {"epoch", no_argument, &epoch_interface, 1},
/* This is a synonym for "--annotate=1". --annotate is now preferred, /* This is a synonym for "--annotate=1". --annotate is now
but keep this here for a long time because people will be running preferred, but keep this here for a long time because people
emacses which use --fullname. */ will be running emacses which use --fullname. */
{"fullname", no_argument, 0, 'f'}, {"fullname", no_argument, 0, 'f'},
{"f", no_argument, 0, 'f'}, {"f", no_argument, 0, 'f'},
@ -560,9 +561,11 @@ captured_main (void *data)
case 'z': case 'z':
{ {
extern int gdbtk_test (char *); extern int gdbtk_test (char *);
if (!gdbtk_test (optarg)) if (!gdbtk_test (optarg))
{ {
fprintf_unfiltered (gdb_stderr, _("%s: unable to load tclcommand file \"%s\""), fprintf_unfiltered (gdb_stderr,
_("%s: unable to load tclcommand file \"%s\""),
argv[0], optarg); argv[0], optarg);
exit (1); exit (1);
} }
@ -655,8 +658,8 @@ extern int gdbtk_test (char *);
control of the console via the deprecated_init_ui_hook (). */ control of the console via the deprecated_init_ui_hook (). */
gdb_init (argv[0]); gdb_init (argv[0]);
/* Now that gdb_init has created the initial inferior, we're in position /* Now that gdb_init has created the initial inferior, we're in
to set args for that inferior. */ position to set args for that inferior. */
if (set_args) if (set_args)
{ {
/* The remaining options are the command-line options for the /* The remaining options are the command-line options for the
@ -706,9 +709,9 @@ Excess command line arguments ignored. (%s%s)\n"),
(optind == argc - 1) ? "" : " ..."); (optind == argc - 1) ? "" : " ...");
} }
/* Lookup gdbinit files. Note that the gdbinit file name may be overriden /* Lookup gdbinit files. Note that the gdbinit file name may be
during file initialization, so get_init_files should be called after overriden during file initialization, so get_init_files should be
gdb_init. */ called after gdb_init. */
get_init_files (&system_gdbinit, &home_gdbinit, &local_gdbinit); get_init_files (&system_gdbinit, &home_gdbinit, &local_gdbinit);
/* Do these (and anything which might call wrap_here or *_filtered) /* Do these (and anything which might call wrap_here or *_filtered)
@ -737,17 +740,17 @@ Excess command line arguments ignored. (%s%s)\n"),
it isn't encapsulated in MI output. */ it isn't encapsulated in MI output. */
if (!quiet && strcmp (interpreter_p, INTERP_MI1) == 0) if (!quiet && strcmp (interpreter_p, INTERP_MI1) == 0)
{ {
/* Print all the junk at the top, with trailing "..." if we are about /* Print all the junk at the top, with trailing "..." if we are
to read a symbol file (possibly slowly). */ about to read a symbol file (possibly slowly). */
print_gdb_version (gdb_stdout); print_gdb_version (gdb_stdout);
if (symarg) if (symarg)
printf_filtered (".."); printf_filtered ("..");
wrap_here (""); wrap_here ("");
printf_filtered ("\n"); printf_filtered ("\n");
gdb_flush (gdb_stdout); /* Force to screen during slow operations */ gdb_flush (gdb_stdout); /* Force to screen during slow
operations. */
} }
/* Install the default UI. All the interpreters should have had a /* Install the default UI. All the interpreters should have had a
look at things by now. Initialize the default interpreter. */ look at things by now. Initialize the default interpreter. */
@ -773,14 +776,15 @@ Excess command line arguments ignored. (%s%s)\n"),
any sane interpreter. */ any sane interpreter. */
if (!quiet && !current_interp_named_p (INTERP_MI1)) if (!quiet && !current_interp_named_p (INTERP_MI1))
{ {
/* Print all the junk at the top, with trailing "..." if we are about /* Print all the junk at the top, with trailing "..." if we are
to read a symbol file (possibly slowly). */ about to read a symbol file (possibly slowly). */
print_gdb_version (gdb_stdout); print_gdb_version (gdb_stdout);
if (symarg) if (symarg)
printf_filtered (".."); printf_filtered ("..");
wrap_here (""); wrap_here ("");
printf_filtered ("\n"); printf_filtered ("\n");
gdb_flush (gdb_stdout); /* Force to screen during slow operations */ gdb_flush (gdb_stdout); /* Force to screen during slow
operations. */
} }
/* Set off error and warning messages with a blank line. */ /* Set off error and warning messages with a blank line. */
@ -814,7 +818,8 @@ Excess command line arguments ignored. (%s%s)\n"),
xfree (dirarg); xfree (dirarg);
/* Skip auto-loading section-specified scripts until we've sourced /* Skip auto-loading section-specified scripts until we've sourced
local_gdbinit (which is often used to augment the source search path). */ local_gdbinit (which is often used to augment the source search
path). */
save_auto_load = gdbpy_global_auto_load; save_auto_load = gdbpy_global_auto_load;
gdbpy_global_auto_load = 0; gdbpy_global_auto_load = 0;
@ -896,7 +901,8 @@ Can't attach to process and specify a core file at the same time."));
} }
xfree (cmdarg); xfree (cmdarg);
/* Read in the old history after all the command files have been read. */ /* Read in the old history after all the command files have been
read. */
init_history (); init_history ();
if (batch_flag) if (batch_flag)

121
gdb/top.c
View file

@ -49,7 +49,7 @@
#include "gdbthread.h" #include "gdbthread.h"
#include "python/python.h" #include "python/python.h"
/* readline include files */ /* readline include files. */
#include "readline/readline.h" #include "readline/readline.h"
#include "readline/history.h" #include "readline/history.h"
@ -107,9 +107,10 @@ Whether to confirm potentially dangerous operations is %s.\n"),
value); value);
} }
/* stdio stream that command input is being read from. Set to stdin normally. /* stdio stream that command input is being read from. Set to stdin
Set by source_command to the file we are sourcing. Set to NULL if we are normally. Set by source_command to the file we are sourcing. Set
executing a user-defined command or interacting via a GUI. */ to NULL if we are executing a user-defined command or interacting
via a GUI. */
FILE *instream; FILE *instream;
@ -149,8 +150,8 @@ int server_command;
/* Baud rate specified for talking to serial target systems. Default /* Baud rate specified for talking to serial target systems. Default
is left as -1, so targets can choose their own defaults. */ is left as -1, so targets can choose their own defaults. */
/* FIXME: This means that "show remotebaud" and gr_files_info can print -1 /* FIXME: This means that "show remotebaud" and gr_files_info can
or (unsigned int)-1. This is a Bad User Interface. */ print -1 or (unsigned int)-1. This is a Bad User Interface. */
int baud_rate = -1; int baud_rate = -1;
@ -187,17 +188,18 @@ char *lim_at_start;
/* Hooks for alternate command interfaces. */ /* Hooks for alternate command interfaces. */
/* Called after most modules have been initialized, but before taking users /* Called after most modules have been initialized, but before taking
command file. users command file.
If the UI fails to initialize and it wants GDB to continue If the UI fails to initialize and it wants GDB to continue using
using the default UI, then it should clear this hook before returning. */ the default UI, then it should clear this hook before returning. */
void (*deprecated_init_ui_hook) (char *argv0); void (*deprecated_init_ui_hook) (char *argv0);
/* This hook is called from within gdb's many mini-event loops which could /* This hook is called from within gdb's many mini-event loops which
steal control from a real user interface's event loop. It returns could steal control from a real user interface's event loop. It
non-zero if the user is requesting a detach, zero otherwise. */ returns non-zero if the user is requesting a detach, zero
otherwise. */
int (*deprecated_ui_loop_hook) (int); int (*deprecated_ui_loop_hook) (int);
@ -209,8 +211,10 @@ void (*deprecated_command_loop_hook) (void);
/* Called from print_frame_info to list the line we stopped in. */ /* Called from print_frame_info to list the line we stopped in. */
void (*deprecated_print_frame_info_listing_hook) (struct symtab * s, int line, void (*deprecated_print_frame_info_listing_hook) (struct symtab * s,
int stopline, int noerror); int line,
int stopline,
int noerror);
/* Replaces most of query. */ /* Replaces most of query. */
int (*deprecated_query_hook) (const char *, va_list); int (*deprecated_query_hook) (const char *, va_list);
@ -241,8 +245,8 @@ void (*deprecated_readline_end_hook) (void);
void (*deprecated_attach_hook) (void); void (*deprecated_attach_hook) (void);
void (*deprecated_detach_hook) (void); void (*deprecated_detach_hook) (void);
/* Called during long calculations to allow GUI to repair window damage, and to /* Called during long calculations to allow GUI to repair window
check for stop buttons, etc... */ damage, and to check for stop buttons, etc... */
void (*deprecated_interactive_hook) (void); void (*deprecated_interactive_hook) (void);
@ -251,18 +255,18 @@ void (*deprecated_interactive_hook) (void);
that several registers have changed (see value_assign). */ that several registers have changed (see value_assign). */
void (*deprecated_register_changed_hook) (int regno); void (*deprecated_register_changed_hook) (int regno);
/* Called when going to wait for the target. Usually allows the GUI to run /* Called when going to wait for the target. Usually allows the GUI
while waiting for target events. */ to run while waiting for target events. */
ptid_t (*deprecated_target_wait_hook) (ptid_t ptid, ptid_t (*deprecated_target_wait_hook) (ptid_t ptid,
struct target_waitstatus *status, struct target_waitstatus *status,
int options); int options);
/* Used by UI as a wrapper around command execution. May do various things /* Used by UI as a wrapper around command execution. May do various
like enabling/disabling buttons, etc... */ things like enabling/disabling buttons, etc... */
void (*deprecated_call_command_hook) (struct cmd_list_element * c, char *cmd, void (*deprecated_call_command_hook) (struct cmd_list_element * c,
int from_tty); char *cmd, int from_tty);
/* Called after a `set' command has finished. Is only run if the /* Called after a `set' command has finished. Is only run if the
`set' command succeeded. */ `set' command succeeded. */
@ -283,7 +287,8 @@ void (*deprecated_context_hook) (int id);
quit_cover (void *s) quit_cover (void *s)
{ {
caution = 0; /* Throw caution to the wind -- we're exiting. caution = 0; /* Throw caution to the wind -- we're exiting.
This prevents asking the user dumb questions. */ This prevents asking the user dumb
questions. */
quit_command ((char *) 0, 0); quit_command ((char *) 0, 0);
return 0; return 0;
} }
@ -339,10 +344,10 @@ prepare_execute_command (void)
{ {
free_all_values (); free_all_values ();
/* With multiple threads running while the one we're examining is stopped, /* With multiple threads running while the one we're examining is
the dcache can get stale without us being able to detect it. stopped, the dcache can get stale without us being able to detect
For the duration of the command, though, use the dcache to help it. For the duration of the command, though, use the dcache to
things like backtrace. */ help things like backtrace. */
if (non_stop) if (non_stop)
target_dcache_invalidate (); target_dcache_invalidate ();
} }
@ -550,8 +555,8 @@ dont_repeat (void)
return; return;
/* If we aren't reading from standard input, we are saving the last /* If we aren't reading from standard input, we are saving the last
thing read from stdin in line and don't want to delete it. Null lines thing read from stdin in line and don't want to delete it. Null
won't repeat here in any case. */ lines won't repeat here in any case. */
if (instream == stdin) if (instream == stdin)
*line = 0; *line = 0;
} }
@ -880,8 +885,9 @@ command_line_input (char *prompt_arg, int repeat, char *annotation_suffix)
while (1) while (1)
{ {
/* Make sure that all output has been output. Some machines may let /* Make sure that all output has been output. Some machines may
you get away with leaving out some of the gdb_flush, but not all. */ let you get away with leaving out some of the gdb_flush, but
not all. */
wrap_here (""); wrap_here ("");
gdb_flush (gdb_stdout); gdb_flush (gdb_stdout);
gdb_flush (gdb_stderr); gdb_flush (gdb_stderr);
@ -931,7 +937,7 @@ command_line_input (char *prompt_arg, int repeat, char *annotation_suffix)
} }
p1 = rl; p1 = rl;
/* Copy line. Don't copy null at end. (Leaves line alone /* Copy line. Don't copy null at end. (Leaves line alone
if this was just a newline) */ if this was just a newline). */
while (*p1) while (*p1)
*p++ = *p1++; *p++ = *p1++;
@ -997,9 +1003,8 @@ command_line_input (char *prompt_arg, int repeat, char *annotation_suffix)
xfree (history_value); xfree (history_value);
} }
/* If we just got an empty line, and that is supposed /* If we just got an empty line, and that is supposed to repeat the
to repeat the previous command, return the value in the previous command, return the value in the global buffer. */
global buffer. */
if (repeat && p == linebuffer) if (repeat && p == linebuffer)
return line; return line;
for (p1 = linebuffer; *p1 == ' ' || *p1 == '\t'; p1++); for (p1 = linebuffer; *p1 == ' ' || *p1 == '\t'; p1++);
@ -1221,8 +1226,8 @@ quit_target (void *arg)
if (write_history_p && history_filename) if (write_history_p && history_filename)
write_history (history_filename); write_history (history_filename);
do_final_cleanups (ALL_CLEANUPS); /* Do any final cleanups before exiting */ do_final_cleanups (ALL_CLEANUPS); /* Do any final cleanups before
exiting. */
return 0; return 0;
} }
@ -1305,8 +1310,8 @@ input_from_terminal_p (void)
static void static void
dont_repeat_command (char *ignored, int from_tty) dont_repeat_command (char *ignored, int from_tty)
{ {
*line = 0; /* Can't call dont_repeat here because we're not *line = 0; /* Can't call dont_repeat here because we're
necessarily reading from stdin. */ not necessarily reading from stdin. */
} }
/* Functions to manipulate command line editing control variables. */ /* Functions to manipulate command line editing control variables. */
@ -1414,7 +1419,7 @@ show_history (char *args, int from_tty)
cmd_show_list (showhistlist, from_tty, ""); cmd_show_list (showhistlist, from_tty, "");
} }
int info_verbose = 0; /* Default verbose msgs off */ int info_verbose = 0; /* Default verbose msgs off. */
/* Called by do_setshow_command. An elaborate joke. */ /* Called by do_setshow_command. An elaborate joke. */
void void
@ -1438,10 +1443,9 @@ set_verbose (char *args, int from_tty, struct cmd_list_element *c)
} }
/* Init the history buffer. Note that we are called after the init file(s) /* Init the history buffer. Note that we are called after the init file(s)
* have been read so that the user can change the history file via his have been read so that the user can change the history file via his
* .gdbinit file (for instance). The GDBHISTFILE environment variable .gdbinit file (for instance). The GDBHISTFILE environment variable
* overrides all of this. overrides all of this. */
*/
void void
init_history (void) init_history (void)
@ -1647,7 +1651,7 @@ gdb_init (char *argv0)
if (pre_init_ui_hook) if (pre_init_ui_hook)
pre_init_ui_hook (); pre_init_ui_hook ();
/* Run the init function of each source file */ /* Run the init function of each source file. */
#ifdef __MSDOS__ #ifdef __MSDOS__
/* Make sure we return to the original directory upon exit, come /* Make sure we return to the original directory upon exit, come
@ -1655,9 +1659,9 @@ gdb_init (char *argv0)
make_final_cleanup (do_chdir_cleanup, xstrdup (current_directory)); make_final_cleanup (do_chdir_cleanup, xstrdup (current_directory));
#endif #endif
init_cmd_lists (); /* This needs to be done first */ init_cmd_lists (); /* This needs to be done first. */
initialize_targets (); /* Setup target_terminal macros for utils.c */ initialize_targets (); /* Setup target_terminal macros for utils.c. */
initialize_utils (); /* Make errors and warnings possible */ initialize_utils (); /* Make errors and warnings possible. */
/* Here is where we call all the _initialize_foo routines. */ /* Here is where we call all the _initialize_foo routines. */
initialize_all_files (); initialize_all_files ();
@ -1671,17 +1675,18 @@ gdb_init (char *argv0)
initialize_inferiors (); initialize_inferiors ();
initialize_current_architecture (); initialize_current_architecture ();
init_cli_cmds(); init_cli_cmds();
init_main (); /* But that omits this file! Do it now */ init_main (); /* But that omits this file! Do it now. */
initialize_stdin_serial (); initialize_stdin_serial ();
async_init_signals (); async_init_signals ();
/* We need a default language for parsing expressions, so simple things like /* We need a default language for parsing expressions, so simple
"set width 0" won't fail if no language is explicitly set in a config file things like "set width 0" won't fail if no language is explicitly
or implicitly set by reading an executable during startup. */ set in a config file or implicitly set by reading an executable
during startup. */
set_language (language_c); set_language (language_c);
expected_language = current_language; /* don't warn about the change. */ expected_language = current_language; /* Don't warn about the change. */
/* Allow another UI to initialize. If the UI fails to initialize, /* Allow another UI to initialize. If the UI fails to initialize,
and it wants GDB to revert to the CLI, it should clear and it wants GDB to revert to the CLI, it should clear
@ -1690,10 +1695,10 @@ gdb_init (char *argv0)
deprecated_init_ui_hook (argv0); deprecated_init_ui_hook (argv0);
#ifdef HAVE_PYTHON #ifdef HAVE_PYTHON
/* Python initialization can require various commands to be installed. /* Python initialization can require various commands to be
For example "info pretty-printer" needs the "info" prefix to be installed. For example "info pretty-printer" needs the "info"
installed. Keep things simple and just do final python initialization prefix to be installed. Keep things simple and just do final
here. */ python initialization here. */
finish_python_initialization (); finish_python_initialization ();
#endif #endif
} }

View file

@ -62,10 +62,10 @@ extern void set_prompt (char *);
/* From random places. */ /* From random places. */
extern int readnow_symbol_files; extern int readnow_symbol_files;
/* Perform _initialize initialization */ /* Perform _initialize initialization. */
extern void gdb_init (char *); extern void gdb_init (char *);
/* For use by event-top.c */ /* For use by event-top.c. */
/* Variables from top.c. */ /* Variables from top.c. */
extern int source_line_number; extern int source_line_number;
extern const char *source_file_name; extern const char *source_file_name;