arm: Check UNDEFWEAK_NO_DYNAMIC_RELOC
[deliverable/binutils-gdb.git] / gdb / infrun.c
index c7298a3979a9f2565c3e21da4c00d225a864b908..d00c5f6ee0c374eabd97f35400459ed449490062 100644 (file)
 #include "event-loop.h"
 #include "thread-fsm.h"
 #include "common/enum-flags.h"
+#include "progspace-and-thread.h"
+#include "common/gdb_optional.h"
+#include "arch-utils.h"
 
 /* Prototypes for local functions */
 
-static void signals_info (char *, int);
+static void info_signals_command (char *, int);
 
 static void handle_command (char *, int);
 
@@ -77,10 +80,6 @@ static void sig_print_header (void);
 
 static void resume_cleanups (void *);
 
-static int hook_stop_stub (void *);
-
-static int restore_selected_frame (void *);
-
 static int follow_fork (void);
 
 static int follow_fork_inferior (int follow_child, int detach_fork);
@@ -92,8 +91,6 @@ static void set_schedlock_func (char *args, int from_tty,
 
 static int currently_stepping (struct thread_info *tp);
 
-void _initialize_infrun (void);
-
 void nullify_last_target_wait_ptid (void);
 
 static void insert_hp_step_resume_breakpoint_at_frame (struct frame_info *);
@@ -477,7 +474,7 @@ holding the child stopped.  Try \"set detach-on-fork\" or \
              /* Ensure that we have a process ptid.  */
              ptid_t process_ptid = pid_to_ptid (ptid_get_pid (child_ptid));
 
-             target_terminal_ours_for_output ();
+             target_terminal::ours_for_output ();
              fprintf_filtered (gdb_stdlog,
                                _("Detaching after %s from child %s.\n"),
                                has_vforked ? "vfork" : "fork",
@@ -487,7 +484,6 @@ holding the child stopped.  Try \"set detach-on-fork\" or \
       else
        {
          struct inferior *parent_inf, *child_inf;
-         struct cleanup *old_chain;
 
          /* Add process to GDB's tables.  */
          child_inf = add_inferior (ptid_get_pid (child_ptid));
@@ -498,7 +494,7 @@ holding the child stopped.  Try \"set detach-on-fork\" or \
          child_inf->gdbarch = parent_inf->gdbarch;
          copy_inferior_target_desc_info (child_inf, parent_inf);
 
-         old_chain = save_current_space_and_thread ();
+         scoped_restore_current_pspace_and_thread restore_pspace_thread;
 
          inferior_ptid = child_ptid;
          add_thread (inferior_ptid);
@@ -536,8 +532,6 @@ holding the child stopped.  Try \"set detach-on-fork\" or \
                 required.  */
              solib_create_inferior_hook (0);
            }
-
-         do_cleanups (old_chain);
        }
 
       if (has_vforked)
@@ -565,7 +559,7 @@ holding the child stopped.  Try \"set detach-on-fork\" or \
 
       if (info_verbose || debug_infrun)
        {
-         target_terminal_ours_for_output ();
+         target_terminal::ours_for_output ();
          fprintf_filtered (gdb_stdlog,
                            _("Attaching after %s %s to child %s.\n"),
                            target_pid_to_str (parent_ptid),
@@ -613,7 +607,7 @@ holding the child stopped.  Try \"set detach-on-fork\" or \
              /* Ensure that we have a process ptid.  */
              ptid_t process_ptid = pid_to_ptid (ptid_get_pid (child_ptid));
 
-             target_terminal_ours_for_output ();
+             target_terminal::ours_for_output ();
              fprintf_filtered (gdb_stdlog,
                                _("Detaching after fork from "
                                  "child %s.\n"),
@@ -895,6 +889,22 @@ proceed_after_vfork_done (struct thread_info *thread,
   return 0;
 }
 
+/* Save/restore inferior_ptid, current program space and current
+   inferior.  Only use this if the current context points at an exited
+   inferior (and therefore there's no current thread to save).  */
+class scoped_restore_exited_inferior
+{
+public:
+  scoped_restore_exited_inferior ()
+    : m_saved_ptid (&inferior_ptid)
+  {}
+
+private:
+  scoped_restore_tmpl<ptid_t> m_saved_ptid;
+  scoped_restore_current_program_space m_pspace;
+  scoped_restore_current_inferior m_inferior;
+};
+
 /* Called whenever we notice an exec or exit event, to handle
    detaching or resuming a vfork parent.  */
 
@@ -914,7 +924,6 @@ handle_vfork_child_exec_or_exit (int exec)
       if (inf->vfork_parent->pending_detach)
        {
          struct thread_info *tp;
-         struct cleanup *old_chain;
          struct program_space *pspace;
          struct address_space *aspace;
 
@@ -922,16 +931,17 @@ handle_vfork_child_exec_or_exit (int exec)
 
          inf->vfork_parent->pending_detach = 0;
 
+         gdb::optional<scoped_restore_exited_inferior>
+           maybe_restore_inferior;
+         gdb::optional<scoped_restore_current_pspace_and_thread>
+           maybe_restore_thread;
+
+         /* If we're handling a child exit, then inferior_ptid points
+            at the inferior's pid, not to a thread.  */
          if (!exec)
-           {
-             /* If we're handling a child exit, then inferior_ptid
-                points at the inferior's pid, not to a thread.  */
-             old_chain = save_inferior_ptid ();
-             save_current_program_space ();
-             save_current_inferior ();
-           }
+           maybe_restore_inferior.emplace ();
          else
-           old_chain = save_current_space_and_thread ();
+           maybe_restore_thread.emplace ();
 
          /* We're letting loose of the parent.  */
          tp = any_live_thread_of_process (inf->vfork_parent->pid);
@@ -956,7 +966,7 @@ handle_vfork_child_exec_or_exit (int exec)
 
          if (debug_infrun || info_verbose)
            {
-             target_terminal_ours_for_output ();
+             target_terminal::ours_for_output ();
 
              if (exec)
                {
@@ -979,8 +989,6 @@ handle_vfork_child_exec_or_exit (int exec)
          /* Put it back.  */
          inf->pspace = pspace;
          inf->aspace = aspace;
-
-         do_cleanups (old_chain);
        }
       else if (exec)
        {
@@ -998,7 +1006,6 @@ handle_vfork_child_exec_or_exit (int exec)
        }
       else
        {
-         struct cleanup *old_chain;
          struct program_space *pspace;
 
          /* If this is a vfork child exiting, then the pspace and
@@ -1010,10 +1017,11 @@ handle_vfork_child_exec_or_exit (int exec)
             go ahead and create a new one for this exiting
             inferior.  */
 
-         /* Switch to null_ptid, so that clone_program_space doesn't want
-            to read the selected frame of a dead process.  */
-         old_chain = save_inferior_ptid ();
-         inferior_ptid = null_ptid;
+         /* Switch to null_ptid while running clone_program_space, so
+            that clone_program_space doesn't want to read the
+            selected frame of a dead process.  */
+         scoped_restore restore_ptid
+           = make_scoped_restore (&inferior_ptid, null_ptid);
 
          /* This inferior is dead, so avoid giving the breakpoints
             module the option to write through to it (cloning a
@@ -1028,10 +1036,6 @@ handle_vfork_child_exec_or_exit (int exec)
          inf->pspace = pspace;
          inf->aspace = pspace->aspace;
 
-         /* Put back inferior_ptid.  We'll continue mourning this
-            inferior.  */
-         do_cleanups (old_chain);
-
          resume_parent = inf->vfork_parent->pid;
          /* Break the bonds.  */
          inf->vfork_parent->vfork_child = NULL;
@@ -1045,7 +1049,7 @@ handle_vfork_child_exec_or_exit (int exec)
        {
          /* If the user wanted the parent to be running, let it go
             free now.  */
-         struct cleanup *old_chain = make_cleanup_restore_current_thread ();
+         scoped_restore_current_thread restore_thread;
 
          if (debug_infrun)
            fprintf_unfiltered (gdb_stdlog,
@@ -1053,8 +1057,6 @@ handle_vfork_child_exec_or_exit (int exec)
                                resume_parent);
 
          iterate_over_threads (proceed_after_vfork_done, &resume_parent);
-
-         do_cleanups (old_chain);
        }
     }
 }
@@ -1203,7 +1205,6 @@ follow_exec (ptid_t ptid, char *exec_file_target)
 
       set_current_inferior (inf);
       set_current_program_space (inf->pspace);
-      add_thread (ptid);
     }
   else
     {
@@ -1235,6 +1236,11 @@ follow_exec (ptid_t ptid, char *exec_file_target)
      registers.  */
   target_find_description ();
 
+  /* The add_thread call ends up reading registers, so do it after updating the
+     target description.  */
+  if (follow_exec_mode_string == follow_exec_mode_new)
+    add_thread (ptid);
+
   solib_create_inferior_hook (0);
 
   jit_inferior_created_hook ();
@@ -1703,12 +1709,8 @@ displaced_step_clear (struct displaced_step_inferior_state *displaced)
   /* Indicate that there is no cleanup pending.  */
   displaced->step_ptid = null_ptid;
 
-  if (displaced->step_closure)
-    {
-      gdbarch_displaced_step_free_closure (displaced->step_gdbarch,
-                                           displaced->step_closure);
-      displaced->step_closure = NULL;
-    }
+  xfree (displaced->step_closure);
+  displaced->step_closure = NULL;
 }
 
 static void
@@ -1752,7 +1754,7 @@ displaced_step_dump_bytes (struct ui_file *file,
 static int
 displaced_step_prepare_throw (ptid_t ptid)
 {
-  struct cleanup *old_cleanups, *ignore_cleanups;
+  struct cleanup *ignore_cleanups;
   struct thread_info *tp = find_thread_ptid (ptid);
   struct regcache *regcache = get_thread_regcache (ptid);
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
@@ -1804,7 +1806,7 @@ displaced_step_prepare_throw (ptid_t ptid)
 
   displaced_step_clear (displaced);
 
-  old_cleanups = save_inferior_ptid ();
+  scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
   inferior_ptid = ptid;
 
   original = regcache_read_pc (regcache);
@@ -1830,7 +1832,6 @@ displaced_step_prepare_throw (ptid_t ptid)
                              "Stepping over breakpoint in-line instead.\n");
        }
 
-      do_cleanups (old_cleanups);
       return -1;
     }
 
@@ -1860,7 +1861,7 @@ displaced_step_prepare_throw (ptid_t ptid)
       /* The architecture doesn't know how or want to displaced step
         this instruction or instruction sequence.  Fallback to
         stepping over the breakpoint in-line.  */
-      do_cleanups (old_cleanups);
+      do_cleanups (ignore_cleanups);
       return -1;
     }
 
@@ -1879,8 +1880,6 @@ displaced_step_prepare_throw (ptid_t ptid)
 
   discard_cleanups (ignore_cleanups);
 
-  do_cleanups (old_cleanups);
-
   if (debug_displaced)
     fprintf_unfiltered (gdb_stdlog, "displaced: displaced pc to %s\n",
                        paddress (gdbarch, copy));
@@ -1937,11 +1936,10 @@ static void
 write_memory_ptid (ptid_t ptid, CORE_ADDR memaddr,
                   const gdb_byte *myaddr, int len)
 {
-  struct cleanup *ptid_cleanup = save_inferior_ptid ();
+  scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
 
   inferior_ptid = ptid;
   write_memory (memaddr, myaddr, len);
-  do_cleanups (ptid_cleanup);
 }
 
 /* Restore the contents of the copy area for thread PTID.  */
@@ -2337,7 +2335,7 @@ do_target_resume (ptid_t resume_ptid, int step, enum gdb_signal sig)
   gdb_assert (!tp->stop_requested);
 
   /* Install inferior's terminal modes.  */
-  target_terminal_inferior ();
+  target_terminal::inferior ();
 
   /* Avoid confusing the next resume, if the next stop/resume
      happens to apply to another thread.  */
@@ -2409,15 +2407,14 @@ resume (enum gdb_signal sig)
     {
       if (debug_infrun)
        {
-         char *statstr;
+         std::string statstr
+           = target_waitstatus_to_string (&tp->suspend.waitstatus);
 
-         statstr = target_waitstatus_to_string (&tp->suspend.waitstatus);
          fprintf_unfiltered (gdb_stdlog,
-                             "infrun: resume: thread %s has pending wait status %s "
-                             "(currently_stepping=%d).\n",
-                             target_pid_to_str (tp->ptid),  statstr,
+                             "infrun: resume: thread %s has pending wait "
+                             "status %s (currently_stepping=%d).\n",
+                             target_pid_to_str (tp->ptid), statstr.c_str (),
                              currently_stepping (tp));
-         xfree (statstr);
        }
 
       tp->resumed = 1;
@@ -2820,16 +2817,15 @@ clear_proceed_status_thread (struct thread_info *tp)
        }
       else if (debug_infrun)
        {
-         char *statstr;
+         std::string statstr
+           = target_waitstatus_to_string (&tp->suspend.waitstatus);
 
-         statstr = target_waitstatus_to_string (&tp->suspend.waitstatus);
          fprintf_unfiltered (gdb_stdlog,
                              "infrun: clear_proceed_status_thread: thread %s "
                              "has pending wait status %s "
                              "(currently_stepping=%d).\n",
-                             target_pid_to_str (tp->ptid), statstr,
+                             target_pid_to_str (tp->ptid), statstr.c_str (),
                              currently_stepping (tp));
-         xfree (statstr);
        }
     }
 
@@ -2990,7 +2986,6 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
   struct execution_control_state ecss;
   struct execution_control_state *ecs = &ecss;
   struct cleanup *old_chain;
-  struct cleanup *defer_resume_cleanup;
   int started;
 
   /* If we're stopped at a fork/vfork, follow the branch set by the
@@ -3132,26 +3127,27 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
      until the target stops again.  */
   tp->prev_pc = regcache_read_pc (regcache);
 
-  defer_resume_cleanup = make_cleanup_defer_target_commit_resume ();
+  {
+    scoped_restore save_defer_tc = make_scoped_defer_target_commit_resume ();
 
-  started = start_step_over ();
+    started = start_step_over ();
 
-  if (step_over_info_valid_p ())
-    {
-      /* Either this thread started a new in-line step over, or some
-        other thread was already doing one.  In either case, don't
-        resume anything else until the step-over is finished.  */
-    }
-  else if (started && !target_is_non_stop_p ())
-    {
-      /* A new displaced stepping sequence was started.  In all-stop,
-        we can't talk to the target anymore until it next stops.  */
-    }
-  else if (!non_stop && target_is_non_stop_p ())
-    {
-      /* In all-stop, but the target is always in non-stop mode.
-        Start all other threads that are implicitly resumed too.  */
-      ALL_NON_EXITED_THREADS (tp)
+    if (step_over_info_valid_p ())
+      {
+       /* Either this thread started a new in-line step over, or some
+          other thread was already doing one.  In either case, don't
+          resume anything else until the step-over is finished.  */
+      }
+    else if (started && !target_is_non_stop_p ())
+      {
+       /* A new displaced stepping sequence was started.  In all-stop,
+          we can't talk to the target anymore until it next stops.  */
+      }
+    else if (!non_stop && target_is_non_stop_p ())
+      {
+       /* In all-stop, but the target is always in non-stop mode.
+          Start all other threads that are implicitly resumed too.  */
+       ALL_NON_EXITED_THREADS (tp)
         {
          /* Ignore threads of processes we're not resuming.  */
          if (!ptid_match (tp->ptid, resume_ptid))
@@ -3187,18 +3183,18 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
          if (!ecs->wait_some_more)
            error (_("Command aborted."));
        }
-    }
-  else if (!tp->resumed && !thread_is_in_step_over_chain (tp))
-    {
-      /* The thread wasn't started, and isn't queued, run it now.  */
-      reset_ecs (ecs, tp);
-      switch_to_thread (tp->ptid);
-      keep_going_pass_signal (ecs);
-      if (!ecs->wait_some_more)
-       error (_("Command aborted."));
-    }
+      }
+    else if (!tp->resumed && !thread_is_in_step_over_chain (tp))
+      {
+       /* The thread wasn't started, and isn't queued, run it now.  */
+       reset_ecs (ecs, tp);
+       switch_to_thread (tp->ptid);
+       keep_going_pass_signal (ecs);
+       if (!ecs->wait_some_more)
+         error (_("Command aborted."));
+      }
+  }
 
-  do_cleanups (defer_resume_cleanup);
   target_commit_resume ();
 
   discard_cleanups (old_chain);
@@ -3418,7 +3414,7 @@ void
 print_target_wait_results (ptid_t waiton_ptid, ptid_t result_ptid,
                           const struct target_waitstatus *ws)
 {
-  char *status_string = target_waitstatus_to_string (ws);
+  std::string status_string = target_waitstatus_to_string (ws);
   string_file stb;
 
   /* The text is split over several lines because it was getting too long.
@@ -3438,13 +3434,11 @@ print_target_wait_results (ptid_t waiton_ptid, ptid_t result_ptid,
              ptid_get_lwp (result_ptid),
              ptid_get_tid (result_ptid),
              target_pid_to_str (result_ptid));
-  stb.printf ("infrun:   %s\n", status_string);
+  stb.printf ("infrun:   %s\n", status_string.c_str ());
 
   /* This uses %s in part to handle %'s in the text, but also to avoid
      a gcc error: the format attribute requires a string literal.  */
   fprintf_unfiltered (gdb_stdlog, "%s", stb.c_str ());
-
-  xfree (status_string);
 }
 
 /* Select a thread at random, out of those which are resumed and have
@@ -3566,14 +3560,13 @@ do_target_wait (ptid_t ptid, struct target_waitstatus *status, int options)
     {
       if (debug_infrun)
        {
-         char *statstr;
+         std::string statstr
+           = target_waitstatus_to_string (&tp->suspend.waitstatus);
 
-         statstr = target_waitstatus_to_string (&tp->suspend.waitstatus);
          fprintf_unfiltered (gdb_stdlog,
                              "infrun: Using pending wait status %s for %s.\n",
-                             statstr,
+                             statstr.c_str (),
                              target_pid_to_str (tp->ptid));
-         xfree (statstr);
        }
 
       /* Now that we've selected our final event LWP, un-adjust its PC
@@ -3630,7 +3623,6 @@ prepare_for_detach (void)
 {
   struct inferior *inf = current_inferior ();
   ptid_t pid_ptid = pid_to_ptid (inf->pid);
-  struct cleanup *old_chain_1;
   struct displaced_step_inferior_state *displaced;
 
   displaced = get_displaced_stepping_state (inf->pid);
@@ -3644,8 +3636,7 @@ prepare_for_detach (void)
     fprintf_unfiltered (gdb_stdlog,
                        "displaced-stepping in-process while detaching");
 
-  old_chain_1 = make_cleanup_restore_integer (&inf->detaching);
-  inf->detaching = 1;
+  scoped_restore restore_detaching = make_scoped_restore (&inf->detaching, true);
 
   while (!ptid_equal (displaced->step_ptid, null_ptid))
     {
@@ -3685,12 +3676,12 @@ prepare_for_detach (void)
         inferior, so this must mean the process is gone.  */
       if (!ecs->wait_some_more)
        {
-         discard_cleanups (old_chain_1);
+         restore_detaching.release ();
          error (_("Program exited while detaching"));
        }
     }
 
