gdb: include gdbsupport/buildargv.h in ser-mingw.c
[binutils-gdb.git] / gdb / infcmd.c
index 3cb05e564c32abc739d296f31a24793a95ca8201..9f4ed8bff1383476e0dfdb65d65064de8de769eb 100644 (file)
@@ -1,6 +1,6 @@
 /* Memory-access and commands for "inferior" process, for GDB.
 
-   Copyright (C) 1986-2021 Free Software Foundation, Inc.
+   Copyright (C) 1986-2022 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -71,16 +71,16 @@ static void step_1 (int, int, const char *);
    Arguments are separated by spaces.  Empty string (pointer to '\0')
    means no args.  */
 
-static char *inferior_args_scratch;
+static std::string inferior_args_scratch;
 
 /* Scratch area where the new cwd will be stored by 'set cwd'.  */
 
-static char *inferior_cwd_scratch;
+static std::string inferior_cwd_scratch;
 
 /* Scratch area where 'set inferior-tty' will store user-provided value.
    We'll immediate copy it into per-inferior storage.  */
 
-static char *inferior_io_terminal_scratch;
+static std::string inferior_io_terminal_scratch;
 
 /* Pid of our debugged inferior, or 0 if no inferior now.
    Since various parts of infrun.c test this to see whether there is a program
@@ -115,52 +115,19 @@ show_inferior_tty_command (struct ui_file *file, int from_tty,
 {
   /* Note that we ignore the passed-in value in favor of computing it
      directly.  */
-  const char *inferior_tty = current_inferior ()->tty ();
+  const std::string &inferior_tty = current_inferior ()->tty ();
 
-  if (inferior_tty == nullptr)
-    inferior_tty = "";
-  fprintf_filtered (gdb_stdout,
+  fprintf_filtered (file,
                    _("Terminal for future runs of program being debugged "
-                     "is \"%s\".\n"), inferior_tty);
-}
-
-const char *
-get_inferior_args (void)
-{
-  if (current_inferior ()->argc != 0)
-    {
-      gdb::array_view<char * const> args (current_inferior ()->argv,
-                                         current_inferior ()->argc);
-      std::string n = construct_inferior_arguments (args);
-      set_inferior_args (n.c_str ());
-    }
-
-  if (current_inferior ()->args == NULL)
-    current_inferior ()->args = make_unique_xstrdup ("");
-
-  return current_inferior ()->args.get ();
-}
-
-/* Set the arguments for the current inferior.  Ownership of
-   NEWARGS is not transferred.  */
-
-void
-set_inferior_args (const char *newargs)
-{
-  if (newargs != nullptr)
-    current_inferior ()->args = make_unique_xstrdup (newargs);
-  else
-    current_inferior ()->args.reset ();
-
-  current_inferior ()->argc = 0;
-  current_inferior ()->argv = 0;
+                     "is \"%s\".\n"), inferior_tty.c_str ());
 }
 
 void
 set_inferior_args_vector (int argc, char **argv)
 {
-  current_inferior ()->argc = argc;
-  current_inferior ()->argv = argv;
+  gdb::array_view<char * const> args (argv, argc);
+  std::string n = construct_inferior_arguments (args);
+  current_inferior ()->set_args (std::move (n));
 }
 
 /* Notice when `set args' is run.  */
@@ -170,7 +137,7 @@ set_args_command (const char *args, int from_tty, struct cmd_list_element *c)
 {
   /* CLI has assigned the user-provided value to inferior_args_scratch.
      Now route it to current inferior.  */
-  set_inferior_args (inferior_args_scratch);
+  current_inferior ()->set_args (inferior_args_scratch);
 }
 
 /* Notice when `show args' is run.  */
