mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-27 03:51:15 +08:00
701f976540
foe->for executin ->execution.
1180 lines
36 KiB
C
1180 lines
36 KiB
C
/* Top level stuff for GDB, the GNU debugger.
|
||
Copyright 1999 Free Software Foundation, Inc.
|
||
Written by Elena Zannoni <ezannoni@cygnus.com> of Cygnus Solutions.
|
||
|
||
This file is part of GDB.
|
||
|
||
This program is free software; you can redistribute it and/or modify
|
||
it under the terms of the GNU General Public License as published by
|
||
the Free Software Foundation; either version 2 of the License, or
|
||
(at your option) any later version.
|
||
|
||
This program is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
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, write to the Free Software
|
||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||
Boston, MA 02111-1307, USA. */
|
||
|
||
#include "defs.h"
|
||
#include "top.h"
|
||
#include "inferior.h"
|
||
#include "target.h"
|
||
#include "terminal.h" /* for job_control */
|
||
#include "signals.h"
|
||
#include "event-loop.h"
|
||
#include "event-top.h"
|
||
|
||
/* For dont_repeat() */
|
||
#include "gdbcmd.h"
|
||
|
||
/* readline include files */
|
||
#include <readline/readline.h>
|
||
#include <readline/history.h>
|
||
|
||
#include <signal.h>
|
||
|
||
/* readline defines this. */
|
||
#undef savestring
|
||
|
||
extern void _initialize_event_loop (void);
|
||
|
||
static void rl_callback_read_char_wrapper (gdb_client_data client_data);
|
||
static void command_line_handler (char *rl);
|
||
static void command_line_handler_continuation (struct continuation_arg *arg);
|
||
static void change_line_handler (void);
|
||
static void change_annotation_level (void);
|
||
static void command_handler (char *command);
|
||
void cli_command_loop (void);
|
||
static void async_do_nothing (gdb_client_data arg);
|
||
static void async_disconnect (gdb_client_data arg);
|
||
static void async_stop_sig (gdb_client_data arg);
|
||
static void async_float_handler (gdb_client_data arg);
|
||
|
||
/* Signal handlers. */
|
||
static void handle_sigquit (int sig);
|
||
static void handle_sighup (int sig);
|
||
static void handle_sigfpe (int sig);
|
||
#if defined(SIGWINCH) && defined(SIGWINCH_HANDLER)
|
||
static void handle_sigwinch (int sig);
|
||
#endif
|
||
|
||
/* Functions to be invoked by the event loop in response to
|
||
signals. */
|
||
static void async_do_nothing (gdb_client_data);
|
||
static void async_disconnect (gdb_client_data);
|
||
static void async_float_handler (gdb_client_data);
|
||
static void async_stop_sig (gdb_client_data);
|
||
|
||
/* Readline offers an alternate interface, via callback
|
||
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
|
||
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
|
||
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. */
|
||
|
||
void (*input_handler) (char *);
|
||
void (*call_readline) (gdb_client_data);
|
||
|
||
/* 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
|
||
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. */
|
||
int async_command_editing_p;
|
||
|
||
/* This variable contains the new prompt that the user sets with the
|
||
set prompt command. */
|
||
char *new_async_prompt;
|
||
|
||
/* This is the annotation suffix that will be used when the
|
||
annotation_level is 2. */
|
||
char *async_annotation_suffix;
|
||
|
||
/* This is used to display the notification of the completion of an
|
||
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. */
|
||
int input_fd;
|
||
|
||
/* 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. */
|
||
struct prompts the_prompts;
|
||
|
||
/* 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
|
||
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. */
|
||
void *sigint_token;
|
||
#ifdef SIGHUP
|
||
void *sighup_token;
|
||
#endif
|
||
void *sigquit_token;
|
||
void *sigfpe_token;
|
||
#if defined(SIGWINCH) && defined(SIGWINCH_HANDLER)
|
||
void *sigwinch_token;
|
||
#endif
|
||
#ifdef STOP_SIGNAL
|
||
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
|
||
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. */
|
||
int more_to_come = 0;
|
||
|
||
struct readline_input_state
|
||
{
|
||
char *linebuffer;
|
||
char *linebuffer_ptr;
|
||
}
|
||
readline_input_state;
|
||
|
||
|
||
/* 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)
|
||
{
|
||
rl_callback_read_char ();
|
||
}
|
||
|
||
/* Initialize all the necessary variables, start the event loop,
|
||
register readline, and stdin, start the loop. */
|
||
void
|
||
cli_command_loop (void)
|
||
{
|
||
int length;
|
||
char *a_prompt;
|
||
char *gdb_prompt = get_prompt ();
|
||
|
||
/* If we are using readline, set things up and display the first
|
||
prompt, otherwise just print the prompt. */
|
||
if (async_command_editing_p)
|
||
{
|
||
/* 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 *) xmalloc (length);
|
||
strcpy (a_prompt, PREFIX (0));
|
||
strcat (a_prompt, gdb_prompt);
|
||
strcat (a_prompt, SUFFIX (0));
|
||
rl_callback_handler_install (a_prompt, input_handler);
|
||
}
|
||
else
|
||
display_gdb_prompt (0);
|
||
|
||
/* 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,
|
||
therefore bypassing readline, and letting gdb handle the input
|
||
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. */
|
||
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
|
||
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. */
|
||
|
||
if (async_command_editing_p)
|
||
{
|
||
/* 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. */
|
||
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. */
|
||
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
|
||
after each gdb command has completed, and in the following cases:
|
||
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 '>'
|
||
3. Other????
|
||
FIXME: 2. & 3. not implemented yet for async. */
|
||
void
|
||
display_gdb_prompt (char *new_prompt)
|
||
{
|
||
int prompt_length = 0;
|
||
char *gdb_prompt = get_prompt ();
|
||
|
||
#ifdef UI_OUT
|
||
/* When an alternative interpreter has been installed, do not
|
||
display the comand prompt. */
|
||
if (interpreter_p)
|
||
return;
|
||
#endif
|
||
|
||
if (target_executing && sync_execution)
|
||
{
|
||
/* This is to trick readline into not trying to display the
|
||
prompt. Even though we display the prompt using this
|
||
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
|
||
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
|
||
not the case, because when the target executes we change 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. */
|
||
|
||
rl_callback_handler_remove ();
|
||
return;
|
||
}
|
||
|
||
if (!new_prompt)
|
||
{
|
||
/* 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. */
|
||
strcpy (new_prompt, PREFIX (0));
|
||
strcat (new_prompt, gdb_prompt);
|
||
/* Suffix needs to have a new line at end and \032 \032 at
|
||
beginning. */
|
||
strcat (new_prompt, SUFFIX (0));
|
||
}
|
||
|
||
if (async_command_editing_p)
|
||
{
|
||
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 */
|
||
else if (new_prompt)
|
||
{
|
||
/* Don't use a _filtered function here. It causes the assumed
|
||
character position to be off, since the newline we read from
|
||
the user is not accounted for. */
|
||
fputs_unfiltered (new_prompt, gdb_stdout);
|
||
|
||
#ifdef MPW
|
||
/* Move to a new line so the entered line doesn't have a prompt
|
||
on the front of it. */
|
||
fputs_unfiltered ("\n", gdb_stdout);
|
||
#endif /* MPW */
|
||
gdb_flush (gdb_stdout);
|
||
}
|
||
}
|
||
|
||
/* Used when the user requests a different annotation level, with
|
||
'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). */
|
||
static void
|
||
change_annotation_level (void)
|
||
{
|
||
char *prefix, *suffix;
|
||
|
||
if (!PREFIX (0) || !PROMPT (0) || !SUFFIX (0))
|
||
{
|
||
/* The prompt stack has not been initialized to "", we are
|
||
using gdb w/o the --async switch */
|
||
warning ("Command has same effect as set annotate");
|
||
return;
|
||
}
|
||
|
||
if (annotation_level > 1)
|
||
{
|
||
if (!strcmp (PREFIX (0), "") && !strcmp (SUFFIX (0), ""))
|
||
{
|
||
/* 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);
|
||
strcat (prefix, "\n");
|
||
|
||
suffix = (char *) alloca (strlen (async_annotation_suffix) + 6);
|
||
strcpy (suffix, "\n\032\032");
|
||
strcat (suffix, async_annotation_suffix);
|
||
strcat (suffix, "\n");
|
||
|
||
push_prompt (prefix, (char *) 0, suffix);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (strcmp (PREFIX (0), "") && strcmp (SUFFIX (0), ""))
|
||
{
|
||
/* 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 savestring for the new prompt. */
|
||
void
|
||
push_prompt (char *prefix, char *prompt, char *suffix)
|
||
{
|
||
the_prompts.top++;
|
||
PREFIX (0) = savestring (prefix, strlen (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. */
|
||
if (prompt)
|
||
PROMPT (0) = savestring (prompt, strlen (prompt));
|
||
else
|
||
PROMPT (0) = savestring (PROMPT (-1), strlen (PROMPT (-1)));
|
||
|
||
SUFFIX (0) = savestring (suffix, strlen (suffix));
|
||
}
|
||
|
||
/* 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. */
|
||
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
|
||
we return to annotation level < 2, we want that new prompt to be
|
||
in effect, until the user does another 'set prompt'. */
|
||
if (strcmp (PROMPT (0), PROMPT (-1)))
|
||
{
|
||
free (PROMPT (-1));
|
||
PROMPT (-1) = savestring (PROMPT (0), strlen (PROMPT (0)));
|
||
}
|
||
|
||
free (PREFIX (0));
|
||
free (PROMPT (0));
|
||
free (SUFFIX (0));
|
||
the_prompts.top--;
|
||
}
|
||
|
||
/* 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. */
|
||
void
|
||
stdin_event_handler (int error, gdb_client_data client_data)
|
||
{
|
||
if (error)
|
||
{
|
||
printf_unfiltered ("error detected on stdin\n");
|
||
delete_file_handler (input_fd);
|
||
discard_all_continuations ();
|
||
/* If stdin died, we may as well kill gdb. */
|
||
quit_command ((char *) 0, stdin == instream);
|
||
}
|
||
else
|
||
(*call_readline) (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. */
|
||
|
||
void
|
||
async_enable_stdin (void *dummy)
|
||
{
|
||
/* 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. */
|
||
target_terminal_ours ();
|
||
pop_prompt ();
|
||
sync_execution = 0;
|
||
}
|
||
|
||
/* Disable reads from stdin (the console) marking the command as
|
||
synchronous. */
|
||
|
||
void
|
||
async_disable_stdin (void)
|
||
{
|
||
sync_execution = 1;
|
||
push_prompt ("", "", "");
|
||
/* FIXME: cagney/1999-09-27: At present this call is technically
|
||
redundant since infcmd.c and infrun.c both already call
|
||
target_terminal_inferior(). As the terminal handling (in
|
||
sync/async mode) is refined, the duplicate calls can be
|
||
eliminated (Here or in infcmd.c/infrun.c). */
|
||
target_terminal_inferior ();
|
||
/* Add the reinstate of stdin to the list of cleanups to be done
|
||
in case the target errors out and dies. These cleanups are also
|
||
done in case of normal successful termination of the execution
|
||
command, by complete_execution(). */
|
||
make_exec_error_cleanup (async_enable_stdin, NULL);
|
||
}
|
||
|
||
|
||
/* Handles a gdb command. This function is called by
|
||
command_line_handler, which has processed one or more input lines
|
||
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. */
|
||
static void
|
||
command_handler (char *command)
|
||
{
|
||
struct cleanup *old_chain;
|
||
int stdin_is_tty = ISATTY (stdin);
|
||
struct continuation_arg *arg1;
|
||
struct continuation_arg *arg2;
|
||
long time_at_cmd_start;
|
||
#ifdef HAVE_SBRK
|
||
long space_at_cmd_start = 0;
|
||
#endif
|
||
extern int display_time;
|
||
extern int display_space;
|
||
|
||
#if defined(TUI)
|
||
extern int insert_mode;
|
||
#endif
|
||
|
||
quit_flag = 0;
|
||
if (instream == stdin && stdin_is_tty)
|
||
reinitialize_more_filter ();
|
||
old_chain = make_cleanup (null_cleanup, 0);
|
||
|
||
#if defined(TUI)
|
||
insert_mode = 0;
|
||
#endif
|
||
/* 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)
|
||
quit_command ((char *) 0, stdin == instream);
|
||
|
||
time_at_cmd_start = get_run_time ();
|
||
|
||
if (display_space)
|
||
{
|
||
#ifdef HAVE_SBRK
|
||
extern char **environ;
|
||
char *lim = (char *) sbrk (0);
|
||
|
||
space_at_cmd_start = (long) (lim - (char *) &environ);
|
||
#endif
|
||
}
|
||
|
||
execute_command (command, instream == stdin);
|
||
|
||
/* Set things up for this function to be compete later, once the
|
||
execution has completed, if we are doing an execution command,
|
||
otherwise, just go ahead and finish. */
|
||
if (target_can_async_p () && target_executing)
|
||
{
|
||
arg1 =
|
||
(struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
|
||
arg2 =
|
||
(struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
|
||
arg1->next = arg2;
|
||
arg2->next = NULL;
|
||
arg1->data.integer = time_at_cmd_start;
|
||
arg2->data.integer = space_at_cmd_start;
|
||
add_continuation (command_line_handler_continuation, arg1);
|
||
}
|
||
|
||
/* Do any commands attached to breakpoint we stopped at. Only if we
|
||
are always running synchronously. Or if we have just executed a
|
||
command that doesn't start the target. */
|
||
if (!target_can_async_p () || !target_executing)
|
||
{
|
||
bpstat_do_actions (&stop_bpstat);
|
||
do_cleanups (old_chain);
|
||
|
||
if (display_time)
|
||
{
|
||
long cmd_time = get_run_time () - time_at_cmd_start;
|
||
|
||
printf_unfiltered ("Command execution time: %ld.%06ld\n",
|
||
cmd_time / 1000000, cmd_time % 1000000);
|
||
}
|
||
|
||
if (display_space)
|
||
{
|
||
#ifdef HAVE_SBRK
|
||
extern char **environ;
|
||
char *lim = (char *) sbrk (0);
|
||
long space_now = lim - (char *) &environ;
|
||
long space_diff = space_now - space_at_cmd_start;
|
||
|
||
printf_unfiltered ("Space used: %ld (%c%ld for this command)\n",
|
||
space_now,
|
||
(space_diff >= 0 ? '+' : '-'),
|
||
space_diff);
|
||
#endif
|
||
}
|
||
}
|
||
}
|
||
|
||
/* Do any commands attached to breakpoint we stopped at. Only if we
|
||
are always running synchronously. Or if we have just executed a
|
||
command that doesn't start the target. */
|
||
void
|
||
command_line_handler_continuation (struct continuation_arg *arg)
|
||
{
|
||
extern int display_time;
|
||
extern int display_space;
|
||
|
||
long time_at_cmd_start = arg->data.longint;
|
||
long space_at_cmd_start = arg->next->data.longint;
|
||
|
||
bpstat_do_actions (&stop_bpstat);
|
||
/*do_cleanups (old_chain); *//*?????FIXME????? */
|
||
|
||
if (display_time)
|
||
{
|
||
long cmd_time = get_run_time () - time_at_cmd_start;
|
||
|
||
printf_unfiltered ("Command execution time: %ld.%06ld\n",
|
||
cmd_time / 1000000, cmd_time % 1000000);
|
||
}
|
||
if (display_space)
|
||
{
|
||
#ifdef HAVE_SBRK
|
||
extern char **environ;
|
||
char *lim = (char *) sbrk (0);
|
||
long space_now = lim - (char *) &environ;
|
||
long space_diff = space_now - space_at_cmd_start;
|
||
|
||
printf_unfiltered ("Space used: %ld (%c%ld for this command)\n",
|
||
space_now,
|
||
(space_diff >= 0 ? '+' : '-'),
|
||
space_diff);
|
||
#endif
|
||
}
|
||
}
|
||
|
||
/* 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
|
||
obsolete once we use the event loop as the default mechanism in
|
||
GDB. */
|
||
static void
|
||
command_line_handler (char *rl)
|
||
{
|
||
static char *linebuffer = 0;
|
||
static unsigned linelength = 0;
|
||
register char *p;
|
||
char *p1;
|
||
extern char *line;
|
||
extern int linesize;
|
||
char *nline;
|
||
char got_eof = 0;
|
||
|
||
|
||
int repeat = (instream == stdin);
|
||
|
||
if (annotation_level > 1 && instream == stdin)
|
||
{
|
||
printf_unfiltered ("\n\032\032post-");
|
||
printf_unfiltered (async_annotation_suffix);
|
||
printf_unfiltered ("\n");
|
||
}
|
||
|
||
if (linebuffer == 0)
|
||
{
|
||
linelength = 80;
|
||
linebuffer = (char *) xmalloc (linelength);
|
||
}
|
||
|
||
p = linebuffer;
|
||
|
||
if (more_to_come)
|
||
{
|
||
strcpy (linebuffer, readline_input_state.linebuffer);
|
||
p = readline_input_state.linebuffer_ptr;
|
||
free (readline_input_state.linebuffer);
|
||
more_to_come = 0;
|
||
pop_prompt ();
|
||
}
|
||
|
||
#ifdef STOP_SIGNAL
|
||
if (job_control)
|
||
signal (STOP_SIGNAL, handle_stop_sig);
|
||
#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. */
|
||
wrap_here ("");
|
||
gdb_flush (gdb_stdout);
|
||
gdb_flush (gdb_stderr);
|
||
|
||
if (source_file_name != NULL)
|
||
{
|
||
++source_line_number;
|
||
sprintf (source_error,
|
||
"%s%s:%d: Error in sourced command file:\n",
|
||
source_pre_error,
|
||
source_file_name,
|
||
source_line_number);
|
||
error_pre_print = source_error;
|
||
}
|
||
|
||
/* If we are in this case, then command_handler will call quit
|
||
and exit from gdb. */
|
||
if (!rl || rl == (char *) EOF)
|
||
{
|
||
got_eof = 1;
|
||
command_handler (0);
|
||
}
|
||
if (strlen (rl) + 1 + (p - linebuffer) > linelength)
|
||
{
|
||
linelength = strlen (rl) + 1 + (p - linebuffer);
|
||
nline = (char *) xrealloc (linebuffer, linelength);
|
||
p += nline - linebuffer;
|
||
linebuffer = nline;
|
||
}
|
||
p1 = rl;
|
||
/* Copy line. Don't copy null at end. (Leaves line alone
|
||
if this was just a newline) */
|
||
while (*p1)
|
||
*p++ = *p1++;
|
||
|
||
free (rl); /* Allocated in readline. */
|
||
|
||
if (*(p - 1) == '\\')
|
||
{
|
||
p--; /* Put on top of '\'. */
|
||
|
||
if (*p == '\\')
|
||
{
|
||
readline_input_state.linebuffer = savestring (linebuffer,
|
||
strlen (linebuffer));
|
||
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. */
|
||
more_to_come = 1;
|
||
push_prompt ("", "", "");
|
||
display_gdb_prompt (0);
|
||
return;
|
||
}
|
||
}
|
||
|
||
#ifdef STOP_SIGNAL
|
||
if (job_control)
|
||
signal (STOP_SIGNAL, SIG_DFL);
|
||
#endif
|
||
|
||
#define SERVER_COMMAND_LENGTH 7
|
||
server_command =
|
||
(p - linebuffer > SERVER_COMMAND_LENGTH)
|
||
&& STREQN (linebuffer, "server ", SERVER_COMMAND_LENGTH);
|
||
if (server_command)
|
||
{
|
||
/* Note that we don't set `line'. Between this and the check in
|
||
dont_repeat, this insures that repeating will still do the
|
||
right thing. */
|
||
*p = '\0';
|
||
command_handler (linebuffer + SERVER_COMMAND_LENGTH);
|
||
display_gdb_prompt (0);
|
||
return;
|
||
}
|
||
|
||
/* Do history expansion if that is wished. */
|
||
if (history_expansion_p && instream == stdin
|
||
&& ISATTY (instream))
|
||
{
|
||
char *history_value;
|
||
int expanded;
|
||
|
||
*p = '\0'; /* Insert null now. */
|
||
expanded = history_expand (linebuffer, &history_value);
|
||
if (expanded)
|
||
{
|
||
/* Print the changes. */
|
||
printf_unfiltered ("%s\n", history_value);
|
||
|
||
/* If there was an error, call this function again. */
|
||
if (expanded < 0)
|
||
{
|
||
free (history_value);
|
||
return;
|
||
}
|
||
if (strlen (history_value) > linelength)
|
||
{
|
||
linelength = strlen (history_value) + 1;
|
||
linebuffer = (char *) xrealloc (linebuffer, linelength);
|
||
}
|
||
strcpy (linebuffer, history_value);
|
||
p = linebuffer + strlen (linebuffer);
|
||
free (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 (repeat && p == linebuffer && *p != '\\')
|
||
{
|
||
command_handler (line);
|
||
display_gdb_prompt (0);
|
||
return;
|
||
}
|
||
|
||
for (p1 = linebuffer; *p1 == ' ' || *p1 == '\t'; p1++);
|
||
if (repeat && !*p1)
|
||
{
|
||
command_handler (line);
|
||
display_gdb_prompt (0);
|
||
return;
|
||
}
|
||
|
||
*p = 0;
|
||
|
||
/* Add line to history if appropriate. */
|
||
if (instream == stdin
|
||
&& ISATTY (stdin) && *linebuffer)
|
||
add_history (linebuffer);
|
||
|
||
/* Note: lines consisting solely of comments are added to the command
|
||
history. This is useful when you type a command, and then
|
||
realize you don't want to execute it quite yet. You can comment
|
||
out the command and then later fetch it from the value history
|
||
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. */
|
||
|
||
/* Save into global buffer if appropriate. */
|
||
if (repeat)
|
||
{
|
||
if (linelength > linesize)
|
||
{
|
||
line = xrealloc (line, linelength);
|
||
linesize = linelength;
|
||
}
|
||
strcpy (line, linebuffer);
|
||
if (!more_to_come)
|
||
{
|
||
command_handler (line);
|
||
display_gdb_prompt (0);
|
||
}
|
||
return;
|
||
}
|
||
|
||
command_handler (linebuffer);
|
||
display_gdb_prompt (0);
|
||
return;
|
||
}
|
||
|
||
/* Does reading of input from terminal w/o the editing features
|
||
provided by the readline library. */
|
||
|
||
/* 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. */
|
||
void
|
||
gdb_readline2 (gdb_client_data client_data)
|
||
{
|
||
int c;
|
||
char *result;
|
||
int input_index = 0;
|
||
int result_size = 80;
|
||
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
|
||
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, getting stuff beyond the newline as well, a select, done
|
||
afterwards will not trigger. */
|
||
if (!done_once && !ISATTY (instream))
|
||
{
|
||
setbuf (instream, NULL);
|
||
done_once = 1;
|
||
}
|
||
|
||
result = (char *) xmalloc (result_size);
|
||
|
||
/* 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. */
|
||
|
||
while (1)
|
||
{
|
||
/* Read from stdin if we are executing a user defined command.
|
||
This is the right thing for prompt_for_continue, at least. */
|
||
c = fgetc (instream ? instream : stdin);
|
||
|
||
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. */
|
||
break;
|
||
free (result);
|
||
(*input_handler) (0);
|
||
}
|
||
|
||
if (c == '\n')
|
||
#ifndef CRLF_SOURCE_FILES
|
||
break;
|
||
#else
|
||
{
|
||
if (input_index > 0 && result[input_index - 1] == '\r')
|
||
input_index--;
|
||
break;
|
||
}
|
||
#endif
|
||
|
||
result[input_index++] = c;
|
||
while (input_index >= result_size)
|
||
{
|
||
result_size *= 2;
|
||
result = (char *) xrealloc (result, result_size);
|
||
}
|
||
}
|
||
|
||
result[input_index++] = '\0';
|
||
(*input_handler) (result);
|
||
}
|
||
|
||
|
||
/* Initialization of signal handlers and tokens. There is a function
|
||
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
|
||
care of invoking the queued procedures to perform the usual tasks
|
||
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. */
|
||
void
|
||
async_init_signals (void)
|
||
{
|
||
signal (SIGINT, handle_sigint);
|
||
sigint_token =
|
||
create_async_signal_handler (async_request_quit, NULL);
|
||
|
||
/* If SIGTRAP was set to SIG_IGN, then the SIG_IGN will get passed
|
||
to the inferior and breakpoints will be ignored. */
|
||
#ifdef SIGTRAP
|
||
signal (SIGTRAP, SIG_DFL);
|
||
#endif
|
||
|
||
/* If we initialize SIGQUIT to SIG_IGN, then the SIG_IGN will get
|
||
passed to the inferior, which we don't want. It would be
|
||
possible to do a "signal (SIGQUIT, SIG_DFL)" after we fork, but
|
||
on BSD4.3 systems using vfork, that can affect the
|
||
GDB process as well as the inferior (the signal handling tables
|
||
might be in memory, shared between the two). Since we establish
|
||
a handler for SIGQUIT, when we call exec it will set the signal
|
||
to SIG_DFL for us. */
|
||
signal (SIGQUIT, handle_sigquit);
|
||
sigquit_token =
|
||
create_async_signal_handler (async_do_nothing, NULL);
|
||
#ifdef SIGHUP
|
||
if (signal (SIGHUP, handle_sighup) != SIG_IGN)
|
||
sighup_token =
|
||
create_async_signal_handler (async_disconnect, NULL);
|
||
else
|
||
sighup_token =
|
||
create_async_signal_handler (async_do_nothing, NULL);
|
||
#endif
|
||
signal (SIGFPE, handle_sigfpe);
|
||
sigfpe_token =
|
||
create_async_signal_handler (async_float_handler, NULL);
|
||
|
||
#if defined(SIGWINCH) && defined(SIGWINCH_HANDLER)
|
||
signal (SIGWINCH, handle_sigwinch);
|
||
sigwinch_token =
|
||
create_async_signal_handler (SIGWINCH_HANDLER, NULL);
|
||
#endif
|
||
#ifdef STOP_SIGNAL
|
||
sigtstp_token =
|
||
create_async_signal_handler (async_stop_sig, NULL);
|
||
#endif
|
||
|
||
}
|
||
|
||
void
|
||
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. */
|
||
void
|
||
handle_sigint (int sig)
|
||
{
|
||
signal (sig, handle_sigint);
|
||
|
||
/* 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
|
||
assumption here is that it is safe to process ^C immediately if
|
||
immediate_quit is set. If we didn't, SIGINT would be really
|
||
processed only the next time through the event loop. To get to
|
||
that point, though, the command that we want to interrupt needs to
|
||
finish first, which is unacceptable. */
|
||
if (immediate_quit)
|
||
async_request_quit (0);
|
||
else
|
||
/* If immediate quit is not set, we process SIGINT the next time
|
||
through the loop, which is fine. */
|
||
mark_async_signal_handler_wrapper (sigint_token);
|
||
}
|
||
|
||
/* Do the quit. All the checks have been done by the caller. */
|
||
void
|
||
async_request_quit (gdb_client_data arg)
|
||
{
|
||
quit_flag = 1;
|
||
#ifdef REQUEST_QUIT
|
||
REQUEST_QUIT;
|
||
#else
|
||
quit ();
|
||
#endif
|
||
}
|
||
|
||
/* Tell the event loop what to do if SIGQUIT is received.
|
||
See event-signal.c. */
|
||
static void
|
||
handle_sigquit (int sig)
|
||
{
|
||
mark_async_signal_handler_wrapper (sigquit_token);
|
||
signal (sig, handle_sigquit);
|
||
}
|
||
|
||
/* Called by the event loop in response to a SIGQUIT. */
|
||
static void
|
||
async_do_nothing (gdb_client_data arg)
|
||
{
|
||
/* Empty function body. */
|
||
}
|
||
|
||
#ifdef SIGHUP
|
||
/* Tell the event loop what to do if SIGHUP is received.
|
||
See event-signal.c. */
|
||
static void
|
||
handle_sighup (int sig)
|
||
{
|
||
mark_async_signal_handler_wrapper (sighup_token);
|
||
signal (sig, handle_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: ??????????? */
|
||
kill (getpid (), SIGHUP);
|
||
}
|
||
#endif
|
||
|
||
#ifdef STOP_SIGNAL
|
||
void
|
||
handle_stop_sig (int sig)
|
||
{
|
||
mark_async_signal_handler_wrapper (sigtstp_token);
|
||
signal (sig, handle_stop_sig);
|
||
}
|
||
|
||
static void
|
||
async_stop_sig (gdb_client_data arg)
|
||
{
|
||
char *prompt = get_prompt ();
|
||
#if STOP_SIGNAL == SIGTSTP
|
||
signal (SIGTSTP, SIG_DFL);
|
||
#if HAVE_SIGPROCMASK
|
||
{
|
||
sigset_t zero;
|
||
sigemptyset (&zero);
|
||
sigprocmask (SIG_SETMASK, &zero, 0);
|
||
}
|
||
#else
|
||
sigsetmask (0);
|
||
#endif
|
||
kill (getpid (), SIGTSTP);
|
||
signal (SIGTSTP, handle_stop_sig);
|
||
#else
|
||
signal (STOP_SIGNAL, handle_stop_sig);
|
||
#endif
|
||
printf_unfiltered ("%s", prompt);
|
||
gdb_flush (gdb_stdout);
|
||
|
||
/* 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. */
|
||
static void
|
||
handle_sigfpe (int sig)
|
||
{
|
||
mark_async_signal_handler_wrapper (sigfpe_token);
|
||
signal (sig, handle_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. */
|
||
error ("Erroneous arithmetic operation.");
|
||
}
|
||
|
||
/* 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)
|
||
{
|
||
mark_async_signal_handler_wrapper (sigwinch_token);
|
||
signal (sig, handle_sigwinch);
|
||
}
|
||
#endif
|
||
|
||
|
||
/* Called by do_setshow_command. */
|
||
/* ARGSUSED */
|
||
void
|
||
set_async_editing_command (char *args, int from_tty, struct cmd_list_element *c)
|
||
{
|
||
change_line_handler ();
|
||
}
|
||
|
||
/* Called by do_setshow_command. */
|
||
/* ARGSUSED */
|
||
void
|
||
set_async_annotation_level (char *args, int from_tty, struct cmd_list_element *c)
|
||
{
|
||
change_annotation_level ();
|
||
}
|
||
|
||
/* Called by do_setshow_command. */
|
||
/* ARGSUSED */
|
||
void
|
||
set_async_prompt (char *args, int from_tty, struct cmd_list_element *c)
|
||
{
|
||
PROMPT (0) = savestring (new_async_prompt, strlen (new_async_prompt));
|
||
}
|
||
|
||
/* 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. */
|
||
void
|
||
_initialize_event_loop (void)
|
||
{
|
||
if (event_loop_p)
|
||
{
|
||
/* If the input stream is connected to a terminal, turn on
|
||
editing. */
|
||
if (ISATTY (instream))
|
||
{
|
||
/* 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;
|
||
|
||
/* When a character is detected on instream by select or
|
||
poll, readline will be invoked via this callback
|
||
function. */
|
||
call_readline = rl_callback_read_char_wrapper;
|
||
}
|
||
else
|
||
{
|
||
async_command_editing_p = 0;
|
||
call_readline = gdb_readline2;
|
||
}
|
||
|
||
/* When readline has read an end-of-line character, it passes
|
||
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. */
|
||
rl_instream = instream;
|
||
|
||
/* Get a file descriptor for the input stream, so that we can
|
||
register it with the event loop. */
|
||
input_fd = fileno (instream);
|
||
|
||
/* Tell gdb to use the cli_command_loop as the main loop. */
|
||
command_loop_hook = cli_command_loop;
|
||
|
||
/* 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 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. */
|
||
add_file_handler (input_fd, stdin_event_handler, 0);
|
||
}
|
||
}
|