-  discard_cleanups (old_chain_1);
+  restore_detaching.release ();
 }
 
 /* Wait for control to return from inferior to debugger.
@@ -3823,7 +3814,7 @@ check_curr_ui_sync_execution_done (void)
       && ui->async
       && !gdb_in_secondary_prompt_p (ui))
     {
-      target_terminal_ours ();
+      target_terminal::ours ();
       observer_notify_sync_execution_done ();
       ui_register_input_event_handler (ui);
     }
@@ -3891,12 +3882,14 @@ fetch_inferior_event (void *client_data)
       set_current_traceframe (-1);
     }
 
+  gdb::optional<scoped_restore_current_thread> maybe_restore_thread;
+
   if (non_stop)
     /* In non-stop mode, the user/frontend should not notice a thread
        switch due to internal events.  Make sure we reverse to the
        user selected thread and frame after handling the event and
        running any breakpoint commands.  */
-    make_cleanup_restore_current_thread ();
+    maybe_restore_thread.emplace ();
 
   overlay_cache_invalid = 1;
   /* Flush target cache before starting to handle each event.  Target
@@ -4181,10 +4174,11 @@ adjust_pc_after_break (struct thread_info *thread,
       || (target_is_non_stop_p ()
          && moribund_breakpoint_here_p (aspace, breakpoint_pc)))
     {
-      struct cleanup *old_cleanups = make_cleanup (null_cleanup, NULL);
+      gdb::optional<scoped_restore_tmpl<int>> restore_operation_disable;
 
       if (record_full_is_used ())
-       record_full_gdb_operation_disable_set ();
+       restore_operation_disable.emplace
+         (record_full_gdb_operation_disable_set ());
 
       /* When using hardware single-step, a SIGTRAP is reported for both
         a completed single-step and a software breakpoint.  Need to
@@ -4208,8 +4202,6 @@ adjust_pc_after_break (struct thread_info *thread,
          || (thread->stepped_breakpoint
              && thread->prev_pc == breakpoint_pc))
        regcache_write_pc (regcache, breakpoint_pc);
-
-      do_cleanups (old_cleanups);
     }
 }
 
@@ -4362,17 +4354,10 @@ wait_one (struct target_waitstatus *ws)
 static int                                     \
 thread_stopped_by_ ## REASON (ptid_t ptid)     \
 {                                              \
-  struct cleanup *old_chain;                   \
-  int res;                                     \
-                                               \
-  old_chain = save_inferior_ptid ();           \
+  scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid); \
   inferior_ptid = ptid;                                \
                                                \
-  res = target_stopped_by_ ## REASON ();       \
-                                               \
-  do_cleanups (old_chain);                     \
-                                               \
-  return res;                                  \
+  return target_stopped_by_ ## REASON ();      \
 }
 
 /* Generate thread_stopped_by_watchpoint.  */