@@ -181,30 +148,16 @@ show_args_command (struct ui_file *file, int from_tty,
 {
   /* Note that we ignore the passed-in value in favor of computing it
      directly.  */
-  deprecated_show_value_hack (file, from_tty, c, get_inferior_args ());
-}
-
-/* See gdbsupport/common-inferior.h.  */
-
-void
-set_inferior_cwd (const char *cwd)
-{
-  struct inferior *inf = current_inferior ();
-
-  gdb_assert (inf != NULL);
-
-  if (cwd == NULL)
-    inf->cwd.reset ();
-  else
-    inf->cwd.reset (xstrdup (cwd));
+  deprecated_show_value_hack (file, from_tty, c,
+                             current_inferior ()->args ().c_str ());
 }
 
 /* See gdbsupport/common-inferior.h.  */
 
-const char *
+const std::string &
 get_inferior_cwd ()
 {
-  return current_inferior ()->cwd.get ();
+  return current_inferior ()->cwd ();
 }
 
 /* Handle the 'set cwd' command.  */
@@ -212,10 +165,7 @@ get_inferior_cwd ()
 static void
 set_cwd_command (const char *args, int from_tty, struct cmd_list_element *c)
 {
-  if (*inferior_cwd_scratch == '\0')
-    set_inferior_cwd (NULL);
-  else
-    set_inferior_cwd (inferior_cwd_scratch);
+  current_inferior ()->set_cwd (inferior_cwd_scratch);
 }
 
 /* Handle the 'show cwd' command.  */
@@ -224,18 +174,19 @@ static void
 show_cwd_command (struct ui_file *file, int from_tty,
                  struct cmd_list_element *c, const char *value)
 {
-  const char *cwd = get_inferior_cwd ();
+  const std::string &cwd = current_inferior ()->cwd ();
 
-  if (cwd == NULL)
-    fprintf_filtered (gdb_stdout,
+  if (cwd.empty ())
+    fprintf_filtered (file,
                      _("\
 You have not set the inferior's current working directory.\n\
 The inferior will inherit GDB's cwd if native debugging, or the remote\n\
 server's cwd if remote debugging.\n"));
   else
-    fprintf_filtered (gdb_stdout,
+    fprintf_filtered (file,
                      _("Current working directory that will be used "
-                       "when starting the inferior is \"%s\".\n"), cwd);
+                       "when starting the inferior is \"%s\".\n"),
+                     cwd.c_str ());
 }
 
 
@@ -298,11 +249,11 @@ post_create_inferior (int from_tty)
      missing registers info), ignore it.  */
   thread_info *thr = inferior_thread ();
 
-  thr->suspend.stop_pc = 0;
+  thr->clear_stop_pc ();
   try
     {
       regcache *rc = get_thread_regcache (thr);
-      thr->suspend.stop_pc = regcache_read_pc (rc);
+      thr->set_stop_pc (regcache_read_pc (rc));
     }
   catch (const gdb_exception_error &ex)
     {
@@ -315,6 +266,10 @@ post_create_inferior (int from_tty)
       const unsigned solib_add_generation
        = current_program_space->solib_add_generation;
 
+      scoped_restore restore_in_initial_library_scan
+       = make_scoped_restore (&current_inferior ()->in_initial_library_scan,
+                              true);
+
       /* Create the hooks to handle shared library load and unload
         events.  */
       solib_create_inferior_hook (from_tty);
@@ -381,7 +336,7 @@ prepare_execution_command (struct target_ops *target, int background)
 {
   /* If we get a request for running in the bg but the target
      doesn't support it, error out.  */
-  if (background && !target->can_async_p ())
+  if (background && !target_can_async_p (target))
     error (_("Asynchronous execution not supported on this target."));
 
   if (!background)
@@ -440,7 +395,7 @@ run_command_1 (const char *args, int from_tty, enum run_how run_how)
      to check again here.  Since reopen_exec_file doesn't do anything
      if the timestamp hasn't changed, I don't see the harm.  */
   reopen_exec_file ();
-  reread_symbols ();
+  reread_symbols (from_tty);
 
   gdb::unique_xmalloc_ptr<char> stripped = strip_bg_char (args, &async_exec);
   args = stripped.get ();
@@ -476,7 +431,7 @@ run_command_1 (const char *args, int from_tty, enum run_how run_how)
 
   /* If there were other args, beside '&', process them.  */
   if (args != NULL)
-    set_inferior_args (args);
+    current_inferior ()->set_args (args);
 
   if (from_tty)
     {
@@ -485,17 +440,13 @@ run_command_1 (const char *args, int from_tty, enum run_how run_how)
       if (exec_file)
        uiout->field_string ("execfile", exec_file);
       uiout->spaces (1);
-      /* We call get_inferior_args() because we might need to compute
-        the value now.  */
-      uiout->field_string ("infargs", get_inferior_args ());
+      uiout->field_string ("infargs", current_inferior ()->args ());
       uiout->text ("\n");
       uiout->flush ();
     }
 
-  /* We call get_inferior_args() because we might need to compute
-     the value now.  */
   run_target->create_inferior (exec_file,
-                              std::string (get_inferior_args ()),
+                              current_inferior ()->args (),
                               current_inferior ()->environment.envp (),
                               from_tty);
   /* to_create_inferior should push the target, so after this point we
@@ -530,9 +481,9 @@ run_command_1 (const char *args, int from_tty, enum run_how run_how)
   if (run_how == RUN_STOP_AT_FIRST_INSN)
     {
       thread_info *thr = inferior_thread ();
-      thr->suspend.waitstatus_pending_p = 1;
-      thr->suspend.waitstatus.kind = TARGET_WAITKIND_STOPPED;
-      thr->suspend.waitstatus.value.sig = GDB_SIGNAL_0;
+      target_waitstatus ws;
+      ws.set_stopped (GDB_SIGNAL_0);
+      thr->set_pending_waitstatus (ws);
     }
 
   /* Start the target running.  Do not use -1 continuation as it would skip
@@ -652,6 +603,8 @@ continue_1 (int all_threads)
       /* Backup current thread and selected frame and restore on scope
         exit.  */
       scoped_restore_current_thread restore_thread;
+      scoped_disable_commit_resumed disable_commit_resumed
+       ("continue all threads in non-stop");
 
       iterate_over_threads (proceed_thread_callback, NULL);
 
@@ -672,6 +625,8 @@ continue_1 (int all_threads)
          */
          target_terminal::inferior ();
        }
+
+      disable_commit_resumed.reset_and_commit ();
     }
   else
     {
@@ -718,7 +673,7 @@ continue_command (const char *args, int from_tty)
      stopped at.  */
   if (args != NULL)
     {
-      bpstat bs = NULL;
+      bpstat *bs = nullptr;
       int num, stat;
       int stopped = 0;
       struct thread_info *tp;
@@ -1219,15 +1174,15 @@ signal_command (const char *signum_exp, int from_tty)
          if (tp == current)
            continue;
 
-         if (tp->suspend.stop_signal != GDB_SIGNAL_0
-             && signal_pass_state (tp->suspend.stop_signal))
+         if (tp->stop_signal () != GDB_SIGNAL_0
+             && signal_pass_state (tp->stop_signal ()))
            {
              if (!must_confirm)
                printf_unfiltered (_("Note:\n"));
              printf_unfiltered (_("  Thread %s previously stopped with signal %s, %s.\n"),
                                 print_thread_id (tp),
-                                gdb_signal_to_name (tp->suspend.stop_signal),
-                                gdb_signal_to_string (tp->suspend.stop_signal));
+                                gdb_signal_to_name (tp->stop_signal ()),
+                                gdb_signal_to_string (tp->stop_signal ()));
              must_confirm = 1;
            }
        }
