Refactor 'maint time' command statistics.
[deliverable/binutils-gdb.git] / gdb / top.c
index 9ad2f54a1796347bcda3ec7dbbdfb862823cbc88..93447fe9aa919c9edebf6742b30103ef7a13efb3 100644 (file)
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -2,7 +2,7 @@
 
    Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
    1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
-   2008 Free Software Foundation, Inc.
+   2008, 2009, 2010 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -46,6 +46,7 @@
 #include "gdb_assert.h"
 #include "main.h"
 #include "event-loop.h"
+#include "gdbthread.h"
 
 /* readline include files */
 #include "readline/readline.h"
@@ -131,9 +132,6 @@ void (*window_hook) (FILE *, char *);
 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.  */
 
@@ -181,26 +179,11 @@ int remote_timeout = 2;
 
 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;
 #endif
 
-/* Signal to catch ^Z typed while reading a command: SIGTSTP or SIGCONT.  */
-
-#ifndef STOP_SIGNAL
-#ifdef SIGTSTP
-#define STOP_SIGNAL SIGTSTP
-static void stop_sig (int);
-#endif
-#endif
-
 /* Hooks for alternate command interfaces.  */
 
 /* Called after most modules have been initialized, but before taking users
@@ -251,13 +234,6 @@ void (*deprecated_readline_begin_hook) (char *, ...);
 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. */
 
@@ -274,14 +250,12 @@ void (*deprecated_interactive_hook) (void);
    that several registers have changed (see value_assign). */
 void (*deprecated_register_changed_hook) (int regno);
 
-/* Tell the GUI someone changed LEN bytes of memory at ADDR */
-void (*deprecated_memory_changed_hook) (CORE_ADDR addr, int len);
-
 /* Called when going to wait for the target.  Usually allows the GUI to run
    while waiting for target events.  */
 
 ptid_t (*deprecated_target_wait_hook) (ptid_t ptid,
-                                      struct target_waitstatus * status);
+                                      struct target_waitstatus *status,
+                                      int options);
 
 /* Used by UI as a wrapper around command execution.  May do various things
    like enabling/disabling buttons, etc...  */
@@ -298,11 +272,6 @@ void (*deprecated_set_hook) (struct cmd_list_element * c);
 
 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
@@ -329,7 +298,7 @@ quit_cover (void *s)
 /* NOTE 1999-04-29: This variable will be static again, once we modify
    gdb to use the event loop as the default command loop and we merge
    event-top.c into this file, top.c */
-/* static */ char *source_file_name;
+/* static */ const char *source_file_name;
 
 /* Clean up on error during a "source" command (or execution of a
    user-defined command).  */
@@ -364,7 +333,20 @@ do_chdir_cleanup (void *old_dir)
 }
 #endif
 
-/* Execute the line P as a command.
+void
+prepare_execute_command (void)
+{
+  free_all_values ();
+
+  /* With multiple threads running while the one we're examining is stopped,
+     the dcache can get stale without us being able to detect it.
+     For the duration of the command, though, use the dcache to help
+     things like backtrace.  */
+  if (non_stop)
+    target_dcache_invalidate ();
+}
+
+/* Execute the line P as a command, in the current user context.
    Pass FROM_TTY as second argument to the defining function.  */
 
 void
@@ -374,8 +356,8 @@ execute_command (char *p, int from_tty)
   enum language flang;
   static int warned = 0;
   char *line;
-  
-  free_all_values ();
+
+  prepare_execute_command ();
 
   /* Force cleanup of any alloca areas if using C alloca instead of
      a builtin alloca.  */
@@ -399,15 +381,6 @@ execute_command (char *p, int from_tty)
 
       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."));
-
       /* Pass null arg rather than an empty one.  */
       arg = *p ? p : 0;
 
@@ -453,10 +426,13 @@ execute_command (char *p, int from_tty)
 
     }
 