@@ -4402,16 +4387,14 @@ save_waitstatus (struct thread_info *tp, struct target_waitstatus *ws)
 
   if (debug_infrun)
     {
-      char *statstr;
+      std::string statstr = target_waitstatus_to_string (ws);
 
-      statstr = target_waitstatus_to_string (ws);
       fprintf_unfiltered (gdb_stdlog,
                          "infrun: saving status %s for %d.%ld.%ld\n",
-                         statstr,
+                         statstr.c_str (),
                          ptid_get_pid (tp->ptid),
                          ptid_get_lwp (tp->ptid),
                          ptid_get_tid (tp->ptid));
-      xfree (statstr);
     }
 
   /* Record for later.  */
@@ -4641,17 +4624,15 @@ stop_all_threads (void)
 
                  if (debug_infrun)
                    {
-                     char *statstr;
+                     std::string statstr = target_waitstatus_to_string (&ws);
 
-                     statstr = target_waitstatus_to_string (&ws);
                      fprintf_unfiltered (gdb_stdlog,
                                          "infrun: target_wait %s, saving "
                                          "status for %d.%ld.%ld\n",
-                                         statstr,
+                                         statstr.c_str (),
                                          ptid_get_pid (t->ptid),
                                          ptid_get_lwp (t->ptid),
                                          ptid_get_tid (t->ptid));
-                     xfree (statstr);
                    }
 
                  /* Record for later.  */