@@ -1290,7 +1245,7 @@ queue_signal_command (const char *signum_exp, int from_tty)
     error (_("Signal handling set to not pass this signal to the program."));
 
   tp = inferior_thread ();
-  tp->suspend.stop_signal = oursig;
+  tp->set_stop_signal (oursig);
 }
 
 /* Data for the FSM that manages the until (with no argument)
@@ -1472,14 +1427,14 @@ get_return_value (struct value *function, struct type *value_type)
      calls are made async, this will likely be made the norm.  */
 
   switch (gdbarch_return_value (gdbarch, function, value_type,
-                               NULL, NULL, NULL))
+                               NULL, NULL, NULL))
     {
     case RETURN_VALUE_REGISTER_CONVENTION:
     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,
-                           value_contents_raw (value), NULL);
+                           value_contents_raw (value).data (), NULL);
       break;
     case RETURN_VALUE_STRUCT_CONVENTION:
       value = NULL;
@@ -1876,7 +1831,7 @@ finish_command (const char *arg, int from_tty)
 static void
 info_program_command (const char *args, int from_tty)
 {
-  bpstat bs;
+  bpstat *bs;
   int num, stat;
   ptid_t ptid;
   process_stratum_target *proc_target;
@@ -1910,7 +1865,7 @@ info_program_command (const char *args, int from_tty)
 
   target_files_info ();
   printf_filtered (_("Program stopped at %s.\n"),
-                  paddress (target_gdbarch (), tp->suspend.stop_pc));
+                  paddress (target_gdbarch (), tp->stop_pc ()));
   if (tp->control.stop_step)
     printf_filtered (_("It stopped after being stepped.\n"));
   else if (stat != 0)
@@ -1929,11 +1884,11 @@ info_program_command (const char *args, int from_tty)
          stat = bpstat_num (&bs, &num);
        }
     }
