Explicitly include <array> for std::array<>.
[deliverable/binutils-gdb.git] / gdb / infcmd.c
index a537b0ad82952512a9f1fe57b6169faeecffa007..3b7178c4d8e936e8c8ab1a468f02022ebd7b06c9 100644 (file)
@@ -1,6 +1,6 @@
 /* Memory-access and commands for "inferior" process, for GDB.
 
-   Copyright (C) 1986-2016 Free Software Foundation, Inc.
+   Copyright (C) 1986-2017 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #include "thread-fsm.h"
 #include "top.h"
 #include "interps.h"
+#include "common/gdb_optional.h"
 
 /* Local functions: */
 
-static void nofp_registers_info (char *, int);
+static void info_registers_command (char *, int);
 
 static void until_next_command (int);
 
@@ -73,7 +74,7 @@ static void path_command (char *, int);
 
 static void unset_command (char *, int);
 
-static void float_info (char *, int);
+static void info_float_command (char *, int);
 
 static void disconnect_command (char *, int);
 
@@ -83,7 +84,7 @@ static void set_environment_command (char *, int);
 
 static void environment_info (char *, int);
 
-static void program_info (char *, int);
+static void info_program_command (char *, int);
 
 static void finish_command (char *, int);
 
@@ -261,14 +262,14 @@ construct_inferior_arguments (int argc, char **argv)
 #ifdef __MINGW32__
       /* This holds all the characters considered special to the
         Windows shells.  */
-      char *special = "\"!&*|[]{}<>?`~^=;, \t\n";
-      const char quote = '"';
+      static const char special[] = "\"!&*|[]{}<>?`~^=;, \t\n";
+      static const char quote = '"';
 #else
       /* This holds all the characters considered special to the
         typical Unix shells.  We include `^' because the SunOS
         /bin/sh treats it as a synonym for `|'.  */
-      char *special = "\"!#$&*()\\|[]{}<>?'`~^; \t\n";
-      const char quote = '\'';
+      static const char special[] = "\"!#$&*()\\|[]{}<>?'`~^; \t\n";
+      static const char quote = '\'';
 #endif
       int i;
       int length = 0;
@@ -458,7 +459,7 @@ post_create_inferior (struct target_ops *target, int from_tty)
          /* If the solist is global across processes, there's no need to
             refetch it here.  */
          if (!gdbarch_has_global_solist (target_gdbarch ()))
-           solib_add (NULL, 0, target, auto_solib_add);
+           solib_add (NULL, 0, auto_solib_add);
        }
     }
 