-  /* Tell the user if the language has changed (except first time).  */
+  /* Tell the user if the language has changed (except first time).
+     First make sure that a new frame has been selected, in case this
+     command or the hooks changed the program state.  */
+  deprecated_safe_get_selected_frame ();
   if (current_language != expected_language)
     {
-      if (language_mode == language_mode_auto)
+      if (language_mode == language_mode_auto && info_verbose)
        {
          language_info (1);    /* Print what changed.  */
        }
@@ -469,7 +445,7 @@ execute_command (char *p, int from_tty)
   /* FIXME:  This should be cacheing the frame and only running when
      the frame changes.  */
 
-  if (target_has_stack)
+  if (has_stack_frames ())
     {
       flang = get_frame_language ();
       if (!warned
@@ -491,12 +467,6 @@ command_loop (void)
   struct cleanup *old_chain;
   char *command;
   int stdin_is_tty = ISATTY (stdin);
-  long time_at_cmd_start;
-#ifdef HAVE_SBRK
-  long space_at_cmd_start = 0;
-#endif
-  extern int display_time;
-  extern int display_space;
 
   while (instream && !feof (instream))
     {
@@ -515,75 +485,12 @@ command_loop (void)
       if (command == 0)
        return;
 
-      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
-       }
+      make_command_stats_cleanup (1);
 
       execute_command (command, instream == stdin);
-      /* Do any commands attached to breakpoint we stopped at.  */
-      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
-         char *lim = (char *) sbrk (0);
-         long space_now = lim - lim_at_start;
-         long space_diff = space_now - space_at_cmd_start;
-
-         printf_unfiltered (_("Space used: %ld (%s%ld for this command)\n"),
-                            space_now,
-                            (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 any commands attached to breakpoint we are stopped at.  */
+      bpstat_do_actions ();
 
       do_cleanups (old_chain);
     }
@@ -814,57 +721,6 @@ gdb_readline_wrapper (char *prompt)
 }
 
 \f
-#ifdef STOP_SIGNAL
-static void
-stop_sig (int signo)
-{
-#if STOP_SIGNAL == SIGTSTP
-  signal (SIGTSTP, SIG_DFL);
-#if HAVE_SIGPROCMASK
-  {
-    sigset_t zero;
-
-    sigemptyset (&zero);
-    sigprocmask (SIG_SETMASK, &zero, 0);
-  }
-#elif HAVE_SIGSETMASK
-  sigsetmask (0);
-#endif
-  kill (getpid (), SIGTSTP);
-  signal (SIGTSTP, stop_sig);
-#else
-  signal (STOP_SIGNAL, stop_sig);
-#endif
-  printf_unfiltered ("%s", get_prompt ());
-  gdb_flush (gdb_stdout);
-
-  /* Forget about any previous command -- null line now will do nothing.  */
-  dont_repeat ();
-}
-#endif /* STOP_SIGNAL */
-
-/* Initialize signal handlers. */
-static void
-float_handler (int signo)
-{
-  /* This message is based on ANSI C, section 4.7.  Note that integer
-     divide by zero causes this, so "float" is a misnomer.  */
-  signal (SIGFPE, float_handler);
-  error (_("Erroneous arithmetic operation."));
-}
-
-static void
-do_nothing (int signo)
-{
-  /* Under System V the default disposition of a signal is reinstated after
-     the signal is caught and delivered to an application process.  On such
-     systems one must restore the replacement signal handler if one wishes
-     to continue handling the signal in one's program.  On BSD systems this
-     is not needed but it is harmless, and it simplifies the code to just do
-     it unconditionally. */
-  signal (signo, do_nothing);
-}
-
 /* The current saved history number from operate-and-get-next.
    This is -1 if not valid.  */
 static int operate_saved_history = -1;
@@ -875,6 +731,7 @@ static void
 gdb_rl_operate_and_get_next_completion (void)
 {
   int delta = where_history () - operate_saved_history;
+
   /* The `key' argument to rl_get_previous_history is ignored.  */
   rl_get_previous_history (delta, 0);
   operate_saved_history = -1;
@@ -1143,11 +1000,11 @@ print_gdb_version (struct ui_file *stream)
      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) 2008 Free Software Foundation, Inc.\n");
+  fprintf_filtered (stream, "Copyright (C) 2010 Free Software Foundation, Inc.\n");
 
   /* Following the copyright is a brief statement that the program is
      free software, that users are free to copy and change it on
@@ -1172,6 +1029,13 @@ and \"show warranty\" for details.\n");
       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.  */
@@ -1186,64 +1050,127 @@ void
 set_prompt (char *s)
 {
 /* ??rehrauer: I don't know why this fails, since it looks as though
-   assignments to prompt are wrapped in calls to savestring...
+   assignments to prompt are wrapped in calls to xstrdup...
    if (prompt != NULL)
    xfree (prompt);
  */
-  PROMPT (0) = savestring (s, strlen (s));
+  PROMPT (0) = xstrdup (s);
 }
 \f
 
+struct qt_args
+{
+  char *args;
+  int from_tty;
+};
+
+/* 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;
+
+  if (inf->pid == 0)
+    return 0;
+
+  thread = any_thread_of_process (inf->pid);
+  if (thread != NULL)
+    {
+      switch_to_thread (thread->ptid);
+
+      /* Leave core files alone.  */
+      if (target_has_execution)
+       {
+         if (inf->attach_flag)
+           target_detach (qt->args, qt->from_tty);
+         else
+           target_kill ();
+       }
+    }
+
+  return 0;
+}
+
+/* Callback for iterate_over_inferiors.  Prints info about what GDB
+   will do to each inferior on a "quit".  ARG points to a struct
+   ui_out where output is to be collected.  */
+
+static int
+print_inferior_quit_action (struct inferior *inf, void *arg)
+{
+  struct ui_file *stb = arg;
+
+  if (inf->pid == 0)
+    return 0;
+
+  if (inf->attach_flag)
+    fprintf_filtered (stb,
+                     _("\tInferior %d [%s] will be detached.\n"), inf->num,
+                     target_pid_to_str (pid_to_ptid (inf->pid)));
+  else
+    fprintf_filtered (stb,
+                     _("\tInferior %d [%s] will be killed.\n"), inf->num,
+                     target_pid_to_str (pid_to_ptid (inf->pid)));
+
+  return 0;
+}
+
 /* If necessary, make the user confirm that we should quit.  Return
    non-zero if we should quit, zero if we shouldn't.  */
 
 int
 quit_confirm (void)
 {
-  if (! ptid_equal (inferior_ptid, null_ptid) && target_has_execution)
-    {
-      char *s;
-
-      /* 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)
-       s = "The program is running.  Quit anyway (and detach it)? ";
-      else
-       s = "The program is running.  Exit anyway? ";
+  struct ui_file *stb;
+  struct cleanup *old_chain;
+  char *str;
+  int qr;
+
+  /* Don't even ask if we're only debugging a core file inferior.  */
+  if (!have_live_inferiors ())
+    return 1;
 
-      if (!query ("%s", s))
-       return 0;
+  /* Build the query string as a single string.  */
+  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? "));
     }
 
-  return 1;
+  str = ui_file_xstrdup (stb, NULL);
+  make_cleanup (xfree, str);
+
+  qr = query ("%s", str);
+  do_cleanups (old_chain);
+  return qr;
 }
 
 /* Helper routine for quit_force that requires error handling.  */
 
-struct qt_args
-{
-  char *args;
-  int from_tty;
-};
-
 static int
 quit_target (void *arg)
 {
   struct qt_args *qt = (struct qt_args *)arg;
 
-  if (! ptid_equal (inferior_ptid, null_ptid) && target_has_execution)
-    {
-      if (attach_flag)
-        target_detach (qt->args, qt->from_tty);
-      else
-        target_kill ();
-    }
+  /* Kill or detach all inferiors.  */
+  iterate_over_inferiors (kill_or_detach, qt);
 
-  /* UDI wants this, to kill the TIP.  */
-  target_close (&current_target, 1);
+  /* 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)
@@ -1283,12 +1210,38 @@ quit_force (char *args, int from_tty)
   exit (exit_code);
 }
 
+/* If OFF, the debugger will run in non-interactive mode, which means
+   that it will automatically select the default answer to all the
+   queries made to the user.  If ON, gdb will wait for the user to
+   answer all queries.  If AUTO, gdb will determine whether to run
+   in interactive mode or not depending on whether stdin is a terminal
+   or not.  */
+static enum auto_boolean interactive_mode = AUTO_BOOLEAN_AUTO;
+
+/* Implement the "show interactive-mode" option.  */
+
+static void
+show_interactive_mode (struct ui_file *file, int from_tty,
+                       struct cmd_list_element *c,
+                       const char *value)
+{
+  if (interactive_mode == AUTO_BOOLEAN_AUTO)
+    fprintf_filtered (file, "\
+Debugger's interactive mode is %s (currently %s).\n",
+                      value, input_from_terminal_p () ? "on" : "off");
+  else
+    fprintf_filtered (file, "Debugger's interactive mode is %s.\n", value);
+}
+
 /* Returns whether GDB is running on a terminal and input is
    currently coming from that terminal.  */
 
 int
 input_from_terminal_p (void)
 {
+  if (interactive_mode != AUTO_BOOLEAN_AUTO)
+    return interactive_mode == AUTO_BOOLEAN_TRUE;
+
   if (gdb_has_a_terminal () && instream == stdin)
     return 1;
 
@@ -1457,7 +1410,7 @@ init_history (void)
 
   tmpenv = getenv ("GDBHISTFILE");
   if (tmpenv)
-    history_filename = savestring (tmpenv, strlen (tmpenv));
+    history_filename = xstrdup (tmpenv);
   else if (!history_filename)
     {
       /* We include the current directory so that if the user changes
@@ -1509,19 +1462,17 @@ Notification of completion for asynchronous execution commands is %s.\n"),
 static void
 init_main (void)
 {
-  struct cmd_list_element *c;
-
   /* initialize the prompt stack to a simple "(gdb) " prompt or to
      whatever the DEFAULT_PROMPT is.  */
   the_prompts.top = 0;
   PREFIX (0) = "";
-  PROMPT (0) = savestring (DEFAULT_PROMPT, strlen (DEFAULT_PROMPT));
+  PROMPT (0) = xstrdup (DEFAULT_PROMPT);
   SUFFIX (0) = "";
   /* Set things up for annotation_level > 1, if the user ever decides
      to use it.  */
   async_annotation_suffix = "prompt";
   /* Set the variable associated with the setshow prompt command.  */
-  new_async_prompt = savestring (PROMPT (0), strlen (PROMPT (0)));
+  new_async_prompt = xstrdup (PROMPT (0));
 
   /* If gdb was started with --annotate=2, this is equivalent to the
      user entering the command 'set annotate 2' at the gdb prompt, so
@@ -1535,6 +1486,7 @@ init_main (void)
   write_history_p = 0;
 
   /* Setup important stuff for command line editing.  */
+  rl_completion_word_break_hook = gdb_completion_word_break_characters;
   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 ();
@@ -1618,6 +1570,27 @@ Use \"on\" to enable the notification, and \"off\" to disable it."),
                           NULL,
                           show_exec_done_display_p,
                           &setlist, &showlist);
+
+  add_setshow_auto_boolean_cmd ("interactive-mode", class_support,
+                                &interactive_mode, _("\
+Set whether GDB should run in interactive mode or not"), _("\
+Show whether GDB runs in interactive mode"), _("\
+If on, run in interactive mode and wait for the user to answer\n\
+all queries.  If off, run in non-interactive mode and automatically\n\
+assume the default answer to all queries.  If auto (the default),\n\
+determine which mode to use based on the standard input settings"),
+                        NULL,
+                        show_interactive_mode,
+                        &setlist, &showlist);
+
+  add_setshow_filename_cmd ("data-directory", class_maintenance,
+                           &gdb_datadir, _("Set GDB's data directory."),
+                           _("Show GDB's data directory."),
+                           _("\
+When set, GDB uses the specified path to search for data files."),
+                           NULL, NULL,
+                           &setlist,
+                           &showlist);
 }
 
 void
@@ -1628,9 +1601,6 @@ gdb_init (char *argv0)
 
   /* 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.  */
@@ -1641,6 +1611,13 @@ gdb_init (char *argv0)
   initialize_targets ();       /* Setup target_terminal macros for utils.c */
   initialize_utils ();         /* Make errors and warnings possible */
   initialize_all_files ();
+  /* This creates the current_program_space.  Do this after all the
+     _initialize_foo routines have had a chance to install their
+     per-sspace data keys.  Also do this before
+     initialize_current_architecture is called, because it accesses
+     exec_bfd of the current program space.  */
+  initialize_progspace ();
+  initialize_inferiors ();
   initialize_current_architecture ();
   init_cli_cmds();
   init_main ();                        /* But that omits this file!  Do it now */
This page took 0.032523 seconds and 4 git commands to generate.