@@ -5070,7 +5051,7 @@ handle_inferior_event_1 (struct execution_control_state *ecs)
       set_current_inferior (find_inferior_ptid (ecs->ptid));
       set_current_program_space (current_inferior ()->pspace);
       handle_vfork_child_exec_or_exit (0);
-      target_terminal_ours (); /* Must do this before mourn anyway.  */
+      target_terminal::ours ();        /* Must do this before mourn anyway.  */
 
       /* Clearing any previous state of convenience variables.  */
       clear_exit_convenience_vars ();
@@ -5322,10 +5303,11 @@ Cannot fill $_exitsignal with the correct signal number.\n"));
       if (debug_infrun)
         fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_EXECD\n");
 
+      /* Note we can't read registers yet (the stop_pc), because we
+        don't yet know the inferior's post-exec architecture.
+        'stop_pc' is explicitly read below instead.  */
       if (!ptid_equal (ecs->ptid, inferior_ptid))
-       context_switch (ecs->ptid);
-
-      stop_pc = regcache_read_pc (get_thread_regcache (ecs->ptid));
+       switch_to_thread_no_regs (ecs->event_thread);
 
       /* Do whatever is necessary to the parent branch of the vfork.  */
       handle_vfork_child_exec_or_exit (1);
@@ -5335,6 +5317,8 @@ Cannot fill $_exitsignal with the correct signal number.\n"));
          stop.  */
       follow_exec (inferior_ptid, ecs->ws.value.execd_pathname);
 
