Add basic support for AArch64.
[deliverable/binutils-gdb.git] / gdb / infrun.c
index 50ad217853095c5de8a741fad529ab088878d872..1cf30feff2c1d290fd9e00fd3046d25c8f22d2a1 100644 (file)
@@ -1,7 +1,7 @@
 /* Target-struct-independent code to start (run) and stop an inferior
    process.
 
-   Copyright (C) 1986-2012 Free Software Foundation, Inc.
+   Copyright (C) 1986-2013 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -57,6 +57,8 @@
 #include "skip.h"
 #include "probe.h"
 #include "objfiles.h"
+#include "completer.h"
+#include "target-descriptions.h"
 
 /* Prototypes for local functions */
 
@@ -140,7 +142,7 @@ show_debug_displaced (struct ui_file *file, int from_tty,
   fprintf_filtered (file, _("Displace stepping debugging is %s.\n"), value);
 }
 
-int debug_infrun = 0;
+unsigned int debug_infrun = 0;
 static void
 show_debug_infrun (struct ui_file *file, int from_tty,
                   struct cmd_list_element *c, const char *value)
@@ -316,6 +318,12 @@ static unsigned char *signal_stop;
 static unsigned char *signal_print;
 static unsigned char *signal_program;
 
+/* Table of signals that are registered with "catch signal".  A
+   non-zero entry indicates that the signal is caught by some "catch
+   signal" command.  This has size GDB_SIGNAL_LAST, to accommodate all
+   signals.  */
+static unsigned char *signal_catch;
+
 /* Table of signals that the target may silently handle.
    This is automatically determined from the flags above,
    and simply cached here.  */
@@ -395,7 +403,7 @@ static void context_switch (ptid_t ptid);
 
 void init_thread_stepping_state (struct thread_info *tss);
 
-void init_infwait_state (void);
+static void init_infwait_state (void);
 
 static const char follow_fork_mode_child[] = "child";
 static const char follow_fork_mode_parent[] = "parent";
@@ -662,7 +670,18 @@ handle_vfork_child_exec_or_exit (int exec)
 
          /* follow-fork child, detach-on-fork on.  */
 
-         old_chain = make_cleanup_restore_current_thread ();
+         inf->vfork_parent->pending_detach = 0;
+
+         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 ();
+           }
+         else
+           old_chain = save_current_space_and_thread ();
 
          /* We're letting loose of the parent.  */
          tp = any_live_thread_of_process (inf->vfork_parent->pid);
@@ -901,6 +920,16 @@ follow_exec (ptid_t pid, char *execd_pathname)
       set_current_inferior (inf);
       set_current_program_space (pspace);
     }
+  else
+    {
+      /* The old description may no longer be fit for the new image.
+        E.g, a 64-bit process exec'ed a 32-bit process.  Clear the
+        old description; we'll read a new one below.  No need to do
+        this on "follow-exec-mode new", as the old inferior stays
+        around (its description is later cleared/refetched on
+        restart).  */
+      target_clear_description ();
+    }
 
   gdb_assert (current_program_space == inf->pspace);
 
@@ -920,6 +949,14 @@ follow_exec (ptid_t pid, char *execd_pathname)
   if ((inf->symfile_flags & SYMFILE_NO_READ) == 0)
     set_initial_language ();
 
+  /* If the target can specify a description, read it.  Must do this
+     after flipping to the new executable (because the target supplied
+     description must be compatible with the executable's
+     architecture, and the old executable may e.g., be 32-bit, while
+     the new one 64-bit), and before anything involving memory or
+     registers.  */
+  target_find_description ();
+
 #ifdef SOLIB_CREATE_INFERIOR_HOOK
   SOLIB_CREATE_INFERIOR_HOOK (PIDGET (inferior_ptid));
 #else
@@ -1185,19 +1222,6 @@ infrun_inferior_exit (struct inferior *inf)
   remove_displaced_stepping_state (inf->pid);
 }
 
-/* Enum strings for "set|show displaced-stepping".  */
-
-static const char can_use_displaced_stepping_auto[] = "auto";
-static const char can_use_displaced_stepping_on[] = "on";
-static const char can_use_displaced_stepping_off[] = "off";
-static const char *const can_use_displaced_stepping_enum[] =
-{
-  can_use_displaced_stepping_auto,
-  can_use_displaced_stepping_on,
-  can_use_displaced_stepping_off,
-  NULL,
-};
-
 /* If ON, and the architecture supports it, GDB will use displaced
    stepping to step over breakpoints.  If OFF, or if the architecture
    doesn't support it, GDB will instead use the traditional
@@ -1206,15 +1230,14 @@ static const char *const can_use_displaced_stepping_enum[] =
    which of all-stop or non-stop mode is active --- displaced stepping
    in non-stop mode; hold-and-step in all-stop mode.  */
 