-  else if (tp->suspend.stop_signal != GDB_SIGNAL_0)
+  else if (tp->stop_signal () != GDB_SIGNAL_0)
     {
       printf_filtered (_("It stopped with signal %s, %s.\n"),
-                      gdb_signal_to_name (tp->suspend.stop_signal),
-                      gdb_signal_to_string (tp->suspend.stop_signal));
+                      gdb_signal_to_name (tp->stop_signal ()),
+                      gdb_signal_to_string (tp->stop_signal ()));
     }
 
   if (from_tty)
@@ -2069,7 +2024,6 @@ path_info (const char *args, int from_tty)
 static void
 path_command (const char *dirname, int from_tty)
 {
-  char *exec_path;
   const char *env;
 
   dont_repeat ();
@@ -2077,10 +2031,9 @@ path_command (const char *dirname, int from_tty)
   /* Can be null if path is not set.  */
   if (!env)
     env = "";
-  exec_path = xstrdup (env);
-  mod_path (dirname, &exec_path);
-  current_inferior ()->environment.set (path_var_name, exec_path);
-  xfree (exec_path);
+  std::string exec_path = env;
+  mod_path (dirname, exec_path);
+  current_inferior ()->environment.set (path_var_name, exec_path.c_str ());
   if (from_tty)
     path_info (NULL, from_tty);
 }
@@ -2127,7 +2080,7 @@ default_print_one_register_info (struct ui_file *file,
       || regtype->code () == TYPE_CODE_DECFLOAT)
     {
       struct value_print_options opts;
-      const gdb_byte *valaddr = value_contents_for_printing (val);
+      const gdb_byte *valaddr = value_contents_for_printing (val).data ();
       enum bfd_endian byte_order = type_byte_order (regtype);
 
       get_user_print_options (&opts);
@@ -2396,12 +2349,11 @@ kill_command (const char *arg, int from_tty)
   int infnum = current_inferior ()->num;
 
   target_kill ();
+  bfd_cache_close_all ();
 
   if (print_inferior_events)
-    printf_unfiltered (_("[Inferior %d (%s) killed]\n"),
-                      infnum, pid_str.c_str ());
-
-  bfd_cache_close_all ();
+    printf_filtered (_("[Inferior %d (%s) killed]\n"),
+                    infnum, pid_str.c_str ());
 }
 
 /* Used in `attach&' command.  Proceed threads of inferior INF iff
@@ -2419,9 +2371,9 @@ proceed_after_attach (inferior *inf)
   scoped_restore_current_thread restore_thread;
 
   for (thread_info *thread : inf->non_exited_threads ())
-    if (!thread->executing
+    if (!thread->executing ()
        && !thread->stop_requested
-       && thread->suspend.stop_signal == GDB_SIGNAL_0)
+       && thread->stop_signal () == GDB_SIGNAL_0)
       {
        switch_to_thread (thread);
        clear_proceed_status (0);
@@ -2446,7 +2398,7 @@ setup_inferior (int from_tty)
   else
     {
       reopen_exec_file ();
-      reread_symbols ();
+      reread_symbols (from_tty);
     }
 
   /* Take any necessary post-attaching actions for this platform.  */
@@ -2496,7 +2448,7 @@ attach_post_wait (int from_tty, enum attach_post_wait_mode mode)
        proceed_after_attach (inferior);
       else
        {
-         if (inferior_thread ()->suspend.stop_signal == GDB_SIGNAL_0)
+         if (inferior_thread ()->stop_signal () == GDB_SIGNAL_0)
            {
              clear_proceed_status (0);
              proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
@@ -2589,6 +2541,18 @@ attach_command (const char *args, int from_tty)
      shouldn't refer to attach_target again.  */
   attach_target = NULL;
 
+  if (debug_infrun)
+    {
+      infrun_debug_printf ("immediately after attach:");
+      for (thread_info *thread : inferior->non_exited_threads ())
+       infrun_debug_printf ("  thread %s, executing = %d, resumed = %d, "
+                            "state = %s",
+                            thread->ptid.to_string ().c_str (),
+                            thread->executing (),
+                            thread->resumed (),
+                            thread_state_string (thread->state));
+    }
+
   /* Set up the "saved terminal modes" of the inferior
      based on what modes we are starting it with.  */
   target_terminal::init ();
@@ -2692,7 +2656,7 @@ notice_new_inferior (thread_info *thr, bool leave_running, int from_tty)
   /* When we "notice" a new inferior we need to do all the things we
      would normally do if we had just attached to it.  */
 
-  if (thr->executing)
+  if (thr->executing ())
     {
       struct inferior *inferior = current_inferior ();