+      stop_pc = regcache_read_pc (get_thread_regcache (ecs->ptid));
+
       /* In follow_exec we may have deleted the original thread and
         created a new one.  Make sure that the event thread is the
         execd thread for that case (this is a nop otherwise).  */
@@ -5702,7 +5686,7 @@ handle_signal_stop (struct execution_control_state *ecs)
     {
       struct regcache *regcache = get_thread_regcache (ecs->ptid);
       struct gdbarch *gdbarch = get_regcache_arch (regcache);
-      struct cleanup *old_chain = save_inferior_ptid ();
+      scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
 
       inferior_ptid = ecs->ptid;
 
@@ -5722,8 +5706,6 @@ handle_signal_stop (struct execution_control_state *ecs)
             fprintf_unfiltered (gdb_stdlog,
                                 "infrun: (no data address available)\n");
        }
-
-      do_cleanups (old_chain);
     }
 
   /* This is originated from start_remote(), start_inferior() and
@@ -6024,14 +6006,14 @@ handle_signal_stop (struct execution_control_state *ecs)
          decr_pc = gdbarch_decr_pc_after_break (gdbarch);
          if (decr_pc != 0)
            {
-             struct cleanup *old_cleanups = make_cleanup (null_cleanup, NULL);
+             gdb::optional<scoped_restore_tmpl<int>>
+               restore_operation_disable;
 
              if (record_full_is_used ())
-               record_full_gdb_operation_disable_set ();
+               restore_operation_disable.emplace
+                 (record_full_gdb_operation_disable_set ());
 
              regcache_write_pc (regcache, stop_pc + decr_pc);
-
-             do_cleanups (old_cleanups);
            }
        }
       else
@@ -6114,9 +6096,9 @@ handle_signal_stop (struct execution_control_state *ecs)
       if (signal_print[ecs->event_thread->suspend.stop_signal])
        {
          /* The signal table tells us to print about this signal.  */
-         target_terminal_ours_for_output ();
+         target_terminal::ours_for_output ();
          observer_notify_signal_received (ecs->event_thread->suspend.stop_signal);
-         target_terminal_inferior ();
+         target_terminal::inferior ();
        }
 
       /* Clear the signal if it should not be passed.  */