-static const char *can_use_displaced_stepping =
-  can_use_displaced_stepping_auto;
+static enum auto_boolean can_use_displaced_stepping = AUTO_BOOLEAN_AUTO;
 
 static void
 show_can_use_displaced_stepping (struct ui_file *file, int from_tty,
                                 struct cmd_list_element *c,
                                 const char *value)
 {
-  if (can_use_displaced_stepping == can_use_displaced_stepping_auto)
+  if (can_use_displaced_stepping == AUTO_BOOLEAN_AUTO)
     fprintf_filtered (file,
                      _("Debugger's willingness to use displaced stepping "
                        "to step over breakpoints is %s (currently %s).\n"),
@@ -1231,9 +1254,8 @@ show_can_use_displaced_stepping (struct ui_file *file, int from_tty,
 static int
 use_displaced_stepping (struct gdbarch *gdbarch)
 {
-  return (((can_use_displaced_stepping == can_use_displaced_stepping_auto
-           && non_stop)
-          || can_use_displaced_stepping == can_use_displaced_stepping_on)
+  return (((can_use_displaced_stepping == AUTO_BOOLEAN_AUTO && non_stop)
+          || can_use_displaced_stepping == AUTO_BOOLEAN_TRUE)
          && gdbarch_displaced_step_copy_insn_p (gdbarch)
          && !RECORD_IS_USED);
 }
@@ -2117,7 +2139,8 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal, int step)
   struct thread_info *tp;
   CORE_ADDR pc;
   struct address_space *aspace;
-  int oneproc = 0;
+  /* GDB may force the inferior to step due to various reasons.  */
+  int force_step = 0;
 
   /* If we're stopped at a fork/vfork, follow the branch set by the
      "set follow-fork-mode" command; otherwise, we'll just proceed
@@ -2157,13 +2180,13 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal, int step)
           actually be executing the breakpoint insn anyway.
           We'll be (un-)executing the previous instruction.  */
 
-       oneproc = 1;
+       force_step = 1;
       else if (gdbarch_single_step_through_delay_p (gdbarch)
               && gdbarch_single_step_through_delay (gdbarch,
                                                     get_current_frame ()))
        /* We stepped onto an instruction that needs to be stepped
           again before re-inserting the breakpoint, do so.  */
-       oneproc = 1;
+       force_step = 1;
     }
   else
     {
@@ -2194,13 +2217,13 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal, int step)
         is required it returns TRUE and sets the current thread to
         the old thread.  */
       if (prepare_to_proceed (step))
-       oneproc = 1;
+       force_step = 1;
     }
 
   /* prepare_to_proceed may change the current thread.  */
   tp = inferior_thread ();
 
-  if (oneproc)
+  if (force_step)
     {
       tp->control.trap_expected = 1;
       /* If displaced stepping is enabled, we can step over the
@@ -2288,7 +2311,8 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal, int step)
   init_infwait_state ();
 
   /* Resume inferior.  */
-  resume (oneproc || step || bpstat_should_step (), tp->suspend.stop_signal);
+  resume (force_step || step || bpstat_should_step (),
+         tp->suspend.stop_signal);
 
   /* Wait for it to stop (if not standalone)
      and in any case decode why it stopped, and act accordingly.  */
@@ -2376,7 +2400,7 @@ enum infwait_states
 ptid_t waiton_ptid;
 
 /* Current inferior wait state.  */
-enum infwait_states infwait_state;
+static enum infwait_states infwait_state;
 
 /* Data to be passed around while handling an event.  This data is
    discarded between events.  */
@@ -2393,7 +2417,6 @@ struct execution_control_state
   CORE_ADDR stop_func_start;
   CORE_ADDR stop_func_end;
   const char *stop_func_name;
-  int new_thread_event;
   int wait_some_more;
 };
 
@@ -2438,8 +2461,6 @@ infrun_thread_stop_requested_callback (struct thread_info *info, void *arg)
 
       old_chain = make_cleanup_restore_current_thread ();
 
-      switch_to_thread (info->ptid);
-
       /* Go through handle_inferior_event/normal_stop, so we always
         have consistent output as if the stop event had been
         reported.  */
@@ -2656,14 +2677,6 @@ prepare_for_detach (void)
       old_chain_2 = make_cleanup (finish_thread_state_cleanup,
                                  &minus_one_ptid);
 
-      /* In non-stop mode, each thread is handled individually.
-        Switch early, so the global state is set correctly for this
-        thread.  */
-      if (non_stop
-         && ecs->ws.kind != TARGET_WAITKIND_EXITED
-         && ecs->ws.kind != TARGET_WAITKIND_SIGNALLED)
-       context_switch (ecs->ptid);
-
       /* Now figure out what to do with the result of the result.  */
       handle_inferior_event (ecs);
 
@@ -2694,8 +2707,6 @@ void
 wait_for_inferior (void)
 {
   struct cleanup *old_cleanups;
-  struct execution_control_state ecss;
-  struct execution_control_state *ecs;
 
   if (debug_infrun)
     fprintf_unfiltered
@@ -2704,13 +2715,14 @@ wait_for_inferior (void)
   old_cleanups =
     make_cleanup (delete_step_thread_step_resume_breakpoint_cleanup, NULL);
 
-  ecs = &ecss;
-  memset (ecs, 0, sizeof (*ecs));
-
   while (1)
     {
+      struct execution_control_state ecss;
+      struct execution_control_state *ecs = &ecss;
       struct cleanup *old_chain;
 
+      memset (ecs, 0, sizeof (*ecs));
+
       overlay_cache_invalid = 1;
 
       if (deprecated_target_wait_hook)
@@ -2791,16 +2803,6 @@ fetch_inferior_event (void *client_data)
   if (debug_infrun)
     print_target_wait_results (waiton_ptid, ecs->ptid, &ecs->ws);
 
-  if (non_stop
-      && ecs->ws.kind != TARGET_WAITKIND_IGNORE
-      && ecs->ws.kind != TARGET_WAITKIND_NO_RESUMED
-      && ecs->ws.kind != TARGET_WAITKIND_EXITED
-      && ecs->ws.kind != TARGET_WAITKIND_SIGNALLED)
-    /* In non-stop mode, each thread is handled individually.  Switch
-       early, so the global state is set correctly for this
-       thread.  */
-    context_switch (ecs->ptid);
-
   /* If an error happens while handling the event, propagate GDB's
      knowledge of the executing state to the frontend/user running
      state.  */
@@ -3039,27 +3041,13 @@ adjust_pc_after_break (struct execution_control_state *ecs)
     }
 }
 
-void
+static void
 init_infwait_state (void)
 {
   waiton_ptid = pid_to_ptid (-1);
   infwait_state = infwait_normal_state;
 }
 
-void
-error_is_running (void)
-{
-  error (_("Cannot execute this command while "
-          "the selected thread is running."));
-}
-
-void
-ensure_not_running (void)
-{
-  if (is_running (inferior_ptid))
-    error_is_running ();
-}
-
 static int
 stepped_in_from (struct frame_info *frame, struct frame_id step_frame_id)
 {
@@ -3085,20 +3073,20 @@ static int
 handle_syscall_event (struct execution_control_state *ecs)
 {
   struct regcache *regcache;
-  struct gdbarch *gdbarch;
   int syscall_number;
 
   if (!ptid_equal (ecs->ptid, inferior_ptid))
     context_switch (ecs->ptid);
 
   regcache = get_thread_regcache (ecs->ptid);
-  gdbarch = get_regcache_arch (regcache);
   syscall_number = ecs->ws.value.syscall_number;
   stop_pc = regcache_read_pc (regcache);
 
   if (catch_syscall_enabled () > 0
       && catching_syscall_number (syscall_number) > 0)
     {
+      enum bpstat_signal_value sval;
+
       if (debug_infrun)
         fprintf_unfiltered (gdb_stdlog, "infrun: syscall number = '%d'\n",
                             syscall_number);
@@ -3106,8 +3094,9 @@ handle_syscall_event (struct execution_control_state *ecs)
       ecs->event_thread->control.stop_bpstat
        = bpstat_stop_status (get_regcache_aspace (regcache),
                              stop_pc, ecs->ptid, &ecs->ws);
-      ecs->random_signal
-       = !bpstat_explains_signal (ecs->event_thread->control.stop_bpstat);
+
+      sval = bpstat_explains_signal (ecs->event_thread->control.stop_bpstat);
+      ecs->random_signal = sval == BPSTAT_SIGNAL_NO;
 
       if (!ecs->random_signal)
        {
@@ -3230,17 +3219,14 @@ handle_inferior_event (struct execution_control_state *ecs)
       return;
     }
 
-  /* If it's a new process, add it to the thread database.  */
-
-  ecs->new_thread_event = (!ptid_equal (ecs->ptid, inferior_ptid)
-                          && !ptid_equal (ecs->ptid, minus_one_ptid)
-                          && !in_thread_list (ecs->ptid));
-
   if (ecs->ws.kind != TARGET_WAITKIND_EXITED
-      && ecs->ws.kind != TARGET_WAITKIND_SIGNALLED && ecs->new_thread_event)
-    add_thread (ecs->ptid);
-
-  ecs->event_thread = find_thread_ptid (ecs->ptid);
+      && ecs->ws.kind != TARGET_WAITKIND_SIGNALLED)
+    {
+      ecs->event_thread = find_thread_ptid (ecs->ptid);
+      /* If it's a new thread, add it to the thread database.  */
+      if (ecs->event_thread == NULL)
+       ecs->event_thread = add_thread (ecs->ptid);
+    }
 
   /* Dependent on valid ECS->EVENT_THREAD.  */
   adjust_pc_after_break (ecs);
@@ -3342,6 +3328,7 @@ handle_inferior_event (struct execution_control_state *ecs)
       if (stop_soon == NO_STOP_QUIETLY)
        {
          struct regcache *regcache;
+         enum bpstat_signal_value sval;
 
          if (!ptid_equal (ecs->ptid, inferior_ptid))
            context_switch (ecs->ptid);
@@ -3352,8 +3339,10 @@ handle_inferior_event (struct execution_control_state *ecs)
          ecs->event_thread->control.stop_bpstat
            = bpstat_stop_status (get_regcache_aspace (regcache),
                                  stop_pc, ecs->ptid, &ecs->ws);
-         ecs->random_signal
-           = !bpstat_explains_signal (ecs->event_thread->control.stop_bpstat);
+
+         sval
+           = bpstat_explains_signal (ecs->event_thread->control.stop_bpstat);
+         ecs->random_signal = sval == BPSTAT_SIGNAL_NO;
 
          if (!ecs->random_signal)
            {
@@ -3384,6 +3373,9 @@ handle_inferior_event (struct execution_control_state *ecs)
         we're attaching or setting up a remote connection.  */
       if (stop_soon == STOP_QUIETLY || stop_soon == NO_STOP_QUIETLY)
        {
+         if (!ptid_equal (ecs->ptid, inferior_ptid))
+           context_switch (ecs->ptid);
+
          /* Loading of shared libraries might have changed breakpoint
             addresses.  Make sure new breakpoints are inserted.  */
          if (stop_soon == NO_STOP_QUIETLY
@@ -3399,28 +3391,45 @@ handle_inferior_event (struct execution_control_state *ecs)
     case TARGET_WAITKIND_SPURIOUS:
       if (debug_infrun)
         fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_SPURIOUS\n");
+      if (!ptid_equal (ecs->ptid, inferior_ptid))
+       context_switch (ecs->ptid);
       resume (0, GDB_SIGNAL_0);
       prepare_to_wait (ecs);
       return;
 
     case TARGET_WAITKIND_EXITED:
+    case TARGET_WAITKIND_SIGNALLED:
       if (debug_infrun)
-        fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_EXITED\n");
+       {
+         if (ecs->ws.kind == TARGET_WAITKIND_EXITED)
+           fprintf_unfiltered (gdb_stdlog,
+                               "infrun: TARGET_WAITKIND_EXITED\n");
+         else
+           fprintf_unfiltered (gdb_stdlog,
+                               "infrun: TARGET_WAITKIND_SIGNALLED\n");
+       }
+
       inferior_ptid = ecs->ptid;
       set_current_inferior (find_inferior_pid (ptid_get_pid (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.  */
-      print_exited_reason (ecs->ws.value.integer);
 
-      /* Record the exit code in the convenience variable $_exitcode, so
-         that the user can inspect this again later.  */
-      set_internalvar_integer (lookup_internalvar ("_exitcode"),
-                              (LONGEST) ecs->ws.value.integer);
+      if (ecs->ws.kind == TARGET_WAITKIND_EXITED)
+       {
+         /* Record the exit code in the convenience variable $_exitcode, so
+            that the user can inspect this again later.  */
+         set_internalvar_integer (lookup_internalvar ("_exitcode"),
+                                  (LONGEST) ecs->ws.value.integer);
+
+         /* Also record this in the inferior itself.  */
+         current_inferior ()->has_exit_code = 1;
+         current_inferior ()->exit_code = (LONGEST) ecs->ws.value.integer;
 
-      /* Also record this in the inferior itself.  */
-      current_inferior ()->has_exit_code = 1;
-      current_inferior ()->exit_code = (LONGEST) ecs->ws.value.integer;
+         print_exited_reason (ecs->ws.value.integer);
+       }
+      else
+       print_signal_exited_reason (ecs->ws.value.sig);
 
       gdb_flush (gdb_stdout);
       target_mourn_inferior ();
@@ -3430,35 +3439,17 @@ handle_inferior_event (struct execution_control_state *ecs)
       stop_stepping (ecs);
       return;
 
-    case TARGET_WAITKIND_SIGNALLED:
-      if (debug_infrun)
-        fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_SIGNALLED\n");
-      inferior_ptid = ecs->ptid;
-      set_current_inferior (find_inferior_pid (ptid_get_pid (ecs->ptid)));
-      set_current_program_space (current_inferior ()->pspace);
-      handle_vfork_child_exec_or_exit (0);
-      stop_print_frame = 0;
-      target_terminal_ours (); /* Must do this before mourn anyway.  */
-
-      /* Note: By definition of TARGET_WAITKIND_SIGNALLED, we shouldn't
-         reach here unless the inferior is dead.  However, for years
-         target_kill() was called here, which hints that fatal signals aren't
-         really fatal on some systems.  If that's true, then some changes
-         may be needed.  */
-      target_mourn_inferior ();
-
-      print_signal_exited_reason (ecs->ws.value.sig);
-      singlestep_breakpoints_inserted_p = 0;
-      cancel_single_step_breakpoints ();
-      stop_stepping (ecs);
-      return;
-
       /* The following are the only cases in which we keep going;
          the above cases end in a continue or goto.  */
     case TARGET_WAITKIND_FORKED:
     case TARGET_WAITKIND_VFORKED:
       if (debug_infrun)
-        fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_FORKED\n");
+       {
+         if (ecs->ws.kind == TARGET_WAITKIND_FORKED)
+           fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_FORKED\n");
+         else
+           fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_VFORKED\n");
+       }
 
       /* Check whether the inferior is displaced stepping.  */
       {
@@ -3515,10 +3506,7 @@ handle_inferior_event (struct execution_control_state *ecs)
       }
 
       if (!ptid_equal (ecs->ptid, inferior_ptid))
-       {
-         context_switch (ecs->ptid);
-         reinit_frame_cache ();
-       }
+       context_switch (ecs->ptid);
 
       /* Immediately detach breakpoints from the child before there's
         any chance of letting the user delete breakpoints from the
@@ -3534,11 +3522,9 @@ handle_inferior_event (struct execution_control_state *ecs)
         vfork follow are detached.  */
       if (ecs->ws.kind != TARGET_WAITKIND_VFORKED)
        {
-         int child_pid = ptid_get_pid (ecs->ws.value.related_pid);
-
          /* This won't actually modify the breakpoint list, but will
             physically remove the breakpoints from the child.  */
-         detach_breakpoints (child_pid);
+         detach_breakpoints (ecs->ws.value.related_pid);
        }
 
       if (singlestep_breakpoints_inserted_p)
@@ -3635,10 +3621,7 @@ handle_inferior_event (struct execution_control_state *ecs)
         fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_EXECD\n");
 
       if (!ptid_equal (ecs->ptid, inferior_ptid))
-       {
-         context_switch (ecs->ptid);
-         reinit_frame_cache ();
-       }
+       context_switch (ecs->ptid);
 
       singlestep_breakpoints_inserted_p = 0;
       cancel_single_step_breakpoints ();
@@ -3657,7 +3640,8 @@ handle_inferior_event (struct execution_control_state *ecs)
        = bpstat_stop_status (get_regcache_aspace (get_current_regcache ()),
                              stop_pc, ecs->ptid, &ecs->ws);
       ecs->random_signal
-       = !bpstat_explains_signal (ecs->event_thread->control.stop_bpstat);
+       = (bpstat_explains_signal (ecs->event_thread->control.stop_bpstat)
+          == BPSTAT_SIGNAL_NO);
 
       /* Note that this may be referenced from inside
         bpstat_stop_status above, through inferior_has_execd.  */
@@ -3708,36 +3692,21 @@ handle_inferior_event (struct execution_control_state *ecs)
       if (debug_infrun)
         fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_NO_HISTORY\n");
       /* Reverse execution: target ran out of history info.  */
+
+      /* Pull the single step breakpoints out of the target.  */
+      if (singlestep_breakpoints_inserted_p)
+       {
+         if (!ptid_equal (ecs->ptid, inferior_ptid))
+           context_switch (ecs->ptid);
+         remove_single_step_breakpoints ();
+         singlestep_breakpoints_inserted_p = 0;
+       }
       stop_pc = regcache_read_pc (get_thread_regcache (ecs->ptid));
       print_no_history_reason ();
       stop_stepping (ecs);
       return;
     }
 
-  if (ecs->new_thread_event)
-    {
-      if (non_stop)
-       /* Non-stop assumes that the target handles adding new threads
-          to the thread list.  */
-       internal_error (__FILE__, __LINE__,
-                       "targets should add new threads to the thread "
-                       "list themselves in non-stop mode.");
-
-      /* We may want to consider not doing a resume here in order to
-        give the user a chance to play with the new thread.  It might
-        be good to make that a user-settable option.  */
-
-      /* At this point, all threads are stopped (happens automatically
-        in either the OS or the native code).  Therefore we need to
-        continue all threads in order to make progress.  */
-
-      if (!ptid_equal (ecs->ptid, inferior_ptid))
-       context_switch (ecs->ptid);
-      target_resume (RESUME_ALL, 0, GDB_SIGNAL_0);
-      prepare_to_wait (ecs);
-      return;
-    }
-
   if (ecs->ws.kind == TARGET_WAITKIND_STOPPED)
     {
       /* Do we need to clean up the state of a thread that has
@@ -3803,6 +3772,8 @@ handle_inferior_event (struct execution_control_state *ecs)
                                "infrun: stepping_past_"
                                "singlestep_breakpoint\n");
          /* Pull the single step breakpoints out of the target.  */
+         if (!ptid_equal (ecs->ptid, inferior_ptid))
+           context_switch (ecs->ptid);
          remove_single_step_breakpoints ();
          singlestep_breakpoints_inserted_p = 0;
 
@@ -3811,7 +3782,7 @@ handle_inferior_event (struct execution_control_state *ecs)
 
          context_switch (saved_singlestep_ptid);
          if (deprecated_context_hook)
-           deprecated_context_hook (pid_to_thread_id (ecs->ptid));
+           deprecated_context_hook (pid_to_thread_id (saved_singlestep_ptid));
 
          resume (1, GDB_SIGNAL_0);
          prepare_to_wait (ecs);
@@ -3835,15 +3806,15 @@ handle_inferior_event (struct execution_control_state *ecs)
          /* Pull the single step breakpoints out of the target.  */
          if (singlestep_breakpoints_inserted_p)
            {
+             if (!ptid_equal (ecs->ptid, inferior_ptid))
+               context_switch (ecs->ptid);
              remove_single_step_breakpoints ();
              singlestep_breakpoints_inserted_p = 0;
            }
 
          ecs->event_thread->control.trap_expected = 0;
 
-         /* Note: We do not call context_switch at this point, as the
-            context is already set up for stepping the original thread.  */
-         switch_to_thread (deferred_step_ptid);
+         context_switch (deferred_step_ptid);
          deferred_step_ptid = null_ptid;
          /* Suppress spurious "Switching to ..." message.  */
          previous_inferior_ptid = inferior_ptid;
@@ -4115,12 +4086,19 @@ handle_inferior_event (struct execution_control_state *ecs)
         skip_inline_frames call would break things.  Fortunately
         that's an extremely unlikely scenario.  */
       if (!pc_at_non_inline_function (aspace, stop_pc, &ecs->ws)
-          && !(ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP
-               && ecs->event_thread->control.trap_expected
-               && pc_at_non_inline_function (aspace,
-                                             ecs->event_thread->prev_pc,
+         && !(ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP
+              && ecs->event_thread->control.trap_expected
+              && pc_at_non_inline_function (aspace,
+                                            ecs->event_thread->prev_pc,
                                             &ecs->ws)))
-       skip_inline_frames (ecs->ptid);
+       {
+         skip_inline_frames (ecs->ptid);
+
+         /* Re-fetch current thread's frame in case that invalidated
+            the frame cache.  */
+         frame = get_current_frame ();
+         gdbarch = get_frame_arch (frame);
+       }
     }
 
   if (ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP
@@ -4168,128 +4146,121 @@ handle_inferior_event (struct execution_control_state *ecs)
      will be made according to the signal handling tables.  */
 
   if (ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP
-      || stop_soon == STOP_QUIETLY || stop_soon == STOP_QUIETLY_NO_SIGSTOP
-      || stop_soon == STOP_QUIETLY_REMOTE)
+      && stop_after_trap)
     {
-      if (ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP
-         && stop_after_trap)
-       {
-          if (debug_infrun)
-           fprintf_unfiltered (gdb_stdlog, "infrun: stopped\n");
-         stop_print_frame = 0;
-         stop_stepping (ecs);
-         return;
-       }
-
-      /* This is originated from start_remote(), start_inferior() and
-         shared libraries hook functions.  */
-      if (stop_soon == STOP_QUIETLY || stop_soon == STOP_QUIETLY_REMOTE)
-       {
-          if (debug_infrun)
-           fprintf_unfiltered (gdb_stdlog, "infrun: quietly stopped\n");
-         stop_stepping (ecs);
-         return;
-       }
+      if (debug_infrun)
+       fprintf_unfiltered (gdb_stdlog, "infrun: stopped\n");
+      stop_print_frame = 0;
+      stop_stepping (ecs);
+      return;
+    }
 
-      /* This originates from attach_command().  We need to overwrite
-        the stop_signal here, because some kernels don't ignore a
-        SIGSTOP in a subsequent ptrace(PTRACE_CONT,SIGSTOP) call.
-        See more comments in inferior.h.  On the other hand, if we
-        get a non-SIGSTOP, report it to the user - assume the backend
-        will handle the SIGSTOP if it should show up later.
-
-        Also consider that the attach is complete when we see a
-        SIGTRAP.  Some systems (e.g. Windows), and stubs supporting
-        target extended-remote report it instead of a SIGSTOP
-        (e.g. gdbserver).  We already rely on SIGTRAP being our
-        signal, so this is no exception.
-
-        Also consider that the attach is complete when we see a
-        GDB_SIGNAL_0.  In non-stop mode, GDB will explicitly tell
-        the target to stop all threads of the inferior, in case the
-        low level attach operation doesn't stop them implicitly.  If
-        they weren't stopped implicitly, then the stub will report a
-        GDB_SIGNAL_0, meaning: stopped for no particular reason
-        other than GDB's request.  */
-      if (stop_soon == STOP_QUIETLY_NO_SIGSTOP
-         && (ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_STOP
-             || ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP
-             || ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_0))
-       {
-         stop_stepping (ecs);
-         ecs->event_thread->suspend.stop_signal = GDB_SIGNAL_0;
-         return;
-       }
+  /* This is originated from start_remote(), start_inferior() and
+     shared libraries hook functions.  */
+  if (stop_soon == STOP_QUIETLY || stop_soon == STOP_QUIETLY_REMOTE)
+    {
+      if (debug_infrun)
+       fprintf_unfiltered (gdb_stdlog, "infrun: quietly stopped\n");
+      stop_stepping (ecs);
+      return;
+    }
 
-      /* See if there is a breakpoint/watchpoint/catchpoint/etc. that
-        handles this event.  */
-      ecs->event_thread->control.stop_bpstat
-       = bpstat_stop_status (get_regcache_aspace (get_current_regcache ()),
-                             stop_pc, ecs->ptid, &ecs->ws);
+  /* This originates from attach_command().  We need to overwrite
+     the stop_signal here, because some kernels don't ignore a
+     SIGSTOP in a subsequent ptrace(PTRACE_CONT,SIGSTOP) call.
+     See more comments in inferior.h.  On the other hand, if we
+     get a non-SIGSTOP, report it to the user - assume the backend
+     will handle the SIGSTOP if it should show up later.
+
+     Also consider that the attach is complete when we see a
+     SIGTRAP.  Some systems (e.g. Windows), and stubs supporting
+     target extended-remote report it instead of a SIGSTOP
+     (e.g. gdbserver).  We already rely on SIGTRAP being our
+     signal, so this is no exception.
+
+     Also consider that the attach is complete when we see a
+     GDB_SIGNAL_0.  In non-stop mode, GDB will explicitly tell
+     the target to stop all threads of the inferior, in case the
+     low level attach operation doesn't stop them implicitly.  If
+     they weren't stopped implicitly, then the stub will report a
+     GDB_SIGNAL_0, meaning: stopped for no particular reason
+     other than GDB's request.  */
+  if (stop_soon == STOP_QUIETLY_NO_SIGSTOP
+      && (ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_STOP
+         || ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP
+         || ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_0))
+    {
+      stop_stepping (ecs);
+      ecs->event_thread->suspend.stop_signal = GDB_SIGNAL_0;
+      return;
+    }
 
-      /* Following in case break condition called a
-        function.  */
-      stop_print_frame = 1;
-
-      /* This is where we handle "moribund" watchpoints.  Unlike
-        software breakpoints traps, hardware watchpoint traps are
-        always distinguishable from random traps.  If no high-level
-        watchpoint is associated with the reported stop data address
-        anymore, then the bpstat does not explain the signal ---
-        simply make sure to ignore it if `stopped_by_watchpoint' is
-        set.  */
-
-      if (debug_infrun
-         && ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP
-         && !bpstat_explains_signal (ecs->event_thread->control.stop_bpstat)
-         && stopped_by_watchpoint)
-       fprintf_unfiltered (gdb_stdlog,
-                           "infrun: no user watchpoint explains "
-                           "watchpoint SIGTRAP, ignoring\n");
+  /* See if there is a breakpoint/watchpoint/catchpoint/etc. that
+     handles this event.  */
+  ecs->event_thread->control.stop_bpstat
+    = bpstat_stop_status (get_regcache_aspace (get_current_regcache ()),
+                         stop_pc, ecs->ptid, &ecs->ws);
 
-      /* NOTE: cagney/2003-03-29: These two checks for a random signal
-         at one stage in the past included checks for an inferior
-         function call's call dummy's return breakpoint.  The original
-         comment, that went with the test, read:
+  /* Following in case break condition called a
+     function.  */
+  stop_print_frame = 1;
 
-         ``End of a stack dummy.  Some systems (e.g. Sony news) give
-         another signal besides SIGTRAP, so check here as well as
-         above.''
+  /* This is where we handle "moribund" watchpoints.  Unlike
+     software breakpoints traps, hardware watchpoint traps are
+     always distinguishable from random traps.  If no high-level
+     watchpoint is associated with the reported stop data address
+     anymore, then the bpstat does not explain the signal ---
+     simply make sure to ignore it if `stopped_by_watchpoint' is
+     set.  */
+
+  if (debug_infrun
+      && ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP
+      && (bpstat_explains_signal (ecs->event_thread->control.stop_bpstat)
+         == BPSTAT_SIGNAL_NO)
+      && stopped_by_watchpoint)
+    fprintf_unfiltered (gdb_stdlog,
+                       "infrun: no user watchpoint explains "
+                       "watchpoint SIGTRAP, ignoring\n");
 
-         If someone ever tries to get call dummys on a
-         non-executable stack to work (where the target would stop
-         with something like a SIGSEGV), then those tests might need
-         to be re-instated.  Given, however, that the tests were only
-         enabled when momentary breakpoints were not being used, I
-         suspect that it won't be the case.
+  /* NOTE: cagney/2003-03-29: These two checks for a random signal
+     at one stage in the past included checks for an inferior
+     function call's call dummy's return breakpoint.  The original
+     comment, that went with the test, read:
 
-         NOTE: kettenis/2004-02-05: Indeed such checks don't seem to
-         be necessary for call dummies on a non-executable stack on
-         SPARC.  */
+     ``End of a stack dummy.  Some systems (e.g. Sony news) give
+     another signal besides SIGTRAP, so check here as well as
+     above.''
 
-      if (ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP)
-       ecs->random_signal
-         = !(bpstat_explains_signal (ecs->event_thread->control.stop_bpstat)
-             || stopped_by_watchpoint
-             || ecs->event_thread->control.trap_expected
-             || (ecs->event_thread->control.step_range_end
-                 && (ecs->event_thread->control.step_resume_breakpoint
-                     == NULL)));
-      else
-       {
-         ecs->random_signal = !bpstat_explains_signal
-                                    (ecs->event_thread->control.stop_bpstat);
-         if (!ecs->random_signal)
-           ecs->event_thread->suspend.stop_signal = GDB_SIGNAL_TRAP;
-       }
-    }
+     If someone ever tries to get call dummys on a
+     non-executable stack to work (where the target would stop
+     with something like a SIGSEGV), then those tests might need
+     to be re-instated.  Given, however, that the tests were only
+     enabled when momentary breakpoints were not being used, I
+     suspect that it won't be the case.
 
-  /* When we reach this point, we've pretty much decided
-     that the reason for stopping must've been a random
-     (unexpected) signal.  */
+     NOTE: kettenis/2004-02-05: Indeed such checks don't seem to
+     be necessary for call dummies on a non-executable stack on
+     SPARC.  */
 
+  if (ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP)
+    ecs->random_signal
+      = !((bpstat_explains_signal (ecs->event_thread->control.stop_bpstat)
+          != BPSTAT_SIGNAL_NO)
+         || stopped_by_watchpoint
+         || ecs->event_thread->control.trap_expected
+         || (ecs->event_thread->control.step_range_end
+             && (ecs->event_thread->control.step_resume_breakpoint
+                 == NULL)));
   else
-    ecs->random_signal = 1;
+    {
+      enum bpstat_signal_value sval;
+
+      sval = bpstat_explains_signal (ecs->event_thread->control.stop_bpstat);
+      ecs->random_signal = (sval == BPSTAT_SIGNAL_NO);
+
+      if (sval == BPSTAT_SIGNAL_HIDE)
+       ecs->event_thread->suspend.stop_signal = GDB_SIGNAL_TRAP;
+    }
 
 process_event_stop_test:
 
@@ -4402,107 +4373,116 @@ process_event_stop_test:
         (leaving the inferior at the step-resume-breakpoint without
         actually executing it).  Either way continue until the
         breakpoint is really hit.  */
-      keep_going (ecs);
-      return;
     }
+  else
+    {
+      /* Handle cases caused by hitting a breakpoint.  */
 
-  /* Handle cases caused by hitting a breakpoint.  */
-  {
-    CORE_ADDR jmp_buf_pc;
-    struct bpstat_what what;
-
-    what = bpstat_what (ecs->event_thread->control.stop_bpstat);
-
-    if (what.call_dummy)
-      {
-       stop_stack_dummy = what.call_dummy;
-      }
+      CORE_ADDR jmp_buf_pc;
+      struct bpstat_what what;
 
-    /* If we hit an internal event that triggers symbol changes, the
-       current frame will be invalidated within bpstat_what (e.g., if
-       we hit an internal solib event).  Re-fetch it.  */
-    frame = get_current_frame ();
-    gdbarch = get_frame_arch (frame);
+      what = bpstat_what (ecs->event_thread->control.stop_bpstat);
 
-    switch (what.main_action)
-      {
-      case BPSTAT_WHAT_SET_LONGJMP_RESUME:
-       /* If we hit the breakpoint at longjmp while stepping, we
-          install a momentary breakpoint at the target of the
-          jmp_buf.  */
+      if (what.call_dummy)
+       {
+         stop_stack_dummy = what.call_dummy;
+       }
 
-       if (debug_infrun)
-         fprintf_unfiltered (gdb_stdlog,
-                             "infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME\n");
+      /* If we hit an internal event that triggers symbol changes, the
+        current frame will be invalidated within bpstat_what (e.g.,
+        if we hit an internal solib event).  Re-fetch it.  */
+      frame = get_current_frame ();
+      gdbarch = get_frame_arch (frame);
 
-       ecs->event_thread->stepping_over_breakpoint = 1;
+      switch (what.main_action)
+       {
+       case BPSTAT_WHAT_SET_LONGJMP_RESUME:
+         /* If we hit the breakpoint at longjmp while stepping, we
+            install a momentary breakpoint at the target of the
+            jmp_buf.  */
 
-       if (what.is_longjmp)
-         {
-           struct value *arg_value;
-
-           /* If we set the longjmp breakpoint via a SystemTap probe,
-              then use it to extract the arguments.  The destination
-              PC is the third argument to the probe.  */
-           arg_value = probe_safe_evaluate_at_pc (frame, 2);
-           if (arg_value)
-             jmp_buf_pc = value_as_address (arg_value);
-           else if (!gdbarch_get_longjmp_target_p (gdbarch)
-                    || !gdbarch_get_longjmp_target (gdbarch,
-                                                    frame, &jmp_buf_pc))
-             {
-               if (debug_infrun)
-                 fprintf_unfiltered (gdb_stdlog,
-                                     "infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME "
-                                     "(!gdbarch_get_longjmp_target)\n");
-               keep_going (ecs);
-               return;
-             }
+         if (debug_infrun)
+           fprintf_unfiltered (gdb_stdlog,
+                               "infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME\n");
 
-           /* We're going to replace the current step-resume breakpoint
-              with a longjmp-resume breakpoint.  */
-           delete_step_resume_breakpoint (ecs->event_thread);
+         ecs->event_thread->stepping_over_breakpoint = 1;
 
-           /* Insert a breakpoint at resume address.  */
-           insert_longjmp_resume_breakpoint (gdbarch, jmp_buf_pc);
-         }
-       else
-         check_exception_resume (ecs, frame);
-       keep_going (ecs);
-       return;
+         if (what.is_longjmp)
+           {
+             struct value *arg_value;
+
+             /* If we set the longjmp breakpoint via a SystemTap
+                probe, then use it to extract the arguments.  The
+                destination PC is the third argument to the
+                probe.  */
+             arg_value = probe_safe_evaluate_at_pc (frame, 2);
+             if (arg_value)
+               jmp_buf_pc = value_as_address (arg_value);
+             else if (!gdbarch_get_longjmp_target_p (gdbarch)
+                      || !gdbarch_get_longjmp_target (gdbarch,
+                                                      frame, &jmp_buf_pc))
+               {
+                 if (debug_infrun)
+                   fprintf_unfiltered (gdb_stdlog,
+                                       "infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME "
+                                       "(!gdbarch_get_longjmp_target)\n");
+                 keep_going (ecs);
+                 return;
+               }
 
-      case BPSTAT_WHAT_CLEAR_LONGJMP_RESUME:
-        if (debug_infrun)
-         fprintf_unfiltered (gdb_stdlog,
-                             "infrun: BPSTAT_WHAT_CLEAR_LONGJMP_RESUME\n");
+             /* Insert a breakpoint at resume address.  */
+             insert_longjmp_resume_breakpoint (gdbarch, jmp_buf_pc);
+           }
+         else
+           check_exception_resume (ecs, frame);
+         keep_going (ecs);
+         return;
 
-       if (what.is_longjmp)
-         {
-           gdb_assert (ecs->event_thread->control.step_resume_breakpoint
-                       != NULL);
-           delete_step_resume_breakpoint (ecs->event_thread);
-         }
-       else
+       case BPSTAT_WHAT_CLEAR_LONGJMP_RESUME:
          {
+           struct frame_info *init_frame;
+
            /* There are several cases to consider.
 
               1. The initiating frame no longer exists.  In this case
-              we must stop, because the exception has gone too far.
+              we must stop, because the exception or longjmp has gone
+              too far.
 
               2. The initiating frame exists, and is the same as the
-              current frame.  We stop, because the exception has been
-              caught.
+              current frame.  We stop, because the exception or
+              longjmp has been caught.
 
               3. The initiating frame exists and is different from
-              the current frame.  This means the exception has been
-              caught beneath the initiating frame, so keep going.  */
-           struct frame_info *init_frame
-             = frame_find_by_id (ecs->event_thread->initiating_frame);
+              the current frame.  This means the exception or longjmp
+              has been caught beneath the initiating frame, so keep
+              going.
+
+              4. longjmp breakpoint has been placed just to protect
+              against stale dummy frames and user is not interested
+              in stopping around longjmps.  */
+
+           if (debug_infrun)
+             fprintf_unfiltered (gdb_stdlog,
+                                 "infrun: BPSTAT_WHAT_CLEAR_LONGJMP_RESUME\n");
 
            gdb_assert (ecs->event_thread->control.exception_resume_breakpoint
                        != NULL);
            delete_exception_resume_breakpoint (ecs->event_thread);
 
+           if (what.is_longjmp)
+             {
+               check_longjmp_breakpoint_for_call_dummy (ecs->event_thread->num);
+
+               if (!frame_id_p (ecs->event_thread->initiating_frame))
+                 {
+                   /* Case 4.  */
+                   keep_going (ecs);
+                   return;
+                 }
+             }
+
+           init_frame = frame_find_by_id (ecs->event_thread->initiating_frame);
+
            if (init_frame)
              {
                struct frame_id current_id
@@ -4523,97 +4503,97 @@ process_event_stop_test:
            /* For Cases 1 and 2, remove the step-resume breakpoint,
               if it exists.  */
            delete_step_resume_breakpoint (ecs->event_thread);
+
+           ecs->event_thread->control.stop_step = 1;
+           print_end_stepping_range_reason ();
+           stop_stepping (ecs);
          }
+         return;
 
-       ecs->event_thread->control.stop_step = 1;
-       print_end_stepping_range_reason ();
-       stop_stepping (ecs);
-       return;
-
-      case BPSTAT_WHAT_SINGLE:
-        if (debug_infrun)
-         fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_SINGLE\n");
-       ecs->event_thread->stepping_over_breakpoint = 1;
-       /* Still need to check other stuff, at least the case
-          where we are stepping and step out of the right range.  */
-       break;
+       case BPSTAT_WHAT_SINGLE:
+         if (debug_infrun)
+           fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_SINGLE\n");
+         ecs->event_thread->stepping_over_breakpoint = 1;
+         /* Still need to check other stuff, at least the case where
+            we are stepping and step out of the right range.  */
+         break;
 
-      case BPSTAT_WHAT_STEP_RESUME:
-        if (debug_infrun)
-         fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_STEP_RESUME\n");
+       case BPSTAT_WHAT_STEP_RESUME:
+         if (debug_infrun)
+           fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_STEP_RESUME\n");
 
-       delete_step_resume_breakpoint (ecs->event_thread);
-       if (ecs->event_thread->control.proceed_to_finish
-           && execution_direction == EXEC_REVERSE)
-         {
-           struct thread_info *tp = ecs->event_thread;
-
-           /* We are finishing a function in reverse, and just hit
-              the step-resume breakpoint at the start address of the
-              function, and we're almost there -- just need to back
-              up by one more single-step, which should take us back
-              to the function call.  */
-           tp->control.step_range_start = tp->control.step_range_end = 1;
-           keep_going (ecs);
-           return;
-         }
-       fill_in_stop_func (gdbarch, ecs);
-       if (stop_pc == ecs->stop_func_start
-           && execution_direction == EXEC_REVERSE)
-         {
-           /* We are stepping over a function call in reverse, and
-              just hit the step-resume breakpoint at the start
-              address of the function.  Go back to single-stepping,
-              which should take us back to the function call.  */
-           ecs->event_thread->stepping_over_breakpoint = 1;
-           keep_going (ecs);
-           return;
-         }
-       break;
+         delete_step_resume_breakpoint (ecs->event_thread);
+         if (ecs->event_thread->control.proceed_to_finish
+             && execution_direction == EXEC_REVERSE)
+           {
+             struct thread_info *tp = ecs->event_thread;
+
+             /* We are finishing a function in reverse, and just hit
+                the step-resume breakpoint at the start address of
+                the function, and we're almost there -- just need to
+                back up by one more single-step, which should take us
+                back to the function call.  */
+             tp->control.step_range_start = tp->control.step_range_end = 1;
+             keep_going (ecs);
+             return;
+           }
+         fill_in_stop_func (gdbarch, ecs);
+         if (stop_pc == ecs->stop_func_start
+             && execution_direction == EXEC_REVERSE)
+           {
+             /* We are stepping over a function call in reverse, and
+                just hit the step-resume breakpoint at the start
+                address of the function.  Go back to single-stepping,
+                which should take us back to the function call.  */
+             ecs->event_thread->stepping_over_breakpoint = 1;
+             keep_going (ecs);
+             return;
+           }
+         break;
 
-      case BPSTAT_WHAT_STOP_NOISY:
-        if (debug_infrun)
-         fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_STOP_NOISY\n");
-       stop_print_frame = 1;
+       case BPSTAT_WHAT_STOP_NOISY:
+         if (debug_infrun)
+           fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_STOP_NOISY\n");
+         stop_print_frame = 1;
 
-       /* We are about to nuke the step_resume_breakpointt via the
-          cleanup chain, so no need to worry about it here.  */
+         /* We are about to nuke the step_resume_breakpointt via the
+            cleanup chain, so no need to worry about it here.  */
 
-       stop_stepping (ecs);
-       return;
+         stop_stepping (ecs);
+         return;
 
-      case BPSTAT_WHAT_STOP_SILENT:
-        if (debug_infrun)
-         fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_STOP_SILENT\n");
-       stop_print_frame = 0;
+       case BPSTAT_WHAT_STOP_SILENT:
+         if (debug_infrun)
+           fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_STOP_SILENT\n");
+         stop_print_frame = 0;
 
-       /* We are about to nuke the step_resume_breakpoin via the
-          cleanup chain, so no need to worry about it here.  */
+         /* We are about to nuke the step_resume_breakpoin via the
+            cleanup chain, so no need to worry about it here.  */
 
-       stop_stepping (ecs);
-       return;
+         stop_stepping (ecs);
+         return;
 
-      case BPSTAT_WHAT_HP_STEP_RESUME:
-        if (debug_infrun)
-         fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_HP_STEP_RESUME\n");
+       case BPSTAT_WHAT_HP_STEP_RESUME:
+         if (debug_infrun)
+           fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_HP_STEP_RESUME\n");
 
-       delete_step_resume_breakpoint (ecs->event_thread);
-       if (ecs->event_thread->step_after_step_resume_breakpoint)
-         {
-           /* Back when the step-resume breakpoint was inserted, we
-              were trying to single-step off a breakpoint.  Go back
-              to doing that.  */
-           ecs->event_thread->step_after_step_resume_breakpoint = 0;
-           ecs->event_thread->stepping_over_breakpoint = 1;
-           keep_going (ecs);
-           return;
-         }
-       break;
+         delete_step_resume_breakpoint (ecs->event_thread);
+         if (ecs->event_thread->step_after_step_resume_breakpoint)
+           {
+             /* Back when the step-resume breakpoint was inserted, we
+                were trying to single-step off a breakpoint.  Go back
+                to doing that.  */
+             ecs->event_thread->step_after_step_resume_breakpoint = 0;
+             ecs->event_thread->stepping_over_breakpoint = 1;
+             keep_going (ecs);
+             return;
+           }
+         break;
 
-      case BPSTAT_WHAT_KEEP_CHECKING:
-       break;
-      }
-  }
+       case BPSTAT_WHAT_KEEP_CHECKING:
+         break;
+       }
+    }
 
   /* We come here if we hit a breakpoint but should not
      stop for it.  Possibly we also were stepping
@@ -4941,14 +4921,22 @@ process_event_stop_test:
 
          if (execution_direction == EXEC_REVERSE)
            {
-             struct symtab_and_line sr_sal;
-
-             /* Normal function call return (static or dynamic).  */
-             init_sal (&sr_sal);
-             sr_sal.pc = ecs->stop_func_start;
-             sr_sal.pspace = get_frame_program_space (frame);
-             insert_step_resume_breakpoint_at_sal (gdbarch,
-                                                   sr_sal, null_frame_id);
+             /* If we're already at the start of the function, we've either
+                just stepped backward into a single instruction function,
+                or stepped back out of a signal handler to the first instruction
+                of the function.  Just keep going, which will single-step back
+                to the caller.  */
+             if (ecs->stop_func_start != stop_pc)
+               {
+                 struct symtab_and_line sr_sal;
+
+                 /* Normal function call return (static or dynamic).  */
+                 init_sal (&sr_sal);
+                 sr_sal.pc = ecs->stop_func_start;
+                 sr_sal.pspace = get_frame_program_space (frame);
+                 insert_step_resume_breakpoint_at_sal (gdbarch,
+                                                       sr_sal, null_frame_id);
+               }
            }
          else
            insert_step_resume_breakpoint_at_caller (frame);
@@ -4994,7 +4982,8 @@ process_event_stop_test:
 
        tmp_sal = find_pc_line (ecs->stop_func_start, 0);
        if (tmp_sal.line != 0
-           && !function_pc_is_marked_for_skip (ecs->stop_func_start))
+           && !function_name_is_marked_for_skip (ecs->stop_func_name,
+                                                 &tmp_sal))
          {
            if (execution_direction == EXEC_REVERSE)
              handle_step_into_function_backward (gdbarch, ecs);
@@ -5018,15 +5007,23 @@ process_event_stop_test:
 
       if (execution_direction == EXEC_REVERSE)
        {
-         /* 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;
+         /* If we're already at the start of the function, we've either just
+            stepped backward into a single instruction function without line
+            number info, or stepped back out of a signal handler to the first
+            instruction of the function without line number info.  Just keep
+            going, which will single-step back to the caller.  */
+         if (ecs->stop_func_start != stop_pc)
+           {
+             /* 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);
-         sr_sal.pc = ecs->stop_func_start;
-         sr_sal.pspace = get_frame_program_space (frame);
-         insert_step_resume_breakpoint_at_sal (gdbarch,
-                                               sr_sal, null_frame_id);
+             init_sal (&sr_sal);
+             sr_sal.pc = ecs->stop_func_start;
+             sr_sal.pspace = get_frame_program_space (frame);
+             insert_step_resume_breakpoint_at_sal (gdbarch,
+                                                   sr_sal, null_frame_id);
+           }
        }
       else
        /* Set a breakpoint at callee's return address (the address
@@ -5497,17 +5494,17 @@ insert_step_resume_breakpoint_at_caller (struct frame_info *next_frame)
 static void
 insert_longjmp_resume_breakpoint (struct gdbarch *gdbarch, CORE_ADDR pc)
 {
-  /* There should never be more than one step-resume or longjmp-resume
-     breakpoint per thread, so we should never be setting a new
+  /* There should never be more than one longjmp-resume breakpoint per
+     thread, so we should never be setting a new
      longjmp_resume_breakpoint when one is already active.  */
-  gdb_assert (inferior_thread ()->control.step_resume_breakpoint == NULL);
+  gdb_assert (inferior_thread ()->control.exception_resume_breakpoint == NULL);
 
   if (debug_infrun)
     fprintf_unfiltered (gdb_stdlog,
                        "infrun: inserting longjmp-resume breakpoint at %s\n",
                        paddress (gdbarch, pc));
 
-  inferior_thread ()->control.step_resume_breakpoint =
+  inferior_thread ()->control.exception_resume_breakpoint =
     set_momentary_breakpoint_at_pc (gdbarch, pc, bp_longjmp_resume);
 }
 
@@ -5563,7 +5560,6 @@ insert_exception_resume_breakpoint (struct thread_info *tp,
 static void
 insert_exception_resume_from_probe (struct thread_info *tp,
                                    const struct probe *probe,
-                                   struct objfile *objfile,
                                    struct frame_info *frame)
 {
   struct value *arg_value;
@@ -5579,7 +5575,7 @@ insert_exception_resume_from_probe (struct thread_info *tp,
   if (debug_infrun)
     fprintf_unfiltered (gdb_stdlog,
                        "infrun: exception resume at %s\n",
-                       paddress (get_objfile_arch (objfile),
+                       paddress (get_objfile_arch (probe->objfile),
                                  handler));
 
   bp = set_momentary_breakpoint_at_pc (get_frame_arch (frame),
@@ -5597,7 +5593,6 @@ check_exception_resume (struct execution_control_state *ecs,
                        struct frame_info *frame)
 {
   volatile struct gdb_exception e;
-  struct objfile *objfile;
   const struct probe *probe;
   struct symbol *func;
 
@@ -5605,11 +5600,10 @@ check_exception_resume (struct execution_control_state *ecs,
      SystemTap probe point.  If so, the probe has two arguments: the
      CFA and the HANDLER.  We ignore the CFA, extract the handler, and
      set a breakpoint there.  */
-  probe = find_probe_by_pc (get_frame_pc (frame), &objfile);
+  probe = find_probe_by_pc (get_frame_pc (frame));
   if (probe)
     {
-      insert_exception_resume_from_probe (ecs->event_thread, probe,
-                                         objfile, frame);
+      insert_exception_resume_from_probe (ecs->event_thread, probe, frame);
       return;
     }
 
@@ -6217,7 +6211,8 @@ signal_cache_update (int signo)
 
   signal_pass[signo] = (signal_stop[signo] == 0
                        && signal_print[signo] == 0
-                       && signal_program[signo] == 1);
+                       && signal_program[signo] == 1
+                       && signal_catch[signo] == 0);
 }
 
 int
@@ -6250,6 +6245,20 @@ signal_pass_update (int signo, int state)
   return ret;
 }
 
+/* Update the global 'signal_catch' from INFO and notify the
+   target.  */
+
+void
+signal_catch_update (const unsigned int *info)
+{
+  int i;
+
+  for (i = 0; i < GDB_SIGNAL_LAST; ++i)
+    signal_catch[i] = info[i] > 0;
+  signal_cache_update (-1);
+  target_pass_signals ((int) GDB_SIGNAL_LAST, signal_pass);
+}
+
 static void
 sig_print_header (void)
 {
@@ -6457,6 +6466,36 @@ Are you sure you want to change it? "),
   do_cleanups (old_chain);
 }
 
+/* Complete the "handle" command.  */
+
+static VEC (char_ptr) *
+handle_completer (struct cmd_list_element *ignore,
+                 char *text, char *word)
+{
+  VEC (char_ptr) *vec_signals, *vec_keywords, *return_val;
+  static const char * const keywords[] =
+    {
+      "all",
+      "stop",
+      "ignore",
+      "print",
+      "pass",
+      "nostop",
+      "noignore",
+      "noprint",
+      "nopass",
+      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;
+}
+
 static void
 xdb_handle_command (char *args, int from_tty)
 {
@@ -6682,7 +6721,9 @@ siginfo_make_value (struct gdbarch *gdbarch, struct internalvar *var,
 struct infcall_suspend_state
 {
   struct thread_suspend_state thread_suspend;
+#if 0 /* Currently unused and empty structures are not valid C.  */
   struct inferior_suspend_state inferior_suspend;
+#endif
 
   /* Other fields:  */
   CORE_ADDR stop_pc;
@@ -6702,7 +6743,9 @@ save_infcall_suspend_state (void)
 {
   struct infcall_suspend_state *inf_state;
   struct thread_info *tp = inferior_thread ();
+#if 0
   struct inferior *inf = current_inferior ();
+#endif
   struct regcache *regcache = get_current_regcache ();
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
   gdb_byte *siginfo_data = NULL;
@@ -6736,7 +6779,9 @@ save_infcall_suspend_state (void)
     }
 
   inf_state->thread_suspend = tp->suspend;
+#if 0 /* Currently unused and empty structures are not valid C.  */
   inf_state->inferior_suspend = inf->suspend;
+#endif
 
   /* run_inferior_call will not use the signal due to its `proceed' call with
      GDB_SIGNAL_0 anyway.  */
@@ -6755,23 +6800,26 @@ void
 restore_infcall_suspend_state (struct infcall_suspend_state *inf_state)
 {
   struct thread_info *tp = inferior_thread ();
+#if 0
   struct inferior *inf = current_inferior ();
+#endif
   struct regcache *regcache = get_current_regcache ();
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
 
   tp->suspend = inf_state->thread_suspend;
+#if 0 /* Currently unused and empty structures are not valid C.  */
   inf->suspend = inf_state->inferior_suspend;
+#endif
 
   stop_pc = inf_state->stop_pc;
 
   if (inf_state->siginfo_gdbarch == gdbarch)
     {
       struct type *type = gdbarch_get_siginfo_type (gdbarch);
-      size_t len = TYPE_LENGTH (type);
 
       /* Errors ignored.  */
       target_write (&current_target, TARGET_OBJECT_SIGNAL_INFO, NULL,
-                   inf_state->siginfo_data, 0, len);
+                   inf_state->siginfo_data, 0, TYPE_LENGTH (type));
     }
 
   /* The inferior can be gone if the user types "print exit(0)"
@@ -7094,27 +7142,39 @@ _initialize_infrun (void)
 {
   int i;
   int numsigs;
+  struct cmd_list_element *c;
 
   add_info ("signals", signals_info, _("\
 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);
 
-  add_com ("handle", class_run, handle_command, _("\
-Specify how to handle a signal.\n\
+  c = add_com ("handle", class_run, handle_command, _("\
+Specify how to handle signals.\n\
+Usage: handle SIGNAL [ACTIONS]\n\
 Args are signals and actions to apply to those signals.\n\
+If no actions are specified, the current settings for the specified signals\n\
+will be displayed instead.\n\
+\n\
 Symbolic signals (e.g. SIGSEGV) are recommended but numeric signals\n\
 from 1-15 are allowed for compatibility with old versions of GDB.\n\
 Numeric ranges may be specified with the form LOW-HIGH (e.g. 1-5).\n\
 The special arg \"all\" is recognized to mean all signals except those\n\
 used by the debugger, typically SIGTRAP and SIGINT.\n\
+\n\
 Recognized actions include \"stop\", \"nostop\", \"print\", \"noprint\",\n\
 \"pass\", \"nopass\", \"ignore\", or \"noignore\".\n\
 Stop means reenter debugger if this signal happens (implies print).\n\
 Print means print a message if this signal happens.\n\
 Pass means let program see this signal; otherwise program doesn't know.\n\
 Ignore is a synonym for nopass and noignore is a synonym for pass.\n\
-Pass and Stop may be combined."));
+Pass and Stop may be combined.\n\
+\n\
+Multiple signals may be specified.  Signal numbers and signal names\n\
+may be interspersed with actions, with the actions being performed for\n\
+all signals cumulatively specified."));
+  set_cmd_completer (c, handle_completer);
+
   if (xdb_commands)
     {
       add_com ("lz", class_info, signals_info, _("\
@@ -7145,13 +7205,13 @@ There is no `stop' command, but you can set a hook on `stop'.\n\
 This allows you to set a list of commands to be run each time execution\n\
 of the program stops."), &cmdlist);
 
-  add_setshow_zinteger_cmd ("infrun", class_maintenance, &debug_infrun, _("\
+  add_setshow_zuinteger_cmd ("infrun", class_maintenance, &debug_infrun, _("\
 Set inferior debugging."), _("\
 Show inferior debugging."), _("\
 When non-zero, inferior specific debugging is enabled."),
-                           NULL,
-                           show_debug_infrun,
-                           &setdebuglist, &showdebuglist);
+                            NULL,
+                            show_debug_infrun,
+                            &setdebuglist, &showdebuglist);
 
   add_setshow_boolean_cmd ("displaced", class_maintenance,
                           &debug_displaced, _("\
@@ -7188,6 +7248,8 @@ leave it stopped or free to run as needed."),
     xmalloc (sizeof (signal_print[0]) * numsigs);
   signal_program = (unsigned char *)
     xmalloc (sizeof (signal_program[0]) * numsigs);
+  signal_catch = (unsigned char *)
+    xmalloc (sizeof (signal_catch[0]) * numsigs);
   signal_pass = (unsigned char *)
     xmalloc (sizeof (signal_program[0]) * numsigs);
   for (i = 0; i < numsigs; i++)
@@ -7195,6 +7257,7 @@ leave it stopped or free to run as needed."),
       signal_stop[i] = 1;
       signal_print[i] = 1;
       signal_program[i] = 1;
+      signal_catch[i] = 0;
     }
 
   /* Signals caused by debugger's own actions
@@ -7320,9 +7383,8 @@ function is skipped and the step command stops at a different source line."),
                           show_step_stop_if_no_debug,
                           &setlist, &showlist);
 
-  add_setshow_enum_cmd ("displaced-stepping", class_run,
-                       can_use_displaced_stepping_enum,
-                       &can_use_displaced_stepping, _("\
+  add_setshow_auto_boolean_cmd ("displaced-stepping", class_run,
+                               &can_use_displaced_stepping, _("\
 Set debugger's willingness to use displaced stepping."), _("\
 Show debugger's willingness to use displaced stepping."), _("\
 If on, gdb will use displaced stepping to step over breakpoints if it is\n\
@@ -7331,9 +7393,9 @@ stepping to step over breakpoints, even if such is supported by the target\n\
 architecture.  If auto (which is the default), gdb will use displaced stepping\n\
 if the target architecture supports it and non-stop mode is active, but will not\n\
 use it in all-stop mode (see help set non-stop)."),
-                       NULL,
-                       show_can_use_displaced_stepping,
-                       &setlist, &showlist);
+                               NULL,
+                               show_can_use_displaced_stepping,
+                               &setlist, &showlist);
 
   add_setshow_enum_cmd ("exec-direction", class_run, exec_direction_names,
                        &exec_direction, _("Set direction of execution.\n\
This page took 0.076732 seconds and 4 git commands to generate.