@@ -526,7 +527,7 @@ prepare_execution_command (struct target_ops *target, int background)
 static void
 run_command_1 (char *args, int from_tty, int tbreak_at_main)
 {
-  char *exec_file;
+  const char *exec_file;
   struct cleanup *old_chain;
   ptid_t ptid;
   struct ui_out *uiout = current_uiout;
@@ -574,7 +575,7 @@ run_command_1 (char *args, int from_tty, int tbreak_at_main)
   if (tbreak_at_main)
     tbreak_command (main_name (), 0);
 
-  exec_file = (char *) get_exec_file (0);
+  exec_file = get_exec_file (0);
 
   /* We keep symbols from add-symbol-file, on the grounds that the
      user might want to add some symbols before running the program
@@ -607,8 +608,9 @@ run_command_1 (char *args, int from_tty, int tbreak_at_main)
 
   /* We call get_inferior_args() because we might need to compute
      the value now.  */
-  run_target->to_create_inferior (run_target, exec_file, get_inferior_args (),
-                                 environ_vector (current_inferior ()->environment),
+  run_target->to_create_inferior (run_target, exec_file,
+                                 std::string (get_inferior_args ()),
+                                 current_inferior ()->environment.envp (),
                                  from_tty);
   /* to_create_inferior should push the target, so after this point we
      shouldn't refer to run_target again.  */
@@ -729,10 +731,10 @@ continue_1 (int all_threads)
     {
       /* Don't error out if the current thread is running, because
         there may be other stopped threads.  */
-      struct cleanup *old_chain;
 
-      /* Backup current thread and selected frame.  */
-      old_chain = make_cleanup_restore_current_thread ();
+      /* Backup current thread and selected frame and restore on scope
+        exit.  */
+      scoped_restore_current_thread restore_thread;
 
       iterate_over_threads (proceed_thread_callback, NULL);
 
@@ -753,9 +755,6 @@ continue_1 (int all_threads)
          */
          target_terminal_inferior ();
        }
-
-      /* Restore selected ptid.  */
-      do_cleanups (old_chain);
     }
   else
     {
@@ -866,14 +865,13 @@ continue_command (char *args, int from_tty)
 static void
 set_step_frame (void)
 {
-  struct symtab_and_line sal;
-  CORE_ADDR pc;
-  struct frame_info *frame = get_current_frame ();
-  struct thread_info *tp = inferior_thread ();
+  frame_info *frame = get_current_frame ();
 
-  find_frame_sal (frame, &sal);
+  symtab_and_line sal = find_frame_sal (frame);
   set_step_info (frame, sal);
-  pc = get_frame_pc (frame);
+
+  CORE_ADDR pc = get_frame_pc (frame);
+  thread_info *tp = inferior_thread ();
   tp->control.step_start_function = find_pc_function (pc);
 }
 
@@ -1180,8 +1178,6 @@ jump_command (char *arg, int from_tty)
 {
   struct gdbarch *gdbarch = get_current_arch ();
   CORE_ADDR addr;
-  struct symtabs_and_lines sals;
-  struct symtab_and_line sal;
   struct symbol *fn;
   struct symbol *sfn;
   int async_exec;
@@ -1201,18 +1197,16 @@ jump_command (char *arg, int from_tty)
   if (!arg)
     error_no_arg (_("starting address"));
 
-  sals = decode_line_with_last_displayed (arg, DECODE_LINE_FUNFIRSTLINE);
-  if (sals.nelts != 1)
-    {
-      error (_("Unreasonable jump request"));
-    }
-
-  sal = sals.sals[0];
-  xfree (sals.sals);
+  std::vector<symtab_and_line> sals
+    = decode_line_with_last_displayed (arg, DECODE_LINE_FUNFIRSTLINE);
+  if (sals.size () != 1)
+    error (_("Unreasonable jump request"));
 
   /* Done with ARGS.  */
   do_cleanups (args_chain);
 
+  symtab_and_line &sal = sals[0];
+
   if (sal.symtab == 0 && sal.pc == 0)
     error (_("No source file has been specified."));
 
@@ -1603,15 +1597,9 @@ advance_command (char *arg, int from_tty)
 struct value *
 get_return_value (struct value *function, struct type *value_type)
 {
-  struct regcache *stop_regs;
-  struct gdbarch *gdbarch;
+  regcache stop_regs (regcache::readonly, *get_current_regcache ());
+  struct gdbarch *gdbarch = stop_regs.arch ();
   struct value *value;
-  struct cleanup *cleanup;
-
-  stop_regs = regcache_dup (get_current_regcache ());
-  cleanup = make_cleanup_regcache_xfree (stop_regs);
-
-  gdbarch = get_regcache_arch (stop_regs);
 
   value_type = check_typedef (value_type);
   gdb_assert (TYPE_CODE (value_type) != TYPE_CODE_VOID);
@@ -1630,7 +1618,7 @@ get_return_value (struct value *function, struct type *value_type)
     case RETURN_VALUE_ABI_RETURNS_ADDRESS:
     case RETURN_VALUE_ABI_PRESERVES_ADDRESS:
       value = allocate_value (value_type);
-      gdbarch_return_value (gdbarch, function, value_type, stop_regs,
+      gdbarch_return_value (gdbarch, function, value_type, &stop_regs,
                            value_contents_raw (value), NULL);
       break;
     case RETURN_VALUE_STRUCT_CONVENTION:
@@ -1640,8 +1628,6 @@ get_return_value (struct value *function, struct type *value_type)
       internal_error (__FILE__, __LINE__, _("bad switch"));
     }
 
-  do_cleanups (cleanup);
-
   return value;
 }
 
@@ -1670,21 +1656,19 @@ print_return_value_1 (struct ui_out *uiout, struct return_value_info *rv)
   if (rv->value != NULL)
     {
       struct value_print_options opts;
-      struct ui_file *stb;
-      struct cleanup *old_chain;
 
       /* Print it.  */
-      stb = mem_fileopen ();
-      old_chain = make_cleanup_ui_file_delete (stb);
       uiout->text ("Value returned is ");
       uiout->field_fmt ("gdb-result-var", "$%d",
-                       rv->value_history_index);
+                        rv->value_history_index);
       uiout->text (" = ");
       get_no_prettyformat_print_options (&opts);
-      value_print (rv->value, stb, &opts);
+
+      string_file stb;
+
+      value_print (rv->value, &stb, &opts);
       uiout->field_stream ("return-value", stb);
       uiout->text ("\n");
-      do_cleanups (old_chain);
     }
   else
     {
@@ -1888,11 +1872,10 @@ finish_backward (struct finish_command_fsm *sm)
     {
       struct frame_info *frame = get_selected_frame (NULL);
       struct gdbarch *gdbarch = get_frame_arch (frame);
-      struct symtab_and_line sr_sal;
 
       /* Set a step-resume at the function's entry point.  Once that's
         hit, we'll do one more step backwards.  */
-      init_sal (&sr_sal);
+      symtab_and_line sr_sal;
       sr_sal.pc = sal.pc;
       sr_sal.pspace = get_frame_program_space (frame);
       insert_step_resume_breakpoint_at_sal (gdbarch,
@@ -2013,10 +1996,7 @@ finish_command (char *arg, int from_tty)
         called by that frame.  We don't use the magic "1" value for
         step_range_end, because then infrun will think this is nexti,
         and not step over the rest of this inlined function call.  */
-      struct symtab_and_line empty_sal;
-
-      init_sal (&empty_sal);
-      set_step_info (frame, empty_sal);
+      set_step_info (frame, {});
       tp->control.step_range_start = get_frame_pc (frame);
       tp->control.step_range_end = tp->control.step_range_start;
       tp->control.step_over_calls = STEP_OVER_ALL;
@@ -2071,7 +2051,7 @@ finish_command (char *arg, int from_tty)
 \f
 
 static void
-program_info (char *args, int from_tty)
+info_program_command (char *args, int from_tty)
 {
   bpstat bs;
   int num, stat;
@@ -2142,7 +2122,7 @@ environment_info (char *var, int from_tty)
 {
   if (var)
     {
-      char *val = get_in_environ (current_inferior ()->environment, var);
+      const char *val = current_inferior ()->environment.get (var);
 
       if (val)
        {
@@ -2160,11 +2140,11 @@ environment_info (char *var, int from_tty)
     }
   else
     {
-      char **vector = environ_vector (current_inferior ()->environment);
+      char **envp = current_inferior ()->environment.envp ();
 
-      while (*vector)
+      for (int idx = 0; envp[idx] != NULL; ++idx)
        {
-         puts_filtered (*vector++);
+         puts_filtered (envp[idx]);
          puts_filtered ("\n");
        }
     }
@@ -2226,10 +2206,10 @@ set_environment_command (char *arg, int from_tty)
       printf_filtered (_("Setting environment variable "
                         "\"%s\" to null value.\n"),
                       var);
-      set_in_environ (current_inferior ()->environment, var, "");
+      current_inferior ()->environment.set (var, "");
     }
   else
-    set_in_environ (current_inferior ()->environment, var, val);
+    current_inferior ()->environment.set (var, val);
   xfree (var);
 }
 
@@ -2241,13 +2221,10 @@ unset_environment_command (char *var, int from_tty)
       /* If there is no argument, delete all environment variables.
          Ask for confirmation if reading from the terminal.  */
       if (!from_tty || query (_("Delete all environment variables? ")))
-       {
-         free_environ (current_inferior ()->environment);
-         current_inferior ()->environment = make_environ ();
-       }
+       current_inferior ()->environment.clear ();
     }
   else
-    unset_in_environ (current_inferior ()->environment, var);
+    current_inferior ()->environment.unset (var);
 }
 
 /* Handle the execution path (PATH variable).  */
@@ -2258,8 +2235,7 @@ static void
 path_info (char *args, int from_tty)
 {
   puts_filtered ("Executable and object file path: ");
-  puts_filtered (get_in_environ (current_inferior ()->environment,
-                                path_var_name));
+  puts_filtered (current_inferior ()->environment.get (path_var_name));
   puts_filtered ("\n");
 }
 
@@ -2269,16 +2245,16 @@ static void
 path_command (char *dirname, int from_tty)
 {
   char *exec_path;
-  char *env;
+  const char *env;
 
   dont_repeat ();
-  env = get_in_environ (current_inferior ()->environment, path_var_name);
+  env = current_inferior ()->environment.get (path_var_name);
   /* Can be null if path is not set.  */
   if (!env)
     env = "";
   exec_path = xstrdup (env);
   mod_path (dirname, &exec_path);
-  set_in_environ (current_inferior ()->environment, path_var_name, exec_path);
+  current_inferior ()->environment.set (path_var_name, exec_path);
   xfree (exec_path);
   if (from_tty)
     path_info ((char *) NULL, from_tty);
@@ -2321,7 +2297,8 @@ default_print_one_register_info (struct ui_file *file,
       if (print_raw_format)
        {
          fprintf_filtered (file, "\t(raw ");
-         print_hex_chars (file, valaddr, TYPE_LENGTH (regtype), byte_order);
+         print_hex_chars (file, valaddr, TYPE_LENGTH (regtype), byte_order,
+                          true);
          fprintf_filtered (file, ")");
        }
     }
@@ -2516,13 +2493,13 @@ registers_info (char *addr_exp, int fpregs)
 }
 
 static void
-all_registers_info (char *addr_exp, int from_tty)
+info_all_registers_command (char *addr_exp, int from_tty)
 {
   registers_info (addr_exp, 1);
 }
 
 static void
-nofp_registers_info (char *addr_exp, int from_tty)
+info_registers_command (char *addr_exp, int from_tty)
 {
   registers_info (addr_exp, 0);
 }
@@ -2557,7 +2534,7 @@ print_vector_info (struct ui_file *file,
 }
 
 static void
-vector_info (char *args, int from_tty)
+info_vector_command (char *args, int from_tty)
 {
   if (!target_has_registers)
     error (_("The program has no registers now."));
@@ -2628,15 +2605,11 @@ proceed_after_attach (int pid)
 {
   /* Don't error out if the current thread is running, because
      there may be other stopped threads.  */
-  struct cleanup *old_chain;
 
   /* Backup current thread and selected frame.  */
-  old_chain = make_cleanup_restore_current_thread ();
+  scoped_restore_current_thread restore_thread;
 
   iterate_over_threads (proceed_after_attach_callback, &pid);
-
-  /* Restore selected ptid.  */
-  do_cleanups (old_chain);
 }
 
 /* See inferior.h.  */
@@ -2683,7 +2656,7 @@ enum attach_post_wait_mode
    should be running.  Else if ATTACH, */
 
 static void
-attach_post_wait (char *args, int from_tty, enum attach_post_wait_mode mode)
+attach_post_wait (const char *args, int from_tty, enum attach_post_wait_mode mode)
 {
   struct inferior *inferior;
 
@@ -2923,15 +2896,13 @@ attach_command (char *args, int from_tty)
 void
 notice_new_inferior (ptid_t ptid, int leave_running, int from_tty)
 {
-  struct cleanup* old_chain;
-  enum attach_post_wait_mode mode;
-
-  old_chain = make_cleanup (null_cleanup, NULL);
+  enum attach_post_wait_mode mode
+    = leave_running ? ATTACH_POST_WAIT_RESUME : ATTACH_POST_WAIT_NOTHING;
 
-  mode = leave_running ? ATTACH_POST_WAIT_RESUME : ATTACH_POST_WAIT_NOTHING;
+  gdb::optional<scoped_restore_current_thread> restore_thread;
 
-  if (!ptid_equal (inferior_ptid, null_ptid))
-    make_cleanup_restore_current_thread ();
+  if (inferior_ptid != null_ptid)
+    restore_thread.emplace ();
 
   /* Avoid reading registers -- we haven't fetched the target
      description yet.  */
@@ -2960,13 +2931,10 @@ notice_new_inferior (ptid_t ptid, int leave_running, int from_tty)
       add_inferior_continuation (attach_command_continuation, a,
                                 attach_command_continuation_free_args);
 
-      do_cleanups (old_chain);
       return;
     }
 
   attach_post_wait ("" /* args */, from_tty, mode);
-
-  do_cleanups (old_chain);
 }
 
 /*
@@ -3113,7 +3081,7 @@ default_print_float_info (struct gdbarch *gdbarch, struct ui_file *file,
 }
 
 static void
-float_info (char *args, int from_tty)
+info_float_command (char *args, int from_tty)
 {
   struct frame_info *frame;
 
@@ -3230,7 +3198,10 @@ is restored."),
                                     set_inferior_tty_command,
                                     show_inferior_tty_command,
                                     &setlist, &showlist);
-  add_com_alias ("tty", "set inferior-tty", class_alias, 0);
+  cmd_name = "inferior-tty";
+  c = lookup_cmd (&cmd_name, setlist, "", -1, 1);
+  gdb_assert (c != NULL);
+  add_alias_cmd ("tty", c, class_alias, 0, &cmdlist);
 
   cmd_name = "args";
   add_setshow_string_noescape_cmd (cmd_name, class_run,
@@ -3416,13 +3387,16 @@ Specifying -a and an ignore count simultaneously is an error."));
 
   c = add_com ("run", class_run, run_command, _("\
 Start debugged program.  You may specify arguments to give it.\n\
-Args may include \"*\", or \"[...]\"; they are expanded using \"sh\".\n\
-Input and output redirection with \">\", \"<\", or \">>\" are also \
-allowed.\n\n\
+Args may include \"*\", or \"[...]\"; they are expanded using the\n\
+shell that will start the program (specified by the \"$SHELL\"\
+environment\nvariable).  Input and output redirection with \">\",\
+\"<\", or \">>\"\nare also allowed.\n\n\
 With no arguments, uses arguments last specified (with \"run\" \
 or \"set args\").\n\
 To cancel previous arguments and run with no arguments,\n\
-use \"set args\" without arguments."));
+use \"set args\" without arguments.\n\
+To start the inferior without using a shell, use \"set \
+startup-with-shell off\"."));
   set_cmd_completer (c, filename_completer);
   add_com_alias ("r", "run", class_run, 1);
 
@@ -3438,24 +3412,24 @@ If non-stop mode is enabled, interrupt only the current thread,\n\
 otherwise all the threads in the program are stopped.  To \n\
 interrupt all running threads in non-stop mode, use the -a option."));
 
-  c = add_info ("registers", nofp_registers_info, _("\
+  c = add_info ("registers", info_registers_command, _("\
 List of integer registers and their contents, for selected stack frame.\n\
 Register name as argument means describe only that register."));
   add_info_alias ("r", "registers", 1);
   set_cmd_completer (c, reg_or_group_completer);
 
-  c = add_info ("all-registers", all_registers_info, _("\
+  c = add_info ("all-registers", info_all_registers_command, _("\
 List of all registers and their contents, for selected stack frame.\n\
 Register name as argument means describe only that register."));
   set_cmd_completer (c, reg_or_group_completer);
 
-  add_info ("program", program_info,
+  add_info ("program", info_program_command,
            _("Execution status of the program."));
 
-  add_info ("float", float_info,
+  add_info ("float", info_float_command,
            _("Print the status of the floating point unit\n"));
 
-  add_info ("vector", vector_info,
+  add_info ("vector", info_vector_command,
            _("Print the status of the vector unit\n"));
 
   add_prefix_cmd ("proc", class_info, info_proc_cmd,
This page took 0.030568 seconds and 4 git commands to generate.