@@ -6576,9 +6558,7 @@ process_event_stop_test (struct execution_control_state *ecs)
        {
          /* Set up a step-resume breakpoint at the address
             indicated by SKIP_SOLIB_RESOLVER.  */
-         struct symtab_and_line sr_sal;
-
-         init_sal (&sr_sal);
+         symtab_and_line sr_sal;
          sr_sal.pc = pc_after_resolver;
          sr_sal.pspace = get_frame_program_space (frame);
 
@@ -6629,9 +6609,7 @@ process_event_stop_test (struct execution_control_state *ecs)
       if (real_stop_pc)
        {
          /* And put the step-breakpoint there and go until there.  */
-         struct symtab_and_line sr_sal;
-
-         init_sal (&sr_sal);   /* initialize to zeroes */
+         symtab_and_line sr_sal;
          sr_sal.pc = real_stop_pc;
          sr_sal.section = find_pc_overlay (sr_sal.pc);
          sr_sal.pspace = get_frame_program_space (frame);
@@ -6729,10 +6707,8 @@ process_event_stop_test (struct execution_control_state *ecs)
                 to the caller.  */
              if (ecs->stop_func_start != stop_pc && ecs->stop_func_start != 0)
                {
-                 struct symtab_and_line sr_sal;
-
                  /* Normal function call return (static or dynamic).  */
-                 init_sal (&sr_sal);
+                 symtab_and_line sr_sal;
                  sr_sal.pc = ecs->stop_func_start;
                  sr_sal.pspace = get_frame_program_space (frame);
                  insert_step_resume_breakpoint_at_sal (gdbarch,
@@ -6759,9 +6735,7 @@ process_event_stop_test (struct execution_control_state *ecs)
 
       if (real_stop_pc != 0 && in_solib_dynsym_resolve_code (real_stop_pc))
        {
-         struct symtab_and_line sr_sal;
-
-         init_sal (&sr_sal);
+         symtab_and_line sr_sal;
          sr_sal.pc = ecs->stop_func_start;
          sr_sal.pspace = get_frame_program_space (frame);
 
@@ -6784,7 +6758,7 @@ process_event_stop_test (struct execution_control_state *ecs)
        tmp_sal = find_pc_line (ecs->stop_func_start, 0);
        if (tmp_sal.line != 0
            && !function_name_is_marked_for_skip (ecs->stop_func_name,
-                                                 &tmp_sal))
+                                                 tmp_sal))
          {
            if (execution_direction == EXEC_REVERSE)
              handle_step_into_function_backward (gdbarch, ecs);
@@ -6815,9 +6789,7 @@ process_event_stop_test (struct execution_control_state *ecs)
            {
              /* Set a breakpoint at callee's start address.
                 From there we can step once and be back in the caller.  */
-             struct symtab_and_line sr_sal;
-
-             init_sal (&sr_sal);
+             symtab_and_line sr_sal;
              sr_sal.pc = ecs->stop_func_start;
              sr_sal.pspace = get_frame_program_space (frame);
              insert_step_resume_breakpoint_at_sal (gdbarch,
@@ -6855,9 +6827,7 @@ process_event_stop_test (struct execution_control_state *ecs)
          /* Stepped backward into the solib dynsym resolver.
             Set a breakpoint at its start and continue, then
             one more step will take us out.  */
-         struct symtab_and_line sr_sal;
-
-         init_sal (&sr_sal);
+         symtab_and_line sr_sal;
          sr_sal.pc = ecs->stop_func_start;
          sr_sal.pspace = get_frame_program_space (frame);
          insert_step_resume_breakpoint_at_sal (gdbarch, 
@@ -6937,13 +6907,11 @@ process_event_stop_test (struct execution_control_state *ecs)
                   ecs->event_thread->control.step_frame_id)
       && inline_skipped_frames (ecs->ptid))
     {
-      struct symtab_and_line call_sal;
-
       if (debug_infrun)
        fprintf_unfiltered (gdb_stdlog,
                            "infrun: stepped into inlined function\n");
 
-      find_frame_sal (get_current_frame (), &call_sal);
+      symtab_and_line call_sal = find_frame_sal (get_current_frame ());
 
       if (ecs->event_thread->control.step_over_calls != STEP_OVER_ALL)
        {
@@ -7307,17 +7275,14 @@ static void
 handle_step_into_function (struct gdbarch *gdbarch,
                           struct execution_control_state *ecs)
 {
-  struct compunit_symtab *cust;
-  struct symtab_and_line stop_func_sal, sr_sal;
-
   fill_in_stop_func (gdbarch, ecs);
 
-  cust = find_pc_compunit_symtab (stop_pc);
+  compunit_symtab *cust = find_pc_compunit_symtab (stop_pc);
   if (cust != NULL && compunit_language (cust) != language_asm)
-    ecs->stop_func_start = gdbarch_skip_prologue (gdbarch,
-                                                 ecs->stop_func_start);
+    ecs->stop_func_start
+      = gdbarch_skip_prologue_noexcept (gdbarch, ecs->stop_func_start);
 
-  stop_func_sal = find_pc_line (ecs->stop_func_start, 0);
+  symtab_and_line stop_func_sal = find_pc_line (ecs->stop_func_start, 0);
   /* Use the step_resume_break to step until the end of the prologue,
      even if that involves jumps (as it seems to on the vax under
      4.2).  */
@@ -7361,7 +7326,7 @@ handle_step_into_function (struct gdbarch *gdbarch,
   else
     {
       /* Put the step-breakpoint there and go until there.  */
-      init_sal (&sr_sal);      /* initialize to zeroes */
+      symtab_and_line sr_sal;
       sr_sal.pc = ecs->stop_func_start;
       sr_sal.section = find_pc_overlay (ecs->stop_func_start);
       sr_sal.pspace = get_frame_program_space (get_current_frame ());
@@ -7393,8 +7358,8 @@ handle_step_into_function_backward (struct gdbarch *gdbarch,
 
   cust = find_pc_compunit_symtab (stop_pc);
   if (cust != NULL && compunit_language (cust) != language_asm)
-    ecs->stop_func_start = gdbarch_skip_prologue (gdbarch,
-                                                 ecs->stop_func_start);
+    ecs->stop_func_start
+      = gdbarch_skip_prologue_noexcept (gdbarch, ecs->stop_func_start);
 
   stop_func_sal = find_pc_line (stop_pc, 0);
 
@@ -7460,13 +7425,11 @@ insert_step_resume_breakpoint_at_sal (struct gdbarch *gdbarch,
 static void
 insert_hp_step_resume_breakpoint_at_frame (struct frame_info *return_frame)
 {
-  struct symtab_and_line sr_sal;
-  struct gdbarch *gdbarch;
-
   gdb_assert (return_frame != NULL);
-  init_sal (&sr_sal);          /* initialize to zeros */
 
-  gdbarch = get_frame_arch (return_frame);
+  struct gdbarch *gdbarch = get_frame_arch (return_frame);
+
+  symtab_and_line sr_sal;
   sr_sal.pc = gdbarch_addr_bits_remove (gdbarch, get_frame_pc (return_frame));
   sr_sal.section = find_pc_overlay (sr_sal.pc);
   sr_sal.pspace = get_frame_program_space (return_frame);
@@ -7493,16 +7456,13 @@ insert_hp_step_resume_breakpoint_at_frame (struct frame_info *return_frame)
 static void
 insert_step_resume_breakpoint_at_caller (struct frame_info *next_frame)
 {
-  struct symtab_and_line sr_sal;
-  struct gdbarch *gdbarch;
-
   /* We shouldn't have gotten here if we don't know where the call site
      is.  */
   gdb_assert (frame_id_p (frame_unwind_caller_id (next_frame)));
 
-  init_sal (&sr_sal);          /* initialize to zeros */
+  struct gdbarch *gdbarch = frame_unwind_caller_arch (next_frame);
 
-  gdbarch = frame_unwind_caller_arch (next_frame);
+  symtab_and_line sr_sal;
   sr_sal.pc = gdbarch_addr_bits_remove (gdbarch,
                                        frame_unwind_caller_pc (next_frame));
   sr_sal.section = find_pc_overlay (sr_sal.pc);
@@ -8122,7 +8082,7 @@ maybe_remove_breakpoints (void)
     {
       if (remove_breakpoints ())
        {
-         target_terminal_ours_for_output ();
+         target_terminal::ours_for_output ();
          printf_filtered (_("Cannot remove breakpoints because "
                             "program is no longer writable.\nFurther "
                             "execution is probably impossible.\n"));
@@ -8279,7 +8239,7 @@ normal_stop (void)
     {
       SWITCH_THRU_ALL_UIS ()
        {
-         target_terminal_ours_for_output ();
+         target_terminal::ours_for_output ();
          printf_filtered (_("[Switching to %s]\n"),
                           target_pid_to_str (inferior_ptid));
          annotate_thread_changed ();
@@ -8292,7 +8252,7 @@ normal_stop (void)
       SWITCH_THRU_ALL_UIS ()
        if (current_ui->prompt_state == PROMPT_BLOCKED)
          {
-           target_terminal_ours_for_output ();
+           target_terminal::ours_for_output ();
            printf_filtered (_("No unwaited-for children left.\n"));
          }
     }
@@ -8350,8 +8310,16 @@ normal_stop (void)
       struct cleanup *old_chain
        = make_cleanup (release_stop_context_cleanup, saved_context);
 
-      catch_errors (hook_stop_stub, stop_command,
-                   "Error while running hook_stop:\n", RETURN_MASK_ALL);
+      TRY
+       {
+         execute_cmd_pre_hook (stop_command);
+       }
+      CATCH (ex, RETURN_MASK_ALL)
+       {
+         exception_fprintf (gdb_stderr, ex,
+                            "Error while running hook_stop:\n");
+       }
+      END_CATCH
 
       /* If the stop hook resumes the target, then there's no point in
         trying to notify about the previous stop; its context is
@@ -8392,13 +8360,6 @@ normal_stop (void)
 
   return 0;
 }
-
-static int
-hook_stop_stub (void *cmd)
-{
-  execute_cmd_pre_hook ((struct cmd_list_element *) cmd);
-  return (0);
-}
 \f
 int
 signal_stop_state (int signo)
@@ -8508,14 +8469,12 @@ sig_print_info (enum gdb_signal oursig)
 static void
 handle_command (char *args, int from_tty)
 {
-  char **argv;
   int digits, wordlen;
   int sigfirst, signum, siglast;
   enum gdb_signal oursig;
   int allsigs;
   int nsigs;
   unsigned char *sigs;
-  struct cleanup *old_chain;
 
   if (args == NULL)
     {
@@ -8530,24 +8489,23 @@ handle_command (char *args, int from_tty)
 
   /* Break the command line up into args.  */
 
-  argv = gdb_buildargv (args);
-  old_chain = make_cleanup_freeargv (argv);
+  gdb_argv built_argv (args);
 
   /* Walk through the args, looking for signal oursigs, signal names, and
      actions.  Signal numbers and signal names may be interspersed with
      actions, with the actions being performed for all signals cumulatively
      specified.  Signal ranges can be specified as <LOW>-<HIGH>.  */
 
-  while (*argv != NULL)
+  for (char *arg : built_argv)
     {
-      wordlen = strlen (*argv);
-      for (digits = 0; isdigit ((*argv)[digits]); digits++)
+      wordlen = strlen (arg);
+      for (digits = 0; isdigit (arg[digits]); digits++)
        {;
        }
       allsigs = 0;
       sigfirst = siglast = -1;
 
-      if (wordlen >= 1 && !strncmp (*argv, "all", wordlen))
+      if (wordlen >= 1 && !strncmp (arg, "all", wordlen))
        {
          /* Apply action to all signals except those used by the
             debugger.  Silently skip those.  */
@@ -8555,37 +8513,37 @@ handle_command (char *args, int from_tty)
          sigfirst = 0;
          siglast = nsigs - 1;
        }
-      else if (wordlen >= 1 && !strncmp (*argv, "stop", wordlen))
+      else if (wordlen >= 1 && !strncmp (arg, "stop", wordlen))
        {
          SET_SIGS (nsigs, sigs, signal_stop);
          SET_SIGS (nsigs, sigs, signal_print);
        }
-      else if (wordlen >= 1 && !strncmp (*argv, "ignore", wordlen))
+      else if (wordlen >= 1 && !strncmp (arg, "ignore", wordlen))
        {
          UNSET_SIGS (nsigs, sigs, signal_program);
        }
-      else if (wordlen >= 2 && !strncmp (*argv, "print", wordlen))
+      else if (wordlen >= 2 && !strncmp (arg, "print", wordlen))
        {
          SET_SIGS (nsigs, sigs, signal_print);
        }
-      else if (wordlen >= 2 && !strncmp (*argv, "pass", wordlen))
+      else if (wordlen >= 2 && !strncmp (arg, "pass", wordlen))
        {
          SET_SIGS (nsigs, sigs, signal_program);
        }
-      else if (wordlen >= 3 && !strncmp (*argv, "nostop", wordlen))
+      else if (wordlen >= 3 && !strncmp (arg, "nostop", wordlen))
        {
          UNSET_SIGS (nsigs, sigs, signal_stop);
        }
-      else if (wordlen >= 3 && !strncmp (*argv, "noignore", wordlen))
+      else if (wordlen >= 3 && !strncmp (arg, "noignore", wordlen))
        {
          SET_SIGS (nsigs, sigs, signal_program);
        }
-      else if (wordlen >= 4 && !strncmp (*argv, "noprint", wordlen))
+      else if (wordlen >= 4 && !strncmp (arg, "noprint", wordlen))
        {
          UNSET_SIGS (nsigs, sigs, signal_print);
          UNSET_SIGS (nsigs, sigs, signal_stop);
        }
-      else if (wordlen >= 4 && !strncmp (*argv, "nopass", wordlen))
+      else if (wordlen >= 4 && !strncmp (arg, "nopass", wordlen))
        {
          UNSET_SIGS (nsigs, sigs, signal_program);
        }
@@ -8598,11 +8556,11 @@ handle_command (char *args, int from_tty)
             SIGHUP, SIGINT, SIGALRM, etc. will work right anyway.  */
 
          sigfirst = siglast = (int)
-           gdb_signal_from_command (atoi (*argv));
-         if ((*argv)[digits] == '-')
+           gdb_signal_from_command (atoi (arg));
+         if (arg[digits] == '-')
            {
              siglast = (int)
-               gdb_signal_from_command (atoi ((*argv) + digits + 1));
+               gdb_signal_from_command (atoi (arg + digits + 1));
            }
          if (sigfirst > siglast)
            {
@@ -8614,7 +8572,7 @@ handle_command (char *args, int from_tty)
        }
       else
        {
-         oursig = gdb_signal_from_name (*argv);
+         oursig = gdb_signal_from_name (arg);
          if (oursig != GDB_SIGNAL_UNKNOWN)
            {
              sigfirst = siglast = (int) oursig;
@@ -8622,7 +8580,7 @@ handle_command (char *args, int from_tty)
          else
            {
              /* Not a number and not a recognized flag word => complain.  */
-             error (_("Unrecognized or ambiguous flag word: \"%s\"."), *argv);
+             error (_("Unrecognized or ambiguous flag word: \"%s\"."), arg);
            }
        }
 
@@ -8660,8 +8618,6 @@ Are you sure you want to change it? "),
              break;
            }
        }
-
-      argv++;
     }
 
   for (signum = 0; signum < nsigs; signum++)
@@ -8682,17 +8638,15 @@ Are you sure you want to change it? "),
 
        break;
       }
-
-  do_cleanups (old_chain);
 }
 
 /* Complete the "handle" command.  */
 
-static VEC (char_ptr) *
+static void
 handle_completer (struct cmd_list_element *ignore,
+                 completion_tracker &tracker,
                  const char *text, const char *word)
 {
-  VEC (char_ptr) *vec_signals, *vec_keywords, *return_val;
   static const char * const keywords[] =
     {
       "all",
@@ -8707,13 +8661,8 @@ handle_completer (struct cmd_list_element *ignore,
       NULL,
     };
 
-  vec_signals = signal_completer (ignore, text, word);
-  vec_keywords = complete_on_enum (keywords, word, word);
-
-  return_val = VEC_merge (char_ptr, vec_signals, vec_keywords);
-  VEC_free (char_ptr, vec_signals);
-  VEC_free (char_ptr, vec_keywords);
-  return return_val;
+  signal_completer (ignore, tracker, text, word);
+  complete_on_enum (tracker, keywords, word, word);
 }
 
 enum gdb_signal
@@ -8731,7 +8680,7 @@ Use \"info signals\" for a list of symbolic signals."));
    targets, all signals should be in the signal tables).  */
 
 static void
-signals_info (char *signum_exp, int from_tty)
+info_signals_command (char *signum_exp, int from_tty)
 {
   enum gdb_signal oursig;
 
@@ -8971,7 +8920,7 @@ make_cleanup_restore_infcall_suspend_state
 void
 discard_infcall_suspend_state (struct infcall_suspend_state *inf_state)
 {
-  regcache_xfree (inf_state->registers);
+  delete inf_state->registers;
   xfree (inf_state->siginfo_data);
   xfree (inf_state);
 }
@@ -9031,25 +8980,20 @@ save_infcall_control_state (void)
   return inf_status;
 }
 
-static int
-restore_selected_frame (void *args)
+static void
+restore_selected_frame (const frame_id &fid)
 {
-  struct frame_id *fid = (struct frame_id *) args;
-  struct frame_info *frame;
-
-  frame = frame_find_by_id (*fid);
+  frame_info *frame = frame_find_by_id (fid);
 
   /* If inf_status->selected_frame_id is NULL, there was no previously
      selected frame.  */
   if (frame == NULL)
     {
       warning (_("Unable to restore previously selected frame."));
-      return 0;
+      return;
     }
 
   select_frame (frame);
-
-  return (1);
 }
 
 /* Restore inferior session state to INF_STATUS.  */
@@ -9079,16 +9023,22 @@ restore_infcall_control_state (struct infcall_control_state *inf_status)
 
   if (target_has_stack)
     {
-      /* The point of catch_errors is that if the stack is clobbered,
+      /* The point of the try/catch is that if the stack is clobbered,
          walking the stack might encounter a garbage pointer and
          error() trying to dereference it.  */
-      if (catch_errors
-         (restore_selected_frame, &inf_status->selected_frame_id,
-          "Unable to restore previously selected frame:\n",
-          RETURN_MASK_ERROR) == 0)
-       /* Error in restoring the selected frame.  Select the innermost
-          frame.  */
-       select_frame (get_current_frame ());
+      TRY
+       {
+         restore_selected_frame (inf_status->selected_frame_id);
+       }
+      CATCH (ex, RETURN_MASK_ERROR)
+       {
+         exception_fprintf (gdb_stderr, ex,
+                            "Unable to restore previously selected frame:\n");
+         /* Error in restoring the selected frame.  Select the
+            innermost frame.  */
+         select_frame (get_current_frame ());
+       }
+      END_CATCH
     }
 
   xfree (inf_status);
@@ -9124,32 +9074,6 @@ discard_infcall_control_state (struct infcall_control_state *inf_status)
   xfree (inf_status);
 }
 \f
-/* restore_inferior_ptid() will be used by the cleanup machinery
-   to restore the inferior_ptid value saved in a call to
-   save_inferior_ptid().  */
-
-static void
-restore_inferior_ptid (void *arg)
-{
-  ptid_t *saved_ptid_ptr = (ptid_t *) arg;
-
-  inferior_ptid = *saved_ptid_ptr;
-  xfree (arg);
-}
-
-/* Save the value of inferior_ptid so that it may be restored by a
-   later call to do_cleanups().  Returns the struct cleanup pointer
-   needed for later doing the cleanup.  */
-
-struct cleanup *
-save_inferior_ptid (void)
-{
-  ptid_t *saved_ptid_ptr = XNEW (ptid_t);
-
-  *saved_ptid_ptr = inferior_ptid;
-  return make_cleanup (restore_inferior_ptid, saved_ptid_ptr);
-}
-
 /* See infrun.h.  */
 
 void
@@ -9247,7 +9171,7 @@ _initialize_infrun (void)
   infrun_async_inferior_event_token
     = create_async_event_handler (infrun_async_inferior_event_handler, NULL);
 
-  add_info ("signals", signals_info, _("\
+  add_info ("signals", info_signals_command, _("\
 What debugger does when program gets various signals.\n\
 Specify a signal as argument to print info on that signal only."));
   add_info_alias ("handle", "signals", 0);
This page took 0.041428 seconds and 4 git commands to generate.