/* Top level stuff for GDB, the GNU debugger.
Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
- 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
- Free Software Foundation, Inc.
+ 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
+ 2008, 2009 Free Software Foundation, Inc.
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
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
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., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA. */
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
#include "gdbcmd.h"
#include "gdb_assert.h"
#include "main.h"
#include "event-loop.h"
+#include "gdbthread.h"
/* readline include files */
#include "readline/readline.h"
int epoch_interface;
int xgdb_verbose;
-/* gdb prints this when reading a command interactively */
-static char *gdb_prompt_string; /* the global prompt string */
-
/* Buffer used for reading command lines, and the size
allocated for it so far. */
int remote_debug = 0;
-/* Non-zero means the target is running. Note: this is different from
- saying that there is an active target and we are stopped at a
- breakpoint, for instance. This is a real indicator whether the
- target is off and running, which gdb is doing something else. */
-int target_executing = 0;
-
/* Sbrk location on entry to main. Used for statistics only. */
#ifdef HAVE_SBRK
char *lim_at_start;
char *(*deprecated_readline_hook) (char *);
void (*deprecated_readline_end_hook) (void);
-/* Called as appropriate to notify the interface of the specified breakpoint
- conditions. */
-
-void (*deprecated_create_breakpoint_hook) (struct breakpoint * bpt);
-void (*deprecated_delete_breakpoint_hook) (struct breakpoint * bpt);
-void (*deprecated_modify_breakpoint_hook) (struct breakpoint * bpt);
-
/* Called as appropriate to notify the interface that we have attached
to or detached from an already running process. */
void (*deprecated_context_hook) (int id);
-/* Takes control from error (). Typically used to prevent longjmps out of the
- middle of the GUI. Usually used in conjunction with a catch routine. */
-
-void (*deprecated_error_hook) (void);
-
/* Handler for SIGHUP. */
#ifdef SIGHUP
/* Execute the line P as a command.
Pass FROM_TTY as second argument to the defining function. */
+/* Execute command P, in the current user context. */
+
void
execute_command (char *p, int from_tty)
{
enum language flang;
static int warned = 0;
char *line;
+ long time_at_cmd_start = 0;
+#ifdef HAVE_SBRK
+ long space_at_cmd_start = 0;
+#endif
+ extern int display_time;
+ extern int display_space;
+
+ if (target_can_async_p ())
+ {
+ time_at_cmd_start = get_run_time ();
+
+ if (display_space)
+ {
+#ifdef HAVE_SBRK
+ char *lim = (char *) sbrk (0);
+ space_at_cmd_start = lim - lim_at_start;
+#endif
+ }
+ }
free_all_values ();
if (p == NULL)
return;
- serial_log_command (p);
+ target_log_command (p);
while (*p == ' ' || *p == '\t')
p++;
c = lookup_cmd (&p, cmdlist, "", 0, 1);
- /* If the target is running, we allow only a limited set of
- commands. */
- if (target_can_async_p () && target_executing)
- if (strcmp (c->name, "help") != 0
- && strcmp (c->name, "pwd") != 0
- && strcmp (c->name, "show") != 0
- && strcmp (c->name, "stop") != 0)
- error (_("Cannot execute this command while the target is running."));
+ /* If the selected thread has terminated, we allow only a
+ limited set of commands. */
+ if (target_can_async_p ()
+ && is_exited (inferior_ptid)
+ && !get_cmd_no_selected_thread_ok (c))
+ error (_("\
+Cannot execute this command without a live selected thread. See `help thread'."));
/* Pass null arg rather than an empty one. */
arg = *p ? p : 0;
/* FIXME: This should be cacheing the frame and only running when
the frame changes. */
- if (target_has_stack)
+ if (target_has_stack && is_stopped (inferior_ptid))
{
flang = get_frame_language ();
if (!warned
}
execute_command (command, instream == stdin);
- /* Do any commands attached to breakpoint we stopped at. */
- bpstat_do_actions (&stop_bpstat);
+
+ /* Do any commands attached to breakpoint we are stopped at. */
+ bpstat_do_actions ();
+
do_cleanups (old_chain);
if (display_time)
long space_now = lim - lim_at_start;
long space_diff = space_now - space_at_cmd_start;
- printf_unfiltered (_("Space used: %ld (%c%ld for this command)\n"),
+ printf_unfiltered (_("Space used: %ld (%s%ld for this command)\n"),
space_now,
- (space_diff >= 0 ? '+' : '-'),
+ (space_diff >= 0 ? "+" : ""),
space_diff);
#endif
}
}
}
-
-/* Read commands from `instream' and execute them until end of file or
- error reading instream. This command loop doesnt care about any
- such things as displaying time and space usage. If the user asks
- for those, they won't work. */
-void
-simplified_command_loop (char *(*read_input_func) (char *),
- void (*execute_command_func) (char *, int))
-{
- struct cleanup *old_chain;
- char *command;
- int stdin_is_tty = ISATTY (stdin);
-
- while (instream && !feof (instream))
- {
- quit_flag = 0;
- if (instream == stdin && stdin_is_tty)
- reinitialize_more_filter ();
- old_chain = make_cleanup (null_cleanup, 0);
-
- /* Get a command-line. */
- command = (*read_input_func) (instream == stdin ?
- get_prompt () : (char *) NULL);
-
- if (command == 0)
- return;
-
- (*execute_command_func) (command, instream == stdin);
-
- /* Do any commands attached to breakpoint we stopped at. */
- bpstat_do_actions (&stop_bpstat);
-
- do_cleanups (old_chain);
- }
-}
\f
/* Commands call this if they do not want to be repeated by null lines. */
/* Prevent operate-and-get-next from acting too early. */
saved_after_char_processing_hook = after_char_processing_hook;
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. */
+ if (async_command_editing_p)
+ rl_callback_handler_remove ();
}
struct gdb_readline_wrapper_cleanup
{
void (*handler_orig) (char *);
- char *prompt_orig;
int already_prompted_orig;
};
struct gdb_readline_wrapper_cleanup *cleanup = arg;
rl_already_prompted = cleanup->already_prompted_orig;
- PROMPT (0) = cleanup->prompt_orig;
gdb_assert (input_handler == gdb_readline_wrapper_line);
input_handler = cleanup->handler_orig;
cleanup->handler_orig = input_handler;
input_handler = gdb_readline_wrapper_line;
- cleanup->prompt_orig = get_prompt ();
- PROMPT (0) = prompt;
cleanup->already_prompted_orig = rl_already_prompted;
back_to = make_cleanup (gdb_readline_wrapper_cleanup, cleanup);
/* Display our prompt and prevent double prompt display. */
- display_gdb_prompt (NULL);
+ display_gdb_prompt (prompt);
rl_already_prompted = 1;
if (after_char_processing_hook)
}
strcpy (linebuffer, history_value);
p = linebuffer + strlen (linebuffer);
- xfree (history_value);
}
+ xfree (history_value);
}
/* If we just got an empty line, and that is supposed
program to parse, and is just canonical program name and version
number, which starts after last space. */
- fprintf_filtered (stream, "GNU gdb %s\n", version);
+ fprintf_filtered (stream, "GNU gdb %s%s\n", PKGVERSION, version);
/* Second line is a copyright notice. */
- fprintf_filtered (stream, "Copyright (C) 2007 Free Software Foundation, Inc.\n");
+ fprintf_filtered (stream, "Copyright (C) 2009 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
there is no warranty. */
fprintf_filtered (stream, "\
-GDB is free software, covered by the GNU General Public License, and you are\n\
-welcome to change it and/or distribute copies of it under certain conditions.\n\
-Type \"show copying\" to see the conditions.\n\
-There is absolutely no warranty for GDB. Type \"show warranty\" for details.\n");
+License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\n\
+This is free software: you are free to change and redistribute it.\n\
+There is NO WARRANTY, to the extent permitted by law. Type \"show copying\"\n\
+and \"show warranty\" for details.\n");
/* After the required info we print the configuration information. */
fprintf_filtered (stream, "%s", host_name);
}
fprintf_filtered (stream, "\".");
+
+ if (REPORT_BUGS_TO[0])
+ {
+ fprintf_filtered (stream,
+ _("\nFor bug reporting instructions, please see:\n"));
+ fprintf_filtered (stream, "%s.", REPORT_BUGS_TO);
+ }
}
\f
/* get_prompt: access method for the GDB prompt string. */
if (! ptid_equal (inferior_ptid, null_ptid) && target_has_execution)
{
char *s;
+ struct inferior *inf = current_inferior ();
/* 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)
s = "A debugging session is active.\nDo you still want to close the debugger?";
- else if (attach_flag)
+ else if (inf->attach_flag)
s = "The program is running. Quit anyway (and detach it)? ";
else
- s = "The program is running. Exit anyway? ";
+ s = "The program is running. Quit anyway (and kill it)? ";
if (!query ("%s", s))
return 0;
return 1;
}
-/* Helper routine for quit_force that requires error handling. */
-
struct qt_args
{
char *args;
int from_tty;
};
+/* Callback for iterate_over_threads. Finds any thread of inferior
+ given by ARG (really an int*). */
+
static int
-quit_target (void *arg)
+any_thread_of (struct thread_info *thread, void *arg)
{
- struct qt_args *qt = (struct qt_args *)arg;
+ int pid = * (int *)arg;
- if (! ptid_equal (inferior_ptid, null_ptid) && target_has_execution)
+ if (PIDGET (thread->ptid) == pid)
+ return 1;
+
+ return 0;
+}
+
+/* Callback for iterate_over_inferiors. Kills or detaches the given
+ inferior, depending on how we originally gained control of it. */
+
+static int
+kill_or_detach (struct inferior *inf, void *args)
+{
+ struct qt_args *qt = args;
+ struct thread_info *thread;
+
+ thread = iterate_over_threads (any_thread_of, &inf->pid);
+ if (thread)
{
- if (attach_flag)
- target_detach (qt->args, qt->from_tty);
+ switch_to_thread (thread->ptid);
+ if (inf->attach_flag)
+ target_detach (qt->args, qt->from_tty);
else
- target_kill ();
+ target_kill ();
}
- /* UDI wants this, to kill the TIP. */
- target_close (¤t_target, 1);
+ return 0;
+}
+
+/* Helper routine for quit_force that requires error handling. */
+
+static int
+quit_target (void *arg)
+{
+ 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 (1);
/* Save the history information if it is appropriate to do so. */
if (write_history_p && history_filename)
/* Run the init function of each source file */
- getcwd (gdb_dirbuf, sizeof (gdb_dirbuf));
- current_directory = gdb_dirbuf;
-
#ifdef __MSDOS__
/* Make sure we return to the original directory upon exit, come
what may, since the OS doesn't do that for us. */