X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Ftop.c;h=a34635b8b508aaa0e8c635bf54eddb0797b91143;hb=79aa2fe86f105fae162f780f760d655f212eaeb6;hp=e2c4c61c64a9e4646d3431c3d00377cd22d0e473;hpb=840a9a1f86976823f24d53d0a9bf8ab41591868c;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/top.c b/gdb/top.c index e2c4c61c64..a34635b8b5 100644 --- a/gdb/top.c +++ b/gdb/top.c @@ -1,6 +1,6 @@ /* Top level stuff for GDB, the GNU debugger. - Copyright (C) 1986-2013 Free Software Foundation, Inc. + Copyright (C) 1986-2016 Free Software Foundation, Inc. This file is part of GDB. @@ -25,9 +25,10 @@ #include "cli/cli-decode.h" #include "symtab.h" #include "inferior.h" -#include "exceptions.h" +#include "infrun.h" #include #include "target.h" +#include "target-dcache.h" #include "breakpoint.h" #include "gdbtypes.h" #include "expression.h" @@ -40,14 +41,17 @@ #include "version.h" #include "serial.h" #include "doublest.h" -#include "gdb_assert.h" #include "main.h" #include "event-loop.h" #include "gdbthread.h" -#include "python/python.h" +#include "extension.h" #include "interps.h" #include "observer.h" #include "maint.h" +#include "filenames.h" +#include "frame.h" +#include "buffer.h" +#include "gdb_select.h" /* readline include files. */ #include "readline/readline.h" @@ -59,11 +63,16 @@ #include #include "event-top.h" -#include "gdb_string.h" -#include "gdb_stat.h" +#include #include #include "ui-out.h" #include "cli-out.h" +#include "tracepoint.h" +#include "inf-loop.h" + +#if defined(TUI) +# include "tui/tui.h" +#endif extern void initialize_all_files (void); @@ -77,27 +86,26 @@ extern void initialize_all_files (void); #define DEFAULT_PROMPT "(gdb) " #endif -/* Initialization file name for gdb. This is overridden in some configs. */ +/* Generate a function that exports a pointer to a field of the + current UI. */ -#ifndef PATH_MAX -# ifdef FILENAME_MAX -# define PATH_MAX FILENAME_MAX -# else -# define PATH_MAX 512 -# endif -#endif +#define gen_ret_current_ui_field_ptr(type, name) \ +type * \ +current_ui_## name ## _ptr (void) \ +{ \ + return ¤t_ui->m_ ## name; \ +} -#ifndef GDBINIT_FILENAME -#define GDBINIT_FILENAME ".gdbinit" -#endif -char gdbinit[PATH_MAX + 1] = GDBINIT_FILENAME; +gen_ret_current_ui_field_ptr (struct ui_file *, gdb_stdout) +gen_ret_current_ui_field_ptr (struct ui_file *, gdb_stdin) +gen_ret_current_ui_field_ptr (struct ui_file *, gdb_stderr) +gen_ret_current_ui_field_ptr (struct ui_file *, gdb_stdlog) -int inhibit_gdbinit = 0; +/* Initialization file name for gdb. This is host-dependent. */ -/* If nonzero, and GDB has been configured to be able to use windows, - attempt to open them upon startup. */ +const char gdbinit[] = GDBINIT; -int use_windows = 0; +int inhibit_gdbinit = 0; extern char lang_frame_mismatch_warn[]; /* language.c */ @@ -133,17 +141,9 @@ char *current_directory; /* The directory name is actually stored here (usually). */ char gdb_dirbuf[1024]; -/* Function to call before reading a command, if nonzero. - The function receives two args: an input stream, - and a prompt string. */ - -void (*window_hook) (FILE *, char *); - -/* Buffer used for reading command lines, and the size - allocated for it so far. */ - +/* The last command line executed on the console. Used for command + repetitions. */ char *saved_command_line; -int saved_command_line_size = 100; /* Nonzero if the current command is modified by "server ". This affects things like recording into the command history, commands @@ -153,13 +153,6 @@ int saved_command_line_size = 100; is issuing commands too. */ 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. */ - -int baud_rate = -1; - /* Timeout limit for response from target. */ /* The default value has been changed many times over the years. It @@ -193,14 +186,6 @@ char *lim_at_start; /* Hooks for alternate command interfaces. */ -/* 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. */ - -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 @@ -208,11 +193,6 @@ void (*deprecated_init_ui_hook) (char *argv0); int (*deprecated_ui_loop_hook) (int); -/* Called instead of command_loop at top level. Can be invoked via - throw_exception(). */ - -void (*deprecated_command_loop_hook) (void); - /* Called from print_frame_info to list the line we stopped in. */ @@ -241,7 +221,7 @@ void (*deprecated_warning_hook) (const char *, va_list); window and it can close it. */ void (*deprecated_readline_begin_hook) (char *, ...); -char *(*deprecated_readline_hook) (char *); +char *(*deprecated_readline_hook) (const char *); void (*deprecated_readline_end_hook) (void); /* Called as appropriate to notify the interface that we have attached @@ -255,11 +235,6 @@ void (*deprecated_detach_hook) (void); 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). */ -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. */ @@ -273,11 +248,6 @@ ptid_t (*deprecated_target_wait_hook) (ptid_t ptid, 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. */ - -void (*deprecated_set_hook) (struct cmd_list_element * c); - /* Called when the current thread changes. Argument is thread id. */ void (*deprecated_context_hook) (int id); @@ -317,7 +287,7 @@ void do_restore_instream_cleanup (void *stream) { /* Restore the previous input stream. */ - instream = stream; + instream = (FILE *) stream; } /* Read commands from STREAM. */ @@ -328,7 +298,21 @@ read_command_file (FILE *stream) cleanups = make_cleanup (do_restore_instream_cleanup, instream); instream = stream; - command_loop (); + + /* Read commands from `instream' and execute them until end of file + or error reading instream. */ + + while (instream != NULL && !feof (instream)) + { + char *command; + + /* Get a command-line. This calls the readline package. */ + command = command_line_input (NULL, 0, NULL); + if (command == NULL) + break; + command_handler (command); + } + do_cleanups (cleanups); } @@ -369,10 +353,11 @@ void check_frame_language_change (void) { static int warned = 0; + struct frame_info *frame; /* First make sure that a new frame has been selected, in case the command or the hooks changed the program state. */ - deprecated_safe_get_selected_frame (); + frame = deprecated_safe_get_selected_frame (); if (current_language != expected_language) { if (language_mode == language_mode_auto && info_verbose) @@ -392,7 +377,7 @@ check_frame_language_change (void) { enum language flang; - flang = get_frame_language (); + flang = get_frame_language (frame); if (!warned && flang != language_unknown && flang != current_language->la_language) @@ -403,6 +388,29 @@ check_frame_language_change (void) } } +/* See top.h. */ + +void +wait_sync_command_done (void) +{ + while (gdb_do_one_event () >= 0) + if (!sync_execution) + break; +} + +/* See top.h. */ + +void +maybe_wait_sync_command_done (int was_sync) +{ + /* If the interpreter is in sync mode (we're running a user + command's list, running command hooks or similars), and we + just ran a synchronous command that started the target, wait + for that command to end. */ + if (!interpreter_async && !was_sync && sync_execution) + wait_sync_command_done (); +} + /* Execute the line P as a command, in the current user context. Pass FROM_TTY as second argument to the defining function. */ @@ -424,6 +432,7 @@ execute_command (char *p, int from_tty) if (p == NULL) { do_cleanups (cleanup); + discard_cleanups (cleanup_if_error); return; } @@ -435,6 +444,8 @@ execute_command (char *p, int from_tty) { const char *cmd = p; char *arg; + int was_sync = sync_execution; + line = p; /* If trace-commands is set then this will print this command. */ @@ -469,11 +480,11 @@ execute_command (char *p, int from_tty) /* If this command has been pre-hooked, run the hook first. */ execute_cmd_pre_hook (c); - if (c->flags & DEPRECATED_WARN_USER) + if (c->deprecated_warn_user) deprecated_cmd_warning (line); /* c->user_commands would be NULL in the case of a python command. */ - if (c->class == class_user && c->user_commands) + if (c->theclass == class_user && c->user_commands) execute_user_command (c, arg); else if (c->type == set_cmd) do_set_command (arg, from_tty, c); @@ -486,16 +497,7 @@ execute_command (char *p, int from_tty) else cmd_func (c, arg, from_tty); - /* If the interpreter is in sync mode (we're running a user - command's list, running command hooks or similars), and we - just ran a synchronous command that started the target, wait - for that command to end. */ - if (!interpreter_async && sync_execution) - { - while (gdb_do_one_event () >= 0) - if (!sync_execution) - break; - } + maybe_wait_sync_command_done (was_sync); /* If this command has been post-hooked, run the hook last. */ execute_cmd_post_hook (c); @@ -555,46 +557,6 @@ execute_command_to_string (char *p, int from_tty) return retval; } -/* Read commands from `instream' and execute them - until end of file or error reading instream. */ - -void -command_loop (void) -{ - struct cleanup *old_chain; - char *command; - int stdin_is_tty = ISATTY (stdin); - - while (instream && !feof (instream)) - { - if (window_hook && instream == stdin) - (*window_hook) (instream, get_prompt ()); - - clear_quit_flag (); - if (instream == stdin && stdin_is_tty) - reinitialize_more_filter (); - old_chain = make_cleanup (null_cleanup, 0); - - /* Get a command-line. This calls the readline package. */ - command = command_line_input (instream == stdin ? - get_prompt () : (char *) NULL, - instream == stdin, "prompt"); - if (command == 0) - { - do_cleanups (old_chain); - return; - } - - make_command_stats_cleanup (1); - - execute_command (command, instream == stdin); - - /* Do any commands attached to breakpoint we are stopped at. */ - bpstat_do_actions (); - - do_cleanups (old_chain); - } -} /* When nonzero, cause dont_repeat to do nothing. This should only be set via prevent_dont_repeat. */ @@ -631,64 +593,80 @@ prevent_dont_repeat (void) /* Read a line from the stream "instream" without command line editing. - It prints PROMPT_ARG once at the start. + It prints PROMPT once at the start. Action is compatible with "readline", e.g. space for the result is malloc'd and should be freed by the caller. A NULL return means end of file. */ -char * -gdb_readline (char *prompt_arg) + +static char * +gdb_readline_no_editing (const char *prompt) { - int c; - char *result; - int input_index = 0; - int result_size = 80; + struct buffer line_buffer; + /* Read from stdin if we are executing a user defined command. This + is the right thing for prompt_for_continue, at least. */ + FILE *stream = instream != NULL ? instream : stdin; + int fd = fileno (stream); + + buffer_init (&line_buffer); - if (prompt_arg) + if (prompt != NULL) { /* 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 (prompt_arg, gdb_stdout); + fputs_unfiltered (prompt, gdb_stdout); gdb_flush (gdb_stdout); } - result = (char *) xmalloc (result_size); - 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); + int c; + int numfds; + fd_set readfds; + + QUIT; + + /* Wait until at least one byte of data is available. Control-C + can interrupt interruptible_select, but not fgetc. */ + FD_ZERO (&readfds); + FD_SET (fd, &readfds); + if (interruptible_select (fd + 1, &readfds, NULL, NULL, NULL) == -1) + { + if (errno == EINTR) + { + /* If this was ctrl-c, the QUIT above handles it. */ + continue; + } + perror_with_name (("select")); + } + + c = fgetc (stream); if (c == EOF) { - if (input_index > 0) + if (line_buffer.used_size > 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; - xfree (result); + xfree (buffer_finish (&line_buffer)); return NULL; } if (c == '\n') { - if (input_index > 0 && result[input_index - 1] == '\r') - input_index--; + if (line_buffer.used_size > 0 + && line_buffer.buffer[line_buffer.used_size - 1] == '\r') + line_buffer.used_size--; break; } - result[input_index++] = c; - while (input_index >= result_size) - { - result_size *= 2; - result = (char *) xrealloc (result, result_size); - } + buffer_grow_char (&line_buffer, c); } - result[input_index++] = '\0'; - return result; + buffer_grow_char (&line_buffer, '\0'); + return buffer_finish (&line_buffer); } /* Variables which control command line editing and history @@ -712,8 +690,8 @@ show_write_history_p (struct ui_file *file, int from_tty, } /* The variable associated with the "set/show history size" - command. */ -static unsigned int history_size_setshow_var; + command. The value -1 means unlimited, and -2 means undefined. */ +static int history_size_setshow_var = -2; static void show_history_size (struct ui_file *file, int from_tty, @@ -723,6 +701,20 @@ show_history_size (struct ui_file *file, int from_tty, value); } +/* Variable associated with the "history remove-duplicates" option. + The value -1 means unlimited. */ +static int history_remove_duplicates = 0; + +static void +show_history_remove_duplicates (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) +{ + fprintf_filtered (file, + _("The number of history entries to look back at for " + "duplicates is %s.\n"), + value); +} + static char *history_filename; static void show_history_filename (struct ui_file *file, int from_tty, @@ -764,6 +756,21 @@ static char *gdb_readline_wrapper_result; return. */ static void (*saved_after_char_processing_hook) (void); + +/* The number of nested readline secondary prompts that are currently + active. */ + +static int gdb_secondary_prompt_depth = 0; + +/* See top.h. */ + +int +gdb_in_secondary_prompt_p (void) +{ + return gdb_secondary_prompt_depth > 0; +} + + /* This function is called when readline has seen a complete line of text. */ @@ -779,50 +786,81 @@ gdb_readline_wrapper_line (char *line) after_char_processing_hook = NULL; /* Prevent parts of the prompt from being redisplayed if annotations - are enabled, and readline's state getting out of sync. */ + are enabled, and readline's state getting out of sync. We'll + reinstall the callback handler, which puts the terminal in raw + mode (or in readline lingo, in prepped state), when we're next + ready to process user input, either in display_gdb_prompt, or if + we're handling an asynchronous target event and running in the + background, just before returning to the event loop to process + further input (or more target events). */ if (async_command_editing_p) - rl_callback_handler_remove (); + gdb_rl_callback_handler_remove (); } struct gdb_readline_wrapper_cleanup { void (*handler_orig) (char *); int already_prompted_orig; + + /* Whether the target was async. */ + int target_is_async_orig; }; static void gdb_readline_wrapper_cleanup (void *arg) { - struct gdb_readline_wrapper_cleanup *cleanup = arg; + struct ui *ui = current_ui; + struct gdb_readline_wrapper_cleanup *cleanup + = (struct gdb_readline_wrapper_cleanup *) arg; rl_already_prompted = cleanup->already_prompted_orig; - gdb_assert (input_handler == gdb_readline_wrapper_line); - input_handler = cleanup->handler_orig; + gdb_assert (ui->input_handler == gdb_readline_wrapper_line); + ui->input_handler = cleanup->handler_orig; + + /* Don't restore our input handler in readline yet. That would make + readline prep the terminal (putting it in raw mode), while the + line we just read may trigger execution of a command that expects + the terminal in the default cooked/canonical mode, such as e.g., + running Python's interactive online help utility. See + gdb_readline_wrapper_line for when we'll reinstall it. */ + gdb_readline_wrapper_result = NULL; gdb_readline_wrapper_done = 0; + gdb_secondary_prompt_depth--; + gdb_assert (gdb_secondary_prompt_depth >= 0); after_char_processing_hook = saved_after_char_processing_hook; saved_after_char_processing_hook = NULL; + if (cleanup->target_is_async_orig) + target_async (1); + xfree (cleanup); } char * -gdb_readline_wrapper (char *prompt) +gdb_readline_wrapper (const char *prompt) { + struct ui *ui = current_ui; struct cleanup *back_to; struct gdb_readline_wrapper_cleanup *cleanup; char *retval; - cleanup = xmalloc (sizeof (*cleanup)); - cleanup->handler_orig = input_handler; - input_handler = gdb_readline_wrapper_line; + cleanup = XNEW (struct gdb_readline_wrapper_cleanup); + cleanup->handler_orig = ui->input_handler; + ui->input_handler = gdb_readline_wrapper_line; cleanup->already_prompted_orig = rl_already_prompted; + cleanup->target_is_async_orig = target_is_async_p (); + + gdb_secondary_prompt_depth++; back_to = make_cleanup (gdb_readline_wrapper_cleanup, cleanup); + if (cleanup->target_is_async_orig) + target_async (0); + /* Display our prompt and prevent double prompt display. */ display_gdb_prompt (prompt); rl_already_prompted = 1; @@ -887,33 +925,130 @@ gdb_rl_operate_and_get_next (int count, int key) return rl_newline (1, key); } - -/* Read one line from the command input stream `instream' - into the local static buffer `linebuffer' (whose current length - is `linelength'). - The buffer is made bigger as necessary. - Returns the address of the start of the line. + +/* Number of user commands executed during this session. */ + +static int command_count = 0; + +/* Add the user command COMMAND to the input history list. */ + +void +gdb_add_history (const char *command) +{ + command_count++; + + if (history_remove_duplicates != 0) + { + int lookbehind; + int lookbehind_threshold; + + /* The lookbehind threshold for finding a duplicate history entry is + bounded by command_count because we can't meaningfully delete + history entries that are already stored in the history file since + the history file is appended to. */ + if (history_remove_duplicates == -1 + || history_remove_duplicates > command_count) + lookbehind_threshold = command_count; + else + lookbehind_threshold = history_remove_duplicates; + + using_history (); + for (lookbehind = 0; lookbehind < lookbehind_threshold; lookbehind++) + { + HIST_ENTRY *temp = previous_history (); + + if (temp == NULL) + break; + + if (strcmp (temp->line, command) == 0) + { + HIST_ENTRY *prev = remove_history (where_history ()); + command_count--; + free_history_entry (prev); + break; + } + } + using_history (); + } + + add_history (command); +} + +/* Safely append new history entries to the history file in a corruption-free + way using an intermediate local history file. */ + +static void +gdb_safe_append_history (void) +{ + int ret, saved_errno; + char *local_history_filename; + struct cleanup *old_chain; + + local_history_filename + = xstrprintf ("%s-gdb%d~", history_filename, getpid ()); + old_chain = make_cleanup (xfree, local_history_filename); + + ret = rename (history_filename, local_history_filename); + saved_errno = errno; + if (ret < 0 && saved_errno != ENOENT) + { + warning (_("Could not rename %s to %s: %s"), + history_filename, local_history_filename, + safe_strerror (saved_errno)); + } + else + { + if (ret < 0) + { + /* If the rename failed with ENOENT then either the global history + file never existed in the first place or another GDB process is + currently appending to it (and has thus temporarily renamed it). + Since we can't distinguish between these two cases, we have to + conservatively assume the first case and therefore must write out + (not append) our known history to our local history file and try + to move it back anyway. Otherwise a global history file would + never get created! */ + gdb_assert (saved_errno == ENOENT); + write_history (local_history_filename); + } + else + { + append_history (command_count, local_history_filename); + if (history_is_stifled ()) + history_truncate_file (local_history_filename, history_max_entries); + } + + ret = rename (local_history_filename, history_filename); + saved_errno = errno; + if (ret < 0 && saved_errno != EEXIST) + warning (_("Could not rename %s to %s: %s"), + local_history_filename, history_filename, + safe_strerror (saved_errno)); + } + + do_cleanups (old_chain); +} + +/* Read one line from the command input stream `instream' into a local + static buffer. The buffer is made bigger as necessary. Returns + the address of the start of the line. NULL is returned for end of file. - *If* the instream == stdin & stdin is a terminal, the line read - is copied into the file line saver (global var char *line, - length linesize) so that it can be duplicated. + *If* the instream == stdin & stdin is a terminal, the line read is + copied into the global 'saved_command_line' so that it can be + repeated. - This routine either uses fancy command line editing or - simple input as the user has requested. */ + This routine either uses fancy command line editing or simple input + as the user has requested. */ char * -command_line_input (char *prompt_arg, int repeat, char *annotation_suffix) +command_line_input (const char *prompt_arg, int repeat, char *annotation_suffix) { - static char *linebuffer = 0; - static unsigned linelength = 0; - char *p; - char *p1; - char *rl; - char *local_prompt = prompt_arg; - char *nline; - char got_eof = 0; + static struct buffer cmd_line_buffer; + static int cmd_line_buffer_initialized; + const char *prompt = prompt_arg; + char *cmd; /* The annotation suffix must be non-NULL. */ if (annotation_suffix == NULL) @@ -921,29 +1056,31 @@ command_line_input (char *prompt_arg, int repeat, char *annotation_suffix) if (annotation_level > 1 && instream == stdin) { - local_prompt = alloca ((prompt_arg == NULL ? 0 : strlen (prompt_arg)) - + strlen (annotation_suffix) + 40); - if (prompt_arg == NULL) + char *local_prompt; + + local_prompt + = (char *) alloca ((prompt == NULL ? 0 : strlen (prompt)) + + strlen (annotation_suffix) + 40); + if (prompt == NULL) local_prompt[0] = '\0'; else - strcpy (local_prompt, prompt_arg); + strcpy (local_prompt, prompt); strcat (local_prompt, "\n\032\032"); strcat (local_prompt, annotation_suffix); strcat (local_prompt, "\n"); + + prompt = local_prompt; } - if (linebuffer == 0) + if (!cmd_line_buffer_initialized) { - linelength = 80; - linebuffer = (char *) xmalloc (linelength); + buffer_init (&cmd_line_buffer); + cmd_line_buffer_initialized = 1; } - p = linebuffer; + /* Starting a new command line. */ + cmd_line_buffer.used_size = 0; - /* Control-C quits instantly if typed while in this loop - since it should not wait until the user types a newline. */ - immediate_quit++; - QUIT; #ifdef STOP_SIGNAL if (job_control) signal (STOP_SIGNAL, handle_stop_sig); @@ -951,6 +1088,8 @@ command_line_input (char *prompt_arg, int repeat, char *annotation_suffix) while (1) { + char *rl; + /* 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. */ @@ -971,142 +1110,36 @@ command_line_input (char *prompt_arg, int repeat, char *annotation_suffix) /* Don't use fancy stuff if not talking to stdin. */ if (deprecated_readline_hook && input_from_terminal_p ()) { - rl = (*deprecated_readline_hook) (local_prompt); + rl = (*deprecated_readline_hook) (prompt); } else if (command_editing_p && input_from_terminal_p ()) { - rl = gdb_readline_wrapper (local_prompt); + rl = gdb_readline_wrapper (prompt); } else { - rl = gdb_readline (local_prompt); + rl = gdb_readline_no_editing (prompt); } - if (annotation_level > 1 && instream == stdin) + cmd = handle_line_of_input (&cmd_line_buffer, rl, + repeat, annotation_suffix); + if (cmd == (char *) EOF) { - puts_unfiltered ("\n\032\032post-"); - puts_unfiltered (annotation_suffix); - puts_unfiltered ("\n"); - } - - if (!rl || rl == (char *) EOF) - { - got_eof = 1; + cmd = NULL; break; } - 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++; - - xfree (rl); /* Allocated in readline. */ - - if (p == linebuffer || *(p - 1) != '\\') + if (cmd != NULL) break; - p--; /* Put on top of '\'. */ - local_prompt = (char *) 0; + prompt = NULL; } #ifdef STOP_SIGNAL if (job_control) signal (STOP_SIGNAL, SIG_DFL); #endif - immediate_quit--; - - if (got_eof) - return NULL; - -#define SERVER_COMMAND_LENGTH 7 - server_command = - (p - linebuffer > SERVER_COMMAND_LENGTH) - && strncmp (linebuffer, "server ", SERVER_COMMAND_LENGTH) == 0; - 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'; - return linebuffer + SERVER_COMMAND_LENGTH; - } - - /* 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) - { - xfree (history_value); - return command_line_input (prompt_arg, repeat, - annotation_suffix); - } - if (strlen (history_value) > linelength) - { - linelength = strlen (history_value) + 1; - linebuffer = (char *) xrealloc (linebuffer, linelength); - } - strcpy (linebuffer, history_value); - p = linebuffer + strlen (linebuffer); - } - 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 (repeat && p == linebuffer) - return saved_command_line; - for (p1 = linebuffer; *p1 == ' ' || *p1 == '\t'; p1++); - if (repeat && !*p1) - return saved_command_line; - - *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 > saved_command_line_size) - { - saved_command_line = xrealloc (saved_command_line, linelength); - saved_command_line_size = linelength; - } - strcpy (saved_command_line, linebuffer); - return saved_command_line; - } - return linebuffer; + return cmd; } /* Print the GDB banner. */ @@ -1122,7 +1155,7 @@ print_gdb_version (struct ui_file *stream) /* Second line is a copyright notice. */ fprintf_filtered (stream, - "Copyright (C) 2013 Free Software Foundation, Inc.\n"); + "Copyright (C) 2016 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 @@ -1147,14 +1180,121 @@ and \"show warranty\" for details.\n"); { fprintf_filtered (stream, "%s", host_name); } - fprintf_filtered (stream, "\"."); + fprintf_filtered (stream, "\".\n\ +Type \"show configuration\" for configuration details."); if (REPORT_BUGS_TO[0]) { - fprintf_filtered (stream, + fprintf_filtered (stream, _("\nFor bug reporting instructions, please see:\n")); - fprintf_filtered (stream, "%s.", REPORT_BUGS_TO); + fprintf_filtered (stream, "%s.\n", REPORT_BUGS_TO); } + fprintf_filtered (stream, + _("Find the GDB manual and other documentation \ +resources online at:\n.\n")); + fprintf_filtered (stream, _("For help, type \"help\".\n")); + fprintf_filtered (stream, _("Type \"apropos word\" to search for \ +commands related to \"word\".")); +} + +/* Print the details of GDB build-time configuration. */ +void +print_gdb_configuration (struct ui_file *stream) +{ + fprintf_filtered (stream, _("\ +This GDB was configured as follows:\n\ + configure --host=%s --target=%s\n\ +"), host_name, target_name); + fprintf_filtered (stream, _("\ + --with-auto-load-dir=%s\n\ + --with-auto-load-safe-path=%s\n\ +"), AUTO_LOAD_DIR, AUTO_LOAD_SAFE_PATH); +#if HAVE_LIBEXPAT + fprintf_filtered (stream, _("\ + --with-expat\n\ +")); +#else + fprintf_filtered (stream, _("\ + --without-expat\n\ +")); +#endif + if (GDB_DATADIR[0]) + fprintf_filtered (stream, _("\ + --with-gdb-datadir=%s%s\n\ +"), GDB_DATADIR, GDB_DATADIR_RELOCATABLE ? " (relocatable)" : ""); +#ifdef ICONV_BIN + fprintf_filtered (stream, _("\ + --with-iconv-bin=%s%s\n\ +"), ICONV_BIN, ICONV_BIN_RELOCATABLE ? " (relocatable)" : ""); +#endif + if (JIT_READER_DIR[0]) + fprintf_filtered (stream, _("\ + --with-jit-reader-dir=%s%s\n\ +"), JIT_READER_DIR, JIT_READER_DIR_RELOCATABLE ? " (relocatable)" : ""); +#if HAVE_LIBUNWIND_IA64_H + fprintf_filtered (stream, _("\ + --with-libunwind-ia64\n\ +")); +#else + fprintf_filtered (stream, _("\ + --without-libunwind-ia64\n\ +")); +#endif +#if HAVE_LIBLZMA + fprintf_filtered (stream, _("\ + --with-lzma\n\ +")); +#else + fprintf_filtered (stream, _("\ + --without-lzma\n\ +")); +#endif +#ifdef WITH_PYTHON_PATH + fprintf_filtered (stream, _("\ + --with-python=%s%s\n\ +"), WITH_PYTHON_PATH, PYTHON_PATH_RELOCATABLE ? " (relocatable)" : ""); +#endif +#if HAVE_GUILE + fprintf_filtered (stream, _("\ + --with-guile\n\ +")); +#else + fprintf_filtered (stream, _("\ + --without-guile\n\ +")); +#endif +#ifdef RELOC_SRCDIR + fprintf_filtered (stream, _("\ + --with-relocated-sources=%s\n\ +"), RELOC_SRCDIR); +#endif + if (DEBUGDIR[0]) + fprintf_filtered (stream, _("\ + --with-separate-debug-dir=%s%s\n\ +"), DEBUGDIR, DEBUGDIR_RELOCATABLE ? " (relocatable)" : ""); + if (TARGET_SYSTEM_ROOT[0]) + fprintf_filtered (stream, _("\ + --with-sysroot=%s%s\n\ +"), TARGET_SYSTEM_ROOT, TARGET_SYSTEM_ROOT_RELOCATABLE ? " (relocatable)" : ""); + if (SYSTEM_GDBINIT[0]) + fprintf_filtered (stream, _("\ + --with-system-gdbinit=%s%s\n\ +"), SYSTEM_GDBINIT, SYSTEM_GDBINIT_RELOCATABLE ? " (relocatable)" : ""); +#if HAVE_LIBBABELTRACE + fprintf_filtered (stream, _("\ + --with-babeltrace\n\ +")); +#else + fprintf_filtered (stream, _("\ + --without-babeltrace\n\ +")); +#endif + /* We assume "relocatable" will be printed at least once, thus we always + print this text. It's a reasonably safe assumption for now. */ + fprintf_filtered (stream, _("\n\ +(\"Relocatable\" means the directory can be moved with the GDB installation\n\ +tree, and GDB will still find it.)\n\ +")); } @@ -1194,7 +1334,7 @@ struct qt_args static int kill_or_detach (struct inferior *inf, void *args) { - struct qt_args *qt = args; + struct qt_args *qt = (struct qt_args *) args; struct thread_info *thread; if (inf->pid == 0) @@ -1225,7 +1365,7 @@ kill_or_detach (struct inferior *inf, void *args) static int print_inferior_quit_action (struct inferior *inf, void *arg) { - struct ui_file *stb = arg; + struct ui_file *stb = (struct ui_file *) arg; if (inf->pid == 0) return 0; @@ -1261,18 +1401,9 @@ quit_confirm (void) stb = mem_fileopen (); old_chain = make_cleanup_ui_file_delete (stb); - /* This is something of a hack. But there's no reliable way to see - if a GUI is running. The `use_windows' variable doesn't cut - it. */ - if (deprecated_init_ui_hook) - fprintf_filtered (stb, _("A debugging session is active.\n" - "Do you still want to close the debugger?")); - else - { - fprintf_filtered (stb, _("A debugging session is active.\n\n")); - iterate_over_inferiors (print_inferior_quit_action, stb); - fprintf_filtered (stb, _("\nQuit anyway? ")); - } + fprintf_filtered (stb, _("A debugging session is active.\n\n")); + iterate_over_inferiors (print_inferior_quit_action, stb); + fprintf_filtered (stb, _("\nQuit anyway? ")); str = ui_file_xstrdup (stb, NULL); make_cleanup (xfree, str); @@ -1282,29 +1413,21 @@ quit_confirm (void) return qr; } -/* Helper routine for quit_force that requires error handling. */ +/* Prepare to exit GDB cleanly by undoing any changes made to the + terminal so that we leave the terminal in the state we acquired it. */ -static int -quit_target (void *arg) +static void +undo_terminal_modifications_before_exit (void) { - struct qt_args *qt = (struct qt_args *)arg; - - /* Kill or detach all inferiors. */ - iterate_over_inferiors (kill_or_detach, qt); - - /* Give all pushed targets a chance to do minimal cleanup, and pop - them all out. */ - pop_all_targets (); - - /* Save the history information if it is appropriate to do so. */ - if (write_history_p && history_filename) - write_history (history_filename); - - do_final_cleanups (all_cleanups ()); /* Do any final cleanups before - exiting. */ - return 0; + target_terminal_ours (); +#if defined(TUI) + tui_disable (); +#endif + if (async_command_editing_p) + gdb_disable_readline (); } + /* Quit without asking for confirmation. */ void @@ -1313,6 +1436,8 @@ quit_force (char *args, int from_tty) int exit_code = 0; struct qt_args qt; + undo_terminal_modifications_before_exit (); + /* An optional expression may be used to cause gdb to terminate with the value of that expression. */ if (args) @@ -1328,8 +1453,54 @@ quit_force (char *args, int from_tty) qt.from_tty = from_tty; /* We want to handle any quit errors and exit regardless. */ - catch_errors (quit_target, &qt, - "Quitting: ", RETURN_MASK_ALL); + + /* Get out of tfind mode, and kill or detach all inferiors. */ + TRY + { + disconnect_tracing (); + iterate_over_inferiors (kill_or_detach, &qt); + } + CATCH (ex, RETURN_MASK_ALL) + { + exception_print (gdb_stderr, ex); + } + END_CATCH + + /* Give all pushed targets a chance to do minimal cleanup, and pop + them all out. */ + TRY + { + pop_all_targets (); + } + CATCH (ex, RETURN_MASK_ALL) + { + exception_print (gdb_stderr, ex); + } + END_CATCH + + /* Save the history information if it is appropriate to do so. */ + TRY + { + if (write_history_p && history_filename + && input_from_terminal_p ()) + gdb_safe_append_history (); + } + CATCH (ex, RETURN_MASK_ALL) + { + exception_print (gdb_stderr, ex); + } + END_CATCH + + /* Do any final cleanups before exiting. */ + TRY + { + do_final_cleanups (all_cleanups ()); + } + CATCH (ex, RETURN_MASK_ALL) + { + exception_print (gdb_stderr, ex); + } + END_CATCH exit (exit_code); } @@ -1428,34 +1599,26 @@ show_commands (char *args, int from_tty) } } -/* Called by do_setshow_command. */ -static void -set_history_size_command (char *args, int from_tty, struct cmd_list_element *c) -{ - /* Readline's history interface works with 'int', so it can only - handle history sizes up to INT_MAX. The command itself is - uinteger, so UINT_MAX means "unlimited", but we only get that if - the user does "set history size 0" -- "set history size " - throws out-of-range. */ - if (history_size_setshow_var > INT_MAX - && history_size_setshow_var != UINT_MAX) - { - unsigned int new_value = history_size_setshow_var; +/* Update the size of our command history file to HISTORY_SIZE. - /* Restore previous value before throwing. */ - if (history_is_stifled ()) - history_size_setshow_var = history_max_entries; - else - history_size_setshow_var = UINT_MAX; + A HISTORY_SIZE of -1 stands for unlimited. */ - error (_("integer %u out of range"), new_value); - } +static void +set_readline_history_size (int history_size) +{ + gdb_assert (history_size >= -1); - /* Commit the new value to readline's history. */ - if (history_size_setshow_var == UINT_MAX) + if (history_size == -1) unstifle_history (); else - stifle_history (history_size_setshow_var); + stifle_history (history_size); +} + +/* Called by do_setshow_command. */ +static void +set_history_size_command (char *args, int from_tty, struct cmd_list_element *c) +{ + set_readline_history_size (history_size_setshow_var); } void @@ -1463,7 +1626,7 @@ set_history (char *args, int from_tty) { printf_unfiltered (_("\"set history\" must be followed " "by the name of a history subcommand.\n")); - help_list (sethistlist, "set history ", -1, gdb_stdout); + help_list (sethistlist, "set history ", all_commands, gdb_stdout); } void @@ -1506,29 +1669,45 @@ init_history (void) { char *tmpenv; - tmpenv = getenv ("HISTSIZE"); + tmpenv = getenv ("GDBHISTSIZE"); if (tmpenv) { - int var; - - var = atoi (tmpenv); - if (var < 0) - { - /* Prefer ending up with no history rather than overflowing - readline's history interface, which uses signed 'int' - everywhere. */ - var = 0; - } - - history_size_setshow_var = var; + long var; + int saved_errno; + char *endptr; + + tmpenv = skip_spaces (tmpenv); + errno = 0; + var = strtol (tmpenv, &endptr, 10); + saved_errno = errno; + endptr = skip_spaces (endptr); + + /* If GDBHISTSIZE is non-numeric then ignore it. If GDBHISTSIZE is the + empty string, a negative number or a huge positive number (larger than + INT_MAX) then set the history size to unlimited. Otherwise set our + history size to the number we have read. This behavior is consistent + with how bash handles HISTSIZE. */ + if (*endptr != '\0') + ; + else if (*tmpenv == '\0' + || var < 0 + || var > INT_MAX + /* On targets where INT_MAX == LONG_MAX, we have to look at + errno after calling strtol to distinguish between a value that + is exactly INT_MAX and an overflowing value that was clamped + to INT_MAX. */ + || (var == INT_MAX && saved_errno == ERANGE)) + history_size_setshow_var = -1; + else + history_size_setshow_var = var; } - /* If the init file hasn't set a size yet, pick the default. */ - else if (history_size_setshow_var == 0) + + /* If neither the init file nor GDBHISTSIZE has set a size yet, pick the + default. */ + if (history_size_setshow_var == -2) history_size_setshow_var = 256; - /* Note that unlike "set history size 0", "HISTSIZE=0" really sets - the history size to 0... */ - stifle_history (history_size_setshow_var); + set_readline_history_size (history_size_setshow_var); tmpenv = getenv ("GDBHISTFILE"); if (tmpenv) @@ -1582,14 +1761,39 @@ show_exec_done_display_p (struct ui_file *file, int from_tty, value); } +/* New values of the "data-directory" parameter are staged here. */ +static char *staged_gdb_datadir; + /* "set" command for the gdb_datadir configuration variable. */ static void set_gdb_datadir (char *args, int from_tty, struct cmd_list_element *c) { + set_gdb_data_directory (staged_gdb_datadir); observer_notify_gdb_datadir_changed (); } +/* "show" command for the gdb_datadir configuration variable. */ + +static void +show_gdb_datadir (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) +{ + fprintf_filtered (file, _("GDB's data directory is \"%s\".\n"), + gdb_datadir); +} + +static void +set_history_filename (char *args, int from_tty, struct cmd_list_element *c) +{ + /* We include the current directory so that if the user changes + directories the file written will be the same as the one + that was read. */ + if (!IS_ABSOLUTE_PATH (history_filename)) + history_filename = reconcat (history_filename, current_directory, "/", + history_filename, (char *) NULL); +} + static void init_main (void) { @@ -1597,10 +1801,6 @@ init_main (void) the DEFAULT_PROMPT is. */ set_prompt (DEFAULT_PROMPT); - /* Set things up for annotation_level > 1, if the user ever decides - to use it. */ - async_annotation_suffix = "prompt"; - /* Set the important stuff up for command editing. */ command_editing_p = 1; history_expansion_p = 0; @@ -1611,6 +1811,7 @@ init_main (void) rl_completion_entry_function = readline_line_completion_function; rl_completer_word_break_characters = default_word_break_characters (); rl_completer_quote_characters = get_gdb_completer_quote_characters (); + rl_completion_display_matches_hook = cli_display_match_list; rl_readline_name = "gdb"; rl_terminal_name = getenv ("TERM"); @@ -1651,19 +1852,38 @@ Without an argument, saving is enabled."), show_write_history_p, &sethistlist, &showhistlist); - add_setshow_uinteger_cmd ("size", no_class, &history_size_setshow_var, _("\ + add_setshow_zuinteger_unlimited_cmd ("size", no_class, + &history_size_setshow_var, _("\ Set the size of the command history,"), _("\ Show the size of the command history,"), _("\ -ie. the number of previous commands to keep a record of."), +ie. the number of previous commands to keep a record of.\n\ +If set to \"unlimited\", the number of commands kept in the history\n\ +list is unlimited. This defaults to the value of the environment\n\ +variable \"GDBHISTSIZE\", or to 256 if this variable is not set."), set_history_size_command, show_history_size, &sethistlist, &showhistlist); + add_setshow_zuinteger_unlimited_cmd ("remove-duplicates", no_class, + &history_remove_duplicates, _("\ +Set how far back in history to look for and remove duplicate entries."), _("\ +Show how far back in history to look for and remove duplicate entries."), _("\ +If set to a nonzero value N, GDB will look back at the last N history entries\n\ +and remove the first history entry that is a duplicate of the most recent\n\ +entry, each time a new history entry is added.\n\ +If set to \"unlimited\", this lookbehind is unbounded.\n\ +Only history entries added during this session are considered for removal.\n\ +If set to 0, removal of duplicate history entries is disabled.\n\ +By default this option is set to 0."), + NULL, + show_history_remove_duplicates, + &sethistlist, &showhistlist); + add_setshow_filename_cmd ("filename", no_class, &history_filename, _("\ Set the filename in which to record the command history"), _("\ Show the filename in which to record the command history"), _("\ (the list of previous commands of which a record is kept)."), - NULL, + set_history_filename, show_history_filename, &sethistlist, &showhistlist); @@ -1693,11 +1913,11 @@ Use \"on\" to enable the notification, and \"off\" to disable it."), &setlist, &showlist); add_setshow_filename_cmd ("data-directory", class_maintenance, - &gdb_datadir, _("Set GDB's data directory."), + &staged_gdb_datadir, _("Set GDB's data directory."), _("Show GDB's data directory."), _("\ When set, GDB uses the specified path to search for data files."), - set_gdb_datadir, NULL, + set_gdb_datadir, show_gdb_datadir, &setlist, &showlist); } @@ -1720,6 +1940,8 @@ gdb_init (char *argv0) initialize_targets (); /* Setup target_terminal macros for utils.c. */ initialize_utils (); /* Make errors and warnings possible. */ + init_page_info (); + /* Here is where we call all the _initialize_foo routines. */ initialize_all_files (); @@ -1732,11 +1954,14 @@ gdb_init (char *argv0) initialize_inferiors (); initialize_current_architecture (); init_cli_cmds(); - initialize_event_loop (); init_main (); /* But that omits this file! Do it now. */ initialize_stdin_serial (); + /* Take a snapshot of our tty state before readline/ncurses have had a chance + to alter it. */ + set_initial_gdb_ttystate (); + async_init_signals (); /* We need a default language for parsing expressions, so simple @@ -1746,17 +1971,9 @@ gdb_init (char *argv0) set_language (language_c); 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 - deprecated_init_ui_hook. */ - if (deprecated_init_ui_hook) - deprecated_init_ui_hook (argv0); - -#ifdef HAVE_PYTHON - /* Python initialization can require various commands to be + /* Python initialization, for example, 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 + script initialization here. */ + finish_ext_lang_initialization (); }