2009-10-20 Michael Snyder <msnyder@msnyder-server.eng.vmware.com>
[deliverable/binutils-gdb.git] / gdb / infrun.c
index 167252adca72eb7e6b57cf9a9ff6bcc99ea07583..a2916b43bb29e39169000e2811612241c2d3317f 100644 (file)
@@ -49,6 +49,8 @@
 #include "mi/mi-common.h"
 #include "event-top.h"
 #include "record.h"
+#include "inline-frame.h"
+#include "jit.h"
 
 /* Prototypes for local functions */
 
@@ -107,6 +109,9 @@ int sync_execution = 0;
 
 static ptid_t previous_inferior_ptid;
 
+/* Default behavior is to detach newly forked processes (legacy).  */
+int detach_fork = 1;
+
 int debug_displaced = 0;
 static void
 show_debug_displaced (struct ui_file *file, int from_tty,
@@ -209,7 +214,7 @@ static unsigned char *signal_program;
 
 /* Value to pass to target_resume() to cause all threads to resume */
 
-#define RESUME_ALL (pid_to_ptid (-1))
+#define RESUME_ALL minus_one_ptid
 
 /* Command list pointer for the "stop" placeholder.  */
 
@@ -459,6 +464,198 @@ follow_inferior_reset_breakpoints (void)
   insert_breakpoints ();
 }
 
+/* The child has exited or execed: resume threads of the parent the
+   user wanted to be executing.  */
+
+static int
+proceed_after_vfork_done (struct thread_info *thread,
+                         void *arg)
+{
+  int pid = * (int *) arg;
+
+  if (ptid_get_pid (thread->ptid) == pid
+      && is_running (thread->ptid)
+      && !is_executing (thread->ptid)
+      && !thread->stop_requested
+      && thread->stop_signal == TARGET_SIGNAL_0)
+    {
+      if (debug_infrun)
+       fprintf_unfiltered (gdb_stdlog,
+                           "infrun: resuming vfork parent thread %s\n",
+                           target_pid_to_str (thread->ptid));
+
+      switch_to_thread (thread->ptid);
+      clear_proceed_status ();
+      proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0);
+    }
+
+  return 0;
+}
+
+/* Called whenever we notice an exec or exit event, to handle
+   detaching or resuming a vfork parent.  */
+
+static void
+handle_vfork_child_exec_or_exit (int exec)
+{
+  struct inferior *inf = current_inferior ();
+
+  if (inf->vfork_parent)
+    {
+      int resume_parent = -1;
+
+      /* This exec or exit marks the end of the shared memory region
+        between the parent and the child.  If the user wanted to
+        detach from the parent, now is the time.  */
+
+      if (inf->vfork_parent->pending_detach)
+       {
+         struct thread_info *tp;
+         struct cleanup *old_chain;
+         struct program_space *pspace;
+         struct address_space *aspace;
+
+         /* follow-fork child, detach-on-fork on */
+
+         old_chain = make_cleanup_restore_current_thread ();
+
+         /* We're letting loose of the parent.  */
+         tp = any_live_thread_of_process (inf->vfork_parent->pid);
+         switch_to_thread (tp->ptid);
+
+         /* We're about to detach from the parent, which implicitly
+            removes breakpoints from its address space.  There's a
+            catch here: we want to reuse the spaces for the child,
+            but, parent/child are still sharing the pspace at this
+            point, although the exec in reality makes the kernel give
+            the child a fresh set of new pages.  The problem here is
+            that the breakpoints module being unaware of this, would
+            likely chose the child process to write to the parent
+            address space.  Swapping the child temporarily away from
+            the spaces has the desired effect.  Yes, this is "sort
+            of" a hack.  */
+
+         pspace = inf->pspace;
+         aspace = inf->aspace;
+         inf->aspace = NULL;
+         inf->pspace = NULL;
+
+         if (debug_infrun || info_verbose)
+           {
+             target_terminal_ours ();
+
+             if (exec)
+               fprintf_filtered (gdb_stdlog,
+                                 "Detaching vfork parent process %d after child exec.\n",
+                                 inf->vfork_parent->pid);
+             else
+               fprintf_filtered (gdb_stdlog,
+                                 "Detaching vfork parent process %d after child exit.\n",
+                                 inf->vfork_parent->pid);
+           }
+
+         target_detach (NULL, 0);
+
+         /* Put it back.  */
+         inf->pspace = pspace;
+         inf->aspace = aspace;
+
+         do_cleanups (old_chain);
+       }
+      else if (exec)
+       {
+         /* We're staying attached to the parent, so, really give the
+            child a new address space.  */
+         inf->pspace = add_program_space (maybe_new_address_space ());
+         inf->aspace = inf->pspace->aspace;
+         inf->removable = 1;
+         set_current_program_space (inf->pspace);
+
+         resume_parent = inf->vfork_parent->pid;
+
+         /* Break the bonds.  */
+         inf->vfork_parent->vfork_child = NULL;
+       }
+      else
+       {
+         struct cleanup *old_chain;
+         struct program_space *pspace;
+
+         /* If this is a vfork child exiting, then the pspace and
+            aspaces were shared with the parent.  Since we're
+            reporting the process exit, we'll be mourning all that is
+            found in the address space, and switching to null_ptid,
+            preparing to start a new inferior.  But, since we don't
+            want to clobber the parent's address/program spaces, we
+            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;
+
+         /* This inferior is dead, so avoid giving the breakpoints
+            module the option to write through to it (cloning a
+            program space resets breakpoints).  */
+         inf->aspace = NULL;
+         inf->pspace = NULL;
+         pspace = add_program_space (maybe_new_address_space ());
+         set_current_program_space (pspace);
+         inf->removable = 1;
+         clone_program_space (pspace, inf->vfork_parent->pspace);
+         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;
+       }
+
+      inf->vfork_parent = NULL;
+
+      gdb_assert (current_program_space == inf->pspace);
+
+      if (non_stop && resume_parent != -1)
+       {
+         /* If the user wanted the parent to be running, let it go
+            free now.  */
+         struct cleanup *old_chain = make_cleanup_restore_current_thread ();
+
+         if (debug_infrun)
+           fprintf_unfiltered (gdb_stdlog, "infrun: resuming vfork parent process %d\n",
+                               resume_parent);
+
+         iterate_over_threads (proceed_after_vfork_done, &resume_parent);
+
+         do_cleanups (old_chain);
+       }
+    }
+}
+
+/* Enum strings for "set|show displaced-stepping".  */
+
+static const char follow_exec_mode_new[] = "new";
+static const char follow_exec_mode_same[] = "same";
+static const char *follow_exec_mode_names[] =
+{
+  follow_exec_mode_new,
+  follow_exec_mode_same,
+  NULL,
+};
+
+static const char *follow_exec_mode_string = follow_exec_mode_same;
+static void
+show_follow_exec_mode_string (struct ui_file *file, int from_tty,
+                             struct cmd_list_element *c, const char *value)
+{
+  fprintf_filtered (file, _("Follow exec mode is \"%s\".\n"),  value);
+}
+
 /* EXECD_PATHNAME is assumed to be non-NULL. */
 
 static void
@@ -466,6 +663,7 @@ follow_exec (ptid_t pid, char *execd_pathname)
 {
   struct target_ops *tgt;
   struct thread_info *th = inferior_thread ();
+  struct inferior *inf = current_inferior ();
 
   /* This is an exec event that we actually wish to pay attention to.
      Refresh our symbol table to the newly exec'd program, remove any
@@ -487,6 +685,9 @@ follow_exec (ptid_t pid, char *execd_pathname)
      that may write the bp's "shadow contents" (the instruction
      value that was overwritten witha TRAP instruction).  Since
      we now have a new a.out, those shadow contents aren't valid. */
+
+  mark_breakpoints_out ();
+
   update_breakpoints_after_exec ();
 
   /* If there was one, it's gone now.  We cannot truly step-to-next
@@ -504,7 +705,9 @@ follow_exec (ptid_t pid, char *execd_pathname)
   th->stop_requested = 0;
 
   /* What is this a.out's name? */
-  printf_unfiltered (_("Executing new program: %s\n"), execd_pathname);
+  printf_unfiltered (_("%s is executing new program: %s\n"),
+                    target_pid_to_str (inferior_ptid),
+                    execd_pathname);
 
   /* We've followed the inferior through an exec.  Therefore, the
      inferior has essentially been killed & reborn. */
@@ -523,9 +726,6 @@ follow_exec (ptid_t pid, char *execd_pathname)
       execd_pathname = name;
     }
 
-  /* That a.out is now the one to use. */
-  exec_file_attach (execd_pathname, 0);
-
   /* Reset the shared library package.  This ensures that we get a
      shlib event when the child reaches "_start", at which point the
      dld will have had a chance to initialize the child.  */
@@ -534,6 +734,30 @@ follow_exec (ptid_t pid, char *execd_pathname)
      previous incarnation of this process.  */
   no_shared_libraries (NULL, 0);
 
+  if (follow_exec_mode_string == follow_exec_mode_new)
+    {
+      struct program_space *pspace;
+      struct inferior *new_inf;
+
+      /* The user wants to keep the old inferior and program spaces
+        around.  Create a new fresh one, and switch to it.  */
+
+      inf = add_inferior (current_inferior ()->pid);
+      pspace = add_program_space (maybe_new_address_space ());
+      inf->pspace = pspace;
+      inf->aspace = pspace->aspace;
+
+      exit_inferior_num_silent (current_inferior ()->num);
+
+      set_current_inferior (inf);
+      set_current_program_space (pspace);
+    }
+
+  gdb_assert (current_program_space == inf->pspace);
+
+  /* That a.out is now the one to use. */
+  exec_file_attach (execd_pathname, 0);
+
   /* Load the main file's symbols.  */
   symbol_file_add_main (execd_pathname, 0);
 
@@ -543,6 +767,8 @@ follow_exec (ptid_t pid, char *execd_pathname)
   solib_create_inferior_hook ();
 #endif
 
+  jit_inferior_created_hook ();
+
   /* Reinsert all breakpoints.  (Those which were symbolic have
      been reset to the proper address in the new a.out, thanks
      to symbol_file_command...) */
@@ -865,8 +1091,8 @@ displaced_step_prepare (ptid_t ptid)
   read_memory (copy, displaced_step_saved_copy, len);
   if (debug_displaced)
     {
-      fprintf_unfiltered (gdb_stdlog, "displaced: saved 0x%s: ",
-                         paddr_nz (copy));
+      fprintf_unfiltered (gdb_stdlog, "displaced: saved %s: ",
+                         paddress (gdbarch, copy));
       displaced_step_dump_bytes (gdb_stdlog, displaced_step_saved_copy, len);
     };
 
@@ -894,8 +1120,8 @@ displaced_step_prepare (ptid_t ptid)
   do_cleanups (old_cleanups);
 
   if (debug_displaced)
-    fprintf_unfiltered (gdb_stdlog, "displaced: displaced pc to 0x%s\n",
-                       paddr_nz (copy));
+    fprintf_unfiltered (gdb_stdlog, "displaced: displaced pc to %s\n",
+                       paddress (gdbarch, copy));
 
   return 1;
 }
@@ -927,8 +1153,9 @@ displaced_step_fixup (ptid_t event_ptid, enum target_signal signal)
     write_memory_ptid (displaced_step_ptid, displaced_step_copy,
                       displaced_step_saved_copy, len);
     if (debug_displaced)
-      fprintf_unfiltered (gdb_stdlog, "displaced: restored 0x%s\n",
-                          paddr_nz (displaced_step_copy));
+      fprintf_unfiltered (gdb_stdlog, "displaced: restored %s\n",
+                          paddress (displaced_step_gdbarch,
+                                   displaced_step_copy));
   }
 
   /* Did the instruction complete successfully?  */
@@ -961,7 +1188,10 @@ displaced_step_fixup (ptid_t event_ptid, enum target_signal signal)
     {
       struct displaced_step_request *head;
       ptid_t ptid;
+      struct regcache *regcache;
+      struct gdbarch *gdbarch;
       CORE_ADDR actual_pc;
+      struct address_space *aspace;
 
       head = displaced_step_request_queue;
       ptid = head->ptid;
@@ -970,9 +1200,11 @@ displaced_step_fixup (ptid_t event_ptid, enum target_signal signal)
 
       context_switch (ptid);
 
-      actual_pc = regcache_read_pc (get_thread_regcache (ptid));
+      regcache = get_thread_regcache (ptid);
+      actual_pc = regcache_read_pc (regcache);
+      aspace = get_regcache_aspace (regcache);
 
-      if (breakpoint_here_p (actual_pc))
+      if (breakpoint_here_p (aspace, actual_pc))
        {
          if (debug_displaced)
            fprintf_unfiltered (gdb_stdlog,
@@ -981,17 +1213,24 @@ displaced_step_fixup (ptid_t event_ptid, enum target_signal signal)
 
          displaced_step_prepare (ptid);
 
+         gdbarch = get_regcache_arch (regcache);
+
          if (debug_displaced)
            {
+             CORE_ADDR actual_pc = regcache_read_pc (regcache);
              gdb_byte buf[4];
 
-             fprintf_unfiltered (gdb_stdlog, "displaced: run 0x%s: ",
-                                 paddr_nz (actual_pc));
+             fprintf_unfiltered (gdb_stdlog, "displaced: run %s: ",
+                                 paddress (gdbarch, actual_pc));
              read_memory (actual_pc, buf, sizeof (buf));
              displaced_step_dump_bytes (gdb_stdlog, buf, sizeof (buf));
            }
 
-         target_resume (ptid, 1, TARGET_SIGNAL_0);
+         if (gdbarch_displaced_step_hw_singlestep
+               (gdbarch, displaced_step_closure))
+           target_resume (ptid, 1, TARGET_SIGNAL_0);
+         else
+           target_resume (ptid, 0, TARGET_SIGNAL_0);
 
          /* Done, we're stepping a thread.  */
          break;
@@ -1130,6 +1369,7 @@ resume (int step, enum target_signal sig)
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
   struct thread_info *tp = inferior_thread ();
   CORE_ADDR pc = regcache_read_pc (regcache);
+  struct address_space *aspace = get_regcache_aspace (regcache);
 
   QUIT;
 
@@ -1155,7 +1395,7 @@ resume (int step, enum target_signal sig)
      removed or inserted, as appropriate.  The exception is if we're sitting
      at a permanent breakpoint; we need to step over it, but permanent
      breakpoints can't be removed.  So we have to test for it here.  */
-  if (breakpoint_here_p (pc) == permanent_breakpoint_here)
+  if (breakpoint_here_p (aspace, pc) == permanent_breakpoint_here)
     {
       if (gdbarch_skip_permanent_breakpoint_p (gdbarch))
        gdbarch_skip_permanent_breakpoint (gdbarch, regcache);
@@ -1174,7 +1414,8 @@ a command like `return' or `jump' to continue execution."));
      comments in the handle_inferior event for dealing with 'random
      signals' explain what we do instead.  */
   if (use_displaced_stepping (gdbarch)
-      && tp->trap_expected
+      && (tp->trap_expected
+         || (step && gdbarch_software_single_step_p (gdbarch)))
       && sig == TARGET_SIGNAL_0)
     {
       if (!displaced_step_prepare (inferior_ptid))
@@ -1189,10 +1430,13 @@ a command like `return' or `jump' to continue execution."));
          discard_cleanups (old_cleanups);
          return;
        }
+
+      step = gdbarch_displaced_step_hw_singlestep
+              (gdbarch, displaced_step_closure);
     }
 
   /* Do we need to do it the hard way, w/temp breakpoints?  */
-  if (step)
+  else if (step)
     step = maybe_software_singlestep (gdbarch, pc);
 
   if (should_resume)
@@ -1268,7 +1512,7 @@ a command like `return' or `jump' to continue execution."));
          /* Most targets can step a breakpoint instruction, thus
             executing it normally.  But if this one cannot, just
             continue and we will hit it anyway.  */
-         if (step && breakpoint_inserted_here_p (pc))
+         if (step && breakpoint_inserted_here_p (aspace, pc))
            step = 0;
        }
 
@@ -1277,11 +1521,12 @@ a command like `return' or `jump' to continue execution."));
           && tp->trap_expected)
         {
          struct regcache *resume_regcache = get_thread_regcache (resume_ptid);
+         struct gdbarch *resume_gdbarch = get_regcache_arch (resume_regcache);
           CORE_ADDR actual_pc = regcache_read_pc (resume_regcache);
           gdb_byte buf[4];
 
-          fprintf_unfiltered (gdb_stdlog, "displaced: run 0x%s: ",
-                              paddr_nz (actual_pc));
+          fprintf_unfiltered (gdb_stdlog, "displaced: run %s: ",
+                              paddress (resume_gdbarch, actual_pc));
           read_memory (actual_pc, buf, sizeof (buf));
           displaced_step_dump_bytes (gdb_stdlog, buf, sizeof (buf));
         }
@@ -1316,6 +1561,7 @@ clear_proceed_status_thread (struct thread_info *tp)
   tp->step_range_start = 0;
   tp->step_range_end = 0;
   tp->step_frame_id = null_frame_id;
+  tp->step_stack_frame_id = null_frame_id;
   tp->step_over_calls = STEP_OVER_UNDEBUGGABLE;
   tp->stop_requested = 0;
 
@@ -1340,23 +1586,26 @@ clear_proceed_status_callback (struct thread_info *tp, void *data)
 void
 clear_proceed_status (void)
 {
+  if (!non_stop)
+    {
+      /* In all-stop mode, delete the per-thread status of all
+        threads, even if inferior_ptid is null_ptid, there may be
+        threads on the list.  E.g., we may be launching a new
+        process, while selecting the executable.  */
+      iterate_over_threads (clear_proceed_status_callback, NULL);
+    }
+
   if (!ptid_equal (inferior_ptid, null_ptid))
     {
       struct inferior *inferior;
 
       if (non_stop)
        {
-         /* If in non-stop mode, only delete the per-thread status
-            of the current thread.  */
+         /* If in non-stop mode, only delete the per-thread status of
+            the current thread.  */
          clear_proceed_status_thread (inferior_thread ());
        }
-      else
-       {
-         /* In all-stop mode, delete the per-thread status of
-            *all* threads.  */
-         iterate_over_threads (clear_proceed_status_callback, NULL);
-       }
-  
+
       inferior = current_inferior ();
       inferior->stop_soon = NO_STOP_QUIETLY;
     }
@@ -1418,7 +1667,8 @@ prepare_to_proceed (int step)
     {
       struct regcache *regcache = get_thread_regcache (wait_ptid);
 
-      if (breakpoint_here_p (regcache_read_pc (regcache)))
+      if (breakpoint_here_p (get_regcache_aspace (regcache),
+                            regcache_read_pc (regcache)))
        {
          /* If stepping, remember current thread to switch back to.  */
          if (step)
@@ -1456,6 +1706,7 @@ proceed (CORE_ADDR addr, enum target_signal siggnal, int step)
   struct gdbarch *gdbarch;
   struct thread_info *tp;
   CORE_ADDR pc;
+  struct address_space *aspace;
   int oneproc = 0;
 
   /* If we're stopped at a fork/vfork, follow the branch set by the
@@ -1470,6 +1721,7 @@ proceed (CORE_ADDR addr, enum target_signal siggnal, int step)
 
   regcache = get_current_regcache ();
   gdbarch = get_regcache_arch (regcache);
+  aspace = get_regcache_aspace (regcache);
   pc = regcache_read_pc (regcache);
 
   if (step > 0)
@@ -1479,7 +1731,7 @@ proceed (CORE_ADDR addr, enum target_signal siggnal, int step)
 
   if (addr == (CORE_ADDR) -1)
     {
-      if (pc == stop_pc && breakpoint_here_p (pc) 
+      if (pc == stop_pc && breakpoint_here_p (aspace, pc)
          && execution_direction != EXEC_REVERSE)
        /* There is a breakpoint at the address we will resume at,
           step one instruction before inserting breakpoints so that
@@ -1505,8 +1757,8 @@ proceed (CORE_ADDR addr, enum target_signal siggnal, int step)
 
   if (debug_infrun)
     fprintf_unfiltered (gdb_stdlog,
-                       "infrun: proceed (addr=0x%s, signal=%d, step=%d)\n",
-                       paddr_nz (addr), siggnal, step);
+                       "infrun: proceed (addr=%s, signal=%d, step=%d)\n",
+                       paddress (gdbarch, addr), siggnal, step);
 
   if (non_stop)
     /* In non-stop, each thread is handled individually.  The context
@@ -1689,6 +1941,9 @@ init_wait_for_inferior (void)
   init_infwait_state ();
 
   displaced_step_clear ();
+
+  /* Discard any skipped inlined frames.  */
+  clear_inline_frame_state (minus_one_ptid);
 }
 
 \f
@@ -1744,9 +1999,9 @@ struct execution_control_state
   int wait_some_more;
 };
 
-void init_execution_control_state (struct execution_control_state *ecs);
+static void init_execution_control_state (struct execution_control_state *ecs);
 
-void handle_inferior_event (struct execution_control_state *ecs);
+static void handle_inferior_event (struct execution_control_state *ecs);
 
 static void handle_step_into_function (struct gdbarch *gdbarch,
                                       struct execution_control_state *ecs);
@@ -1754,9 +2009,10 @@ static void handle_step_into_function_backward (struct gdbarch *gdbarch,
                                                struct execution_control_state *ecs);
 static void insert_step_resume_breakpoint_at_frame (struct frame_info *step_frame);
 static void insert_step_resume_breakpoint_at_caller (struct frame_info *);
-static void insert_step_resume_breakpoint_at_sal (struct symtab_and_line sr_sal,
+static void insert_step_resume_breakpoint_at_sal (struct gdbarch *gdbarch,
+                                                 struct symtab_and_line sr_sal,
                                                  struct frame_id sr_id);
-static void insert_longjmp_resume_breakpoint (CORE_ADDR);
+static void insert_longjmp_resume_breakpoint (struct gdbarch *, CORE_ADDR);
 
 static void stop_stepping (struct execution_control_state *ecs);
 static void prepare_to_wait (struct execution_control_state *ecs);
@@ -1921,7 +2177,6 @@ print_target_wait_results (ptid_t waiton_ptid, ptid_t result_ptid,
   char *status_string = target_waitstatus_to_string (ws);
   struct ui_file *tmp_stream = mem_fileopen ();
   char *text;
-  long len;
 
   /* The text is split over several lines because it was getting too long.
      Call fprintf_unfiltered (gdb_stdlog) once so that the text is still
@@ -1941,7 +2196,7 @@ print_target_wait_results (ptid_t waiton_ptid, ptid_t result_ptid,
                      "infrun:   %s\n",
                      status_string);
 
-  text = ui_file_xstrdup (tmp_stream, &len);
+  text = ui_file_xstrdup (tmp_stream, NULL);
 
   /* 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.  */
@@ -1982,23 +2237,22 @@ wait_for_inferior (int treat_exec_as_sigtrap)
   ecs = &ecss;
   memset (ecs, 0, sizeof (*ecs));
 
-  overlay_cache_invalid = 1;
-
   /* We'll update this if & when we switch to a new thread.  */
   previous_inferior_ptid = inferior_ptid;
 
-  /* We have to invalidate the registers BEFORE calling target_wait
-     because they can be loaded from the target while in target_wait.
-     This makes remote debugging a bit more efficient for those
-     targets that provide critical registers as part of their normal
-     status mechanism. */
-
-  registers_changed ();
-
   while (1)
     {
       struct cleanup *old_chain;
 
+      /* We have to invalidate the registers BEFORE calling target_wait
+        because they can be loaded from the target while in target_wait.
+        This makes remote debugging a bit more efficient for those
+        targets that provide critical registers as part of their normal
+        status mechanism. */
+
+      overlay_cache_invalid = 1;
+      registers_changed ();
+
       if (deprecated_target_wait_hook)
        ecs->ptid = deprecated_target_wait_hook (waiton_ptid, &ecs->ws, 0);
       else
@@ -2019,6 +2273,10 @@ wait_for_inferior (int treat_exec_as_sigtrap)
         state.  */
       old_chain = make_cleanup (finish_thread_state_cleanup, &minus_one_ptid);
 
+      if (ecs->ws.kind == TARGET_WAITKIND_SYSCALL_ENTRY
+          || ecs->ws.kind == TARGET_WAITKIND_SYSCALL_RETURN)
+        ecs->ws.value.syscall_number = UNKNOWN_SYSCALL;
+
       /* Now figure out what to do with the result of the result.  */
       handle_inferior_event (ecs);
 
@@ -2052,14 +2310,8 @@ fetch_inferior_event (void *client_data)
 
   memset (ecs, 0, sizeof (*ecs));
 
-  overlay_cache_invalid = 1;
-
-  /* We can only rely on wait_for_more being correct before handling
-     the event in all-stop, but previous_inferior_ptid isn't used in
-     non-stop.  */
-  if (!ecs->wait_some_more)
-    /* We'll update this if & when we switch to a new thread.  */
-    previous_inferior_ptid = inferior_ptid;
+  /* We'll update this if & when we switch to a new thread.  */
+  previous_inferior_ptid = inferior_ptid;
 
   if (non_stop)
     /* In non-stop mode, the user/frontend should not notice a thread
@@ -2074,6 +2326,7 @@ fetch_inferior_event (void *client_data)
      targets that provide critical registers as part of their normal
      status mechanism. */
 
+  overlay_cache_invalid = 1;
   registers_changed ();
 
   if (deprecated_target_wait_hook)
@@ -2137,10 +2390,23 @@ fetch_inferior_event (void *client_data)
     display_gdb_prompt (0);
 }
 
+/* Record the frame and location we're currently stepping through.  */
+void
+set_step_info (struct frame_info *frame, struct symtab_and_line sal)
+{
+  struct thread_info *tp = inferior_thread ();
+
+  tp->step_frame_id = get_frame_id (frame);
+  tp->step_stack_frame_id = get_stack_frame_id (frame);
+
+  tp->current_symtab = sal.symtab;
+  tp->current_line = sal.line;
+}
+
 /* Prepare an execution control state for looping through a
    wait_for_inferior-type loop.  */
 
-void
+static void
 init_execution_control_state (struct execution_control_state *ecs)
 {
   ecs->random_signal = 0;
@@ -2151,16 +2417,10 @@ init_execution_control_state (struct execution_control_state *ecs)
 void
 init_thread_stepping_state (struct thread_info *tss)
 {
-  struct symtab_and_line sal;
-
   tss->stepping_over_breakpoint = 0;
   tss->step_after_step_resume_breakpoint = 0;
   tss->stepping_through_solib_after_catch = 0;
   tss->stepping_through_solib_catchpoints = NULL;
-
-  sal = find_pc_line (tss->prev_pc, 0);
-  tss->current_line = sal.line;
-  tss->current_symtab = sal.symtab;
 }
 
 /* Return the cached copy of the last pid/waitstatus returned by
@@ -2202,6 +2462,7 @@ adjust_pc_after_break (struct execution_control_state *ecs)
 {
   struct regcache *regcache;
   struct gdbarch *gdbarch;
+  struct address_space *aspace;
   CORE_ADDR breakpoint_pc;
 
   /* If we've hit a breakpoint, we'll normally be stopped with SIGTRAP.  If
@@ -2267,6 +2528,8 @@ adjust_pc_after_break (struct execution_control_state *ecs)
   if (gdbarch_decr_pc_after_break (gdbarch) == 0)
     return;
 
+  aspace = get_regcache_aspace (regcache);
+
   /* Find the location where (if we've hit a breakpoint) the
      breakpoint would be.  */
   breakpoint_pc = regcache_read_pc (regcache)
@@ -2280,8 +2543,8 @@ adjust_pc_after_break (struct execution_control_state *ecs)
      already queued and arrive later.  To suppress those spurious
      SIGTRAPs, we keep a list of such breakpoint locations for a bit,
      and retire them after a number of stop events are reported.  */
-  if (software_breakpoint_inserted_here_p (breakpoint_pc)
-      || (non_stop && moribund_breakpoint_here_p (breakpoint_pc)))
+  if (software_breakpoint_inserted_here_p (aspace, breakpoint_pc)
+      || (non_stop && moribund_breakpoint_here_p (aspace, breakpoint_pc)))
     {
       struct cleanup *old_cleanups = NULL;
       if (RECORD_IS_USED)
@@ -2337,11 +2600,75 @@ ensure_not_running (void)
     error_is_running ();
 }
 
+static int
+stepped_in_from (struct frame_info *frame, struct frame_id step_frame_id)
+{
+  for (frame = get_prev_frame (frame);
+       frame != NULL;
+       frame = get_prev_frame (frame))
+    {
+      if (frame_id_eq (get_frame_id (frame), step_frame_id))
+       return 1;
+      if (get_frame_type (frame) != INLINE_FRAME)
+       break;
+    }
+
+  return 0;
+}
+
+/* Auxiliary function that handles syscall entry/return events.
+   It returns 1 if the inferior should keep going (and GDB
+   should ignore the event), or 0 if the event deserves to be
+   processed.  */
+
+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 = gdbarch_get_syscall_number (gdbarch, ecs->ptid);
+  stop_pc = regcache_read_pc (regcache);
+
+  target_last_waitstatus.value.syscall_number = syscall_number;
+
+  if (catch_syscall_enabled () > 0
+      && catching_syscall_number (syscall_number) > 0)
+    {
+      if (debug_infrun)
+        fprintf_unfiltered (gdb_stdlog, "infrun: syscall number = '%d'\n",
+                            syscall_number);
+
+      ecs->event_thread->stop_bpstat
+       = bpstat_stop_status (get_regcache_aspace (regcache),
+                             stop_pc, ecs->ptid);
+      ecs->random_signal = !bpstat_explains_signal (ecs->event_thread->stop_bpstat);
+
+      if (!ecs->random_signal)
+       {
+         /* Catchpoint hit.  */
+         ecs->event_thread->stop_signal = TARGET_SIGNAL_TRAP;
+         return 0;
+       }
+    }
+
+  /* If no catchpoint triggered for this, then keep going.  */
+  ecs->event_thread->stop_signal = TARGET_SIGNAL_0;
+  keep_going (ecs);
+  return 1;
+}
+
 /* Given an execution control state that has been freshly filled in
    by an event from the inferior, figure out what it means and take
    appropriate action.  */
 
-void
+static void
 handle_inferior_event (struct execution_control_state *ecs)
 {
   struct frame_info *frame;
@@ -2352,9 +2679,25 @@ handle_inferior_event (struct execution_control_state *ecs)
   struct symtab_and_line stop_pc_sal;
   enum stop_kind stop_soon;
 
+  if (ecs->ws.kind == TARGET_WAITKIND_IGNORE)
+    {
+      /* We had an event in the inferior, but we are not interested in
+        handling it at this level.  The lower layers have already
+        done what needs to be done, if anything.
+
+        One of the possible circumstances for this is when the
+        inferior produces output for the console.  The inferior has
+        not stopped, and we are ignoring the event.  Another possible
+        circumstance is any event which the lower level knows will be
+        reported multiple times without an intervening resume.  */
+      if (debug_infrun)
+       fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_IGNORE\n");
+      prepare_to_wait (ecs);
+      return;
+    }
+
   if (ecs->ws.kind != TARGET_WAITKIND_EXITED
-      && ecs->ws.kind != TARGET_WAITKIND_SIGNALLED
-      && ecs->ws.kind != TARGET_WAITKIND_IGNORE)
+      && ecs->ws.kind != TARGET_WAITKIND_SIGNALLED)
     {
       struct inferior *inf = find_inferior_pid (ptid_get_pid (ecs->ptid));
       gdb_assert (inf);
@@ -2388,30 +2731,25 @@ handle_inferior_event (struct execution_control_state *ecs)
   /* Dependent on the current PC value modified by adjust_pc_after_break.  */
   reinit_frame_cache ();
 
-  if (ecs->ws.kind != TARGET_WAITKIND_IGNORE)
-    {
-      breakpoint_retire_moribund ();
-
-      /* Mark the non-executing threads accordingly.  In all-stop, all
-        threads of all processes are stopped when we get any event
-        reported.  In non-stop mode, only the event thread stops.  If
-        we're handling a process exit in non-stop mode, there's
-        nothing to do, as threads of the dead process are gone, and
-        threads of any other process were left running.  */
-      if (!non_stop)
-       set_executing (minus_one_ptid, 0);
-      else if (ecs->ws.kind != TARGET_WAITKIND_SIGNALLED
-              && ecs->ws.kind != TARGET_WAITKIND_EXITED)
-       set_executing (inferior_ptid, 0);
-    }
+  breakpoint_retire_moribund ();
+
+  /* Mark the non-executing threads accordingly.  In all-stop, all
+     threads of all processes are stopped when we get any event
+     reported.  In non-stop mode, only the event thread stops.  If
+     we're handling a process exit in non-stop mode, there's nothing
+     to do, as threads of the dead process are gone, and threads of
+     any other process were left running.  */
+  if (!non_stop)
+    set_executing (minus_one_ptid, 0);
+  else if (ecs->ws.kind != TARGET_WAITKIND_SIGNALLED
+          && ecs->ws.kind != TARGET_WAITKIND_EXITED)
+    set_executing (inferior_ptid, 0);
 
   switch (infwait_state)
     {
     case infwait_thread_hop_state:
       if (debug_infrun)
         fprintf_unfiltered (gdb_stdlog, "infrun: infwait_thread_hop_state\n");
-      /* Cancel the waiton_ptid. */
-      waiton_ptid = pid_to_ptid (-1);
       break;
 
     case infwait_normal_state:
@@ -2442,7 +2780,9 @@ handle_inferior_event (struct execution_control_state *ecs)
     default:
       internal_error (__FILE__, __LINE__, _("bad switch"));
     }
+
   infwait_state = infwait_normal_state;
+  waiton_ptid = pid_to_ptid (-1);
 
   switch (ecs->ws.kind)
     {
@@ -2518,6 +2858,9 @@ handle_inferior_event (struct execution_control_state *ecs)
       if (debug_infrun)
         fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_EXITED\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_stop_reason (EXITED, ecs->ws.value.integer);
 
@@ -2536,6 +2879,9 @@ handle_inferior_event (struct execution_control_state *ecs)
       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 */
 
@@ -2592,19 +2938,45 @@ handle_inferior_event (struct execution_control_state *ecs)
 
       stop_pc = regcache_read_pc (get_thread_regcache (ecs->ptid));
 
-      ecs->event_thread->stop_bpstat = bpstat_stop_status (stop_pc, ecs->ptid);
+      ecs->event_thread->stop_bpstat
+       = bpstat_stop_status (get_regcache_aspace (get_current_regcache ()),
+                             stop_pc, ecs->ptid);
 
       ecs->random_signal = !bpstat_explains_signal (ecs->event_thread->stop_bpstat);
 
       /* If no catchpoint triggered for this, then keep going.  */
       if (ecs->random_signal)
        {
+         ptid_t parent;
+         ptid_t child;
          int should_resume;
+         int follow_child = (follow_fork_mode_string == follow_fork_mode_child);
 
          ecs->event_thread->stop_signal = TARGET_SIGNAL_0;
 
          should_resume = follow_fork ();
 
+         parent = ecs->ptid;
+         child = ecs->ws.value.related_pid;
+
+         /* In non-stop mode, also resume the other branch.  */
+         if (non_stop && !detach_fork)
+           {
+             if (follow_child)
+               switch_to_thread (parent);
+             else
+               switch_to_thread (child);
+
+             ecs->event_thread = inferior_thread ();
+             ecs->ptid = inferior_ptid;
+             keep_going (ecs);
+           }
+
+         if (follow_child)
+           switch_to_thread (child);
+         else
+           switch_to_thread (parent);
+
          ecs->event_thread = inferior_thread ();
          ecs->ptid = inferior_ptid;
 
@@ -2617,6 +2989,22 @@ handle_inferior_event (struct execution_control_state *ecs)
       ecs->event_thread->stop_signal = TARGET_SIGNAL_TRAP;
       goto process_event_stop_test;
 
+    case TARGET_WAITKIND_VFORK_DONE:
+      /* Done with the shared memory region.  Re-insert breakpoints in
+        the parent, and keep going.  */
+
+      if (debug_infrun)
+       fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_VFORK_DONE\n");
+
+      if (!ptid_equal (ecs->ptid, inferior_ptid))
+       context_switch (ecs->ptid);
+
+      current_inferior ()->waiting_for_vfork_done = 0;
+      /* This also takes care of reinserting breakpoints in the
+        previously locked inferior.  */
+      keep_going (ecs);
+      return;
+
     case TARGET_WAITKIND_EXECD:
       if (debug_infrun)
         fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_EXECD\n");
@@ -2629,12 +3017,17 @@ handle_inferior_event (struct execution_control_state *ecs)
 
       stop_pc = regcache_read_pc (get_thread_regcache (ecs->ptid));
 
+      /* Do whatever is necessary to the parent branch of the vfork.  */
+      handle_vfork_child_exec_or_exit (1);
+
       /* This causes the eventpoints and symbol table to be reset.
          Must do this now, before trying to determine whether to
          stop.  */
       follow_exec (inferior_ptid, ecs->ws.value.execd_pathname);
 
-      ecs->event_thread->stop_bpstat = bpstat_stop_status (stop_pc, ecs->ptid);
+      ecs->event_thread->stop_bpstat
+       = bpstat_stop_status (get_regcache_aspace (get_current_regcache ()),
+                             stop_pc, ecs->ptid);
       ecs->random_signal = !bpstat_explains_signal (ecs->event_thread->stop_bpstat);
 
       /* Note that this may be referenced from inside
@@ -2657,9 +3050,10 @@ handle_inferior_event (struct execution_control_state *ecs)
     case TARGET_WAITKIND_SYSCALL_ENTRY:
       if (debug_infrun)
         fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_SYSCALL_ENTRY\n");
-      resume (0, TARGET_SIGNAL_0);
-      prepare_to_wait (ecs);
-      return;
+      /* Getting the current syscall number */
+      if (handle_syscall_event (ecs) != 0)
+        return;
+      goto process_event_stop_test;
 
       /* Before examining the threads further, step this thread to
          get it entirely out of the syscall.  (We get notice of the
@@ -2669,9 +3063,9 @@ handle_inferior_event (struct execution_control_state *ecs)
     case TARGET_WAITKIND_SYSCALL_RETURN:
       if (debug_infrun)
         fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_SYSCALL_RETURN\n");
-      target_resume (ecs->ptid, 1, TARGET_SIGNAL_0);
-      prepare_to_wait (ecs);
-      return;
+      if (handle_syscall_event (ecs) != 0)
+        return;
+      goto process_event_stop_test;
 
     case TARGET_WAITKIND_STOPPED:
       if (debug_infrun)
@@ -2685,21 +3079,6 @@ handle_inferior_event (struct execution_control_state *ecs)
       print_stop_reason (NO_HISTORY, 0);
       stop_stepping (ecs);
       return;
-
-      /* We had an event in the inferior, but we are not interested
-         in handling it at this level. The lower layers have already
-         done what needs to be done, if anything.
-
-         One of the possible circumstances for this is when the
-         inferior produces output for the console. The inferior has
-         not stopped, and we are ignoring the event.  Another possible
-         circumstance is any event which the lower level knows will be
-         reported multiple times without an intervening resume.  */
-    case TARGET_WAITKIND_IGNORE:
-      if (debug_infrun)
-        fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_IGNORE\n");
-      prepare_to_wait (ecs);
-      return;
     }
 
   if (ecs->new_thread_event)
@@ -2718,6 +3097,8 @@ targets should add new threads to the thread list themselves in non-stop mode.")
         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, TARGET_SIGNAL_0);
       prepare_to_wait (ecs);
       return;
@@ -2743,8 +3124,11 @@ targets should add new threads to the thread list themselves in non-stop mode.")
 
   if (debug_infrun)
     {
-      fprintf_unfiltered (gdb_stdlog, "infrun: stop_pc = 0x%s\n",
-                          paddr_nz (stop_pc));
+      struct regcache *regcache = get_thread_regcache (ecs->ptid);
+      struct gdbarch *gdbarch = get_regcache_arch (regcache);
+
+      fprintf_unfiltered (gdb_stdlog, "infrun: stop_pc = %s\n",
+                          paddress (gdbarch, stop_pc));
       if (target_stopped_by_watchpoint ())
        {
           CORE_ADDR addr;
@@ -2752,8 +3136,8 @@ targets should add new threads to the thread list themselves in non-stop mode.")
 
           if (target_stopped_data_address (&current_target, &addr))
             fprintf_unfiltered (gdb_stdlog,
-                                "infrun: stopped data address = 0x%s\n",
-                                paddr_nz (addr));
+                                "infrun: stopped data address = %s\n",
+                                paddress (gdbarch, addr));
           else
             fprintf_unfiltered (gdb_stdlog,
                                 "infrun: (no data address available)\n");
@@ -2780,6 +3164,7 @@ targets should add new threads to the thread list themselves in non-stop mode.")
          singlestep_breakpoints_inserted_p = 0;
 
          ecs->random_signal = 0;
+         ecs->event_thread->trap_expected = 0;
 
          context_switch (saved_singlestep_ptid);
          if (deprecated_context_hook)
@@ -2833,14 +3218,15 @@ targets should add new threads to the thread list themselves in non-stop mode.")
   if (ecs->event_thread->stop_signal == TARGET_SIGNAL_TRAP)
     {
       int thread_hop_needed = 0;
+      struct address_space *aspace = get_regcache_aspace (get_current_regcache ());
 
       /* Check if a regular breakpoint has been hit before checking
          for a potential single step breakpoint. Otherwise, GDB will
          not see this breakpoint hit when stepping onto breakpoints.  */
-      if (regular_breakpoint_inserted_here_p (stop_pc))
+      if (regular_breakpoint_inserted_here_p (aspace, stop_pc))
        {
          ecs->random_signal = 0;
-         if (!breakpoint_thread_match (stop_pc, ecs->ptid))
+         if (!breakpoint_thread_match (aspace, stop_pc, ecs->ptid))
            thread_hop_needed = 1;
        }
       else if (singlestep_breakpoints_inserted_p)
@@ -2964,7 +3350,6 @@ targets should add new threads to the thread list themselves in non-stop mode.")
 
              ecs->event_thread->stepping_over_breakpoint = 1;
              keep_going (ecs);
-             registers_changed ();
              return;
            }
        }
@@ -3039,7 +3424,6 @@ targets should add new threads to the thread list themselves in non-stop mode.")
        /* Single step */
       hw_step = maybe_software_singlestep (gdbarch, stop_pc);
       target_resume (ecs->ptid, hw_step, TARGET_SIGNAL_0);
-      registers_changed ();
       waiton_ptid = ecs->ptid;
       if (target_have_steppable_watchpoint)
        infwait_state = infwait_step_watch_state;
@@ -3065,6 +3449,12 @@ targets should add new threads to the thread list themselves in non-stop mode.")
   ecs->random_signal = 0;
   stopped_by_random_signal = 0;
 
+  /* Hide inlined functions starting here, unless we just performed stepi or
+     nexti.  After stepi and nexti, always show the innermost frame (not any
+     inline function call sites).  */
+  if (ecs->event_thread->step_range_end != 1)
+    skip_inline_frames (ecs->ptid);
+
   if (ecs->event_thread->stop_signal == TARGET_SIGNAL_TRAP
       && ecs->event_thread->trap_expected
       && gdbarch_single_step_through_delay_p (gdbarch)
@@ -3123,7 +3513,8 @@ targets should add new threads to the thread list themselves in non-stop mode.")
      non-standard signals can't be explained by the breakpoint.  */
   if (ecs->event_thread->stop_signal == TARGET_SIGNAL_TRAP
       || (! ecs->event_thread->trap_expected
-          && breakpoint_inserted_here_p (stop_pc)
+          && breakpoint_inserted_here_p (get_regcache_aspace (get_current_regcache ()),
+                                        stop_pc)
          && (ecs->event_thread->stop_signal == TARGET_SIGNAL_ILL
              || ecs->event_thread->stop_signal == TARGET_SIGNAL_SEGV
              || ecs->event_thread->stop_signal == TARGET_SIGNAL_EMT))
@@ -3180,8 +3571,10 @@ targets should add new threads to the thread list themselves in non-stop mode.")
        }
 
       /* See if there is a breakpoint at the current PC.  */
-      ecs->event_thread->stop_bpstat = bpstat_stop_status (stop_pc, ecs->ptid);
-      
+      ecs->event_thread->stop_bpstat
+       = bpstat_stop_status (get_regcache_aspace (get_current_regcache ()),
+                             stop_pc, ecs->ptid);
+
       /* Following in case break condition called a
         function.  */
       stop_print_frame = 1;
@@ -3302,8 +3695,8 @@ process_event_stop_test:
          && ecs->event_thread->stop_signal != TARGET_SIGNAL_0
          && (ecs->event_thread->step_range_start <= stop_pc
              && stop_pc < ecs->event_thread->step_range_end)
-         && frame_id_eq (get_frame_id (frame),
-                         ecs->event_thread->step_frame_id)
+         && frame_id_eq (get_stack_frame_id (frame),
+                         ecs->event_thread->step_stack_frame_id)
          && ecs->event_thread->step_resume_breakpoint == NULL)
        {
          /* The inferior is about to take a signal that will take it
@@ -3375,7 +3768,7 @@ infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME (!gdbarch_get_longjmp_target)\n");
        delete_step_resume_breakpoint (ecs->event_thread);
 
        /* Insert a breakpoint at resume address.  */
-       insert_longjmp_resume_breakpoint (jmp_buf_pc);
+       insert_longjmp_resume_breakpoint (gdbarch, jmp_buf_pc);
 
        keep_going (ecs);
        return;
@@ -3492,6 +3885,22 @@ infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME (!gdbarch_get_longjmp_target)\n");
        }
        break;
 
+      case BPSTAT_WHAT_CHECK_JIT:
+        if (debug_infrun)
+          fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_CHECK_JIT\n");
+
+        /* Switch terminal for any messages produced by breakpoint_re_set.  */
+        target_terminal_ours_for_output ();
+
+        jit_event_handler (gdbarch);
+
+        target_terminal_inferior ();
+
+        /* We want to step over this breakpoint, then keep going.  */
+        ecs->event_thread->stepping_over_breakpoint = 1;
+
+        break;
+
       case BPSTAT_WHAT_LAST:
        /* Not a real code, but listed here to shut up gcc -Wall.  */
 
@@ -3643,9 +4052,10 @@ infrun: not switching back to stepped thread, it has vanished\n");
                          ecs->event_thread->step_frame_id)))
     {
       if (debug_infrun)
-       fprintf_unfiltered (gdb_stdlog, "infrun: stepping inside range [0x%s-0x%s]\n",
-                           paddr_nz (ecs->event_thread->step_range_start),
-                           paddr_nz (ecs->event_thread->step_range_end));
+       fprintf_unfiltered
+         (gdb_stdlog, "infrun: stepping inside range [%s-%s]\n",
+          paddress (gdbarch, ecs->event_thread->step_range_start),
+          paddress (gdbarch, ecs->event_thread->step_range_end));
 
       /* When stepping backward, stop at beginning of line range
         (unless it's the function entry point, in which case
@@ -3695,8 +4105,10 @@ infrun: not switching back to stepped thread, it has vanished\n");
          struct symtab_and_line sr_sal;
          init_sal (&sr_sal);
          sr_sal.pc = pc_after_resolver;
+         sr_sal.pspace = get_frame_program_space (frame);
 
-         insert_step_resume_breakpoint_at_sal (sr_sal, null_frame_id);
+         insert_step_resume_breakpoint_at_sal (gdbarch,
+                                               sr_sal, null_frame_id);
        }
 
       keep_going (ecs);
@@ -3727,11 +4139,22 @@ infrun: not switching back to stepped thread, it has vanished\n");
      NOTE: frame_id_eq will never report two invalid frame IDs as
      being equal, so to get into this block, both the current and
      previous frame must have valid frame IDs.  */
-  if (!frame_id_eq (get_frame_id (frame),
-                   ecs->event_thread->step_frame_id)
-      && (frame_id_eq (frame_unwind_id (frame),
-                      ecs->event_thread->step_frame_id)
-         || execution_direction == EXEC_REVERSE))
+  /* The outer_frame_id check is a heuristic to detect stepping
+     through startup code.  If we step over an instruction which
+     sets the stack pointer from an invalid value to a valid value,
+     we may detect that as a subroutine call from the mythical
+     "outermost" function.  This could be fixed by marking
+     outermost frames as !stack_p,code_p,special_p.  Then the
+     initial outermost frame, before sp was valid, would
+     have code_addr == &_start.  See the commend in frame_id_eq
+     for more.  */
+  if (!frame_id_eq (get_stack_frame_id (frame),
+                   ecs->event_thread->step_stack_frame_id)
+      && (frame_id_eq (frame_unwind_caller_id (get_current_frame ()),
+                      ecs->event_thread->step_stack_frame_id)
+         && (!frame_id_eq (ecs->event_thread->step_stack_frame_id,
+                           outer_frame_id)
+             || step_start_function != find_pc_function (stop_pc))))
     {
       CORE_ADDR real_stop_pc;
 
@@ -3759,6 +4182,7 @@ infrun: not switching back to stepped thread, it has vanished\n");
       /* Reverse stepping through solib trampolines.  */
 
       if (execution_direction == EXEC_REVERSE
+         && ecs->event_thread->step_over_calls != STEP_OVER_NONE
          && (gdbarch_skip_trampoline_code (gdbarch, frame, stop_pc)
              || (ecs->stop_func_start == 0
                  && in_solib_dynsym_resolve_code (stop_pc))))
@@ -3792,7 +4216,9 @@ infrun: not switching back to stepped thread, it has vanished\n");
              /* Normal function call return (static or dynamic).  */
              init_sal (&sr_sal);
              sr_sal.pc = ecs->stop_func_start;
-             insert_step_resume_breakpoint_at_sal (sr_sal, null_frame_id);
+             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);
@@ -3817,8 +4243,10 @@ infrun: not switching back to stepped thread, it has vanished\n");
          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 (sr_sal, null_frame_id);
+         insert_step_resume_breakpoint_at_sal (gdbarch,
+                                               sr_sal, null_frame_id);
          keep_going (ecs);
          return;
        }
@@ -3833,6 +4261,7 @@ infrun: not switching back to stepped thread, it has vanished\n");
        struct symtab_and_line tmp_sal;
 
        tmp_sal = find_pc_line (ecs->stop_func_start, 0);
+       tmp_sal.pspace = get_frame_program_space (frame);
        if (tmp_sal.line != 0)
          {
            if (execution_direction == EXEC_REVERSE)
@@ -3862,7 +4291,9 @@ infrun: not switching back to stepped thread, it has vanished\n");
          struct symtab_and_line sr_sal;
          init_sal (&sr_sal);
          sr_sal.pc = ecs->stop_func_start;
-         insert_step_resume_breakpoint_at_sal (sr_sal, null_frame_id);
+         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
@@ -3873,6 +4304,39 @@ infrun: not switching back to stepped thread, it has vanished\n");
       return;
     }
 
+  /* Reverse stepping through solib trampolines.  */
+
+  if (execution_direction == EXEC_REVERSE
+      && ecs->event_thread->step_over_calls != STEP_OVER_NONE)
+    {
+      if (gdbarch_skip_trampoline_code (gdbarch, frame, stop_pc)
+         || (ecs->stop_func_start == 0
+             && in_solib_dynsym_resolve_code (stop_pc)))
+       {
+         /* Any solib trampoline code can be handled in reverse
+            by simply continuing to single-step.  We have already
+            executed the solib function (backwards), and a few 
+            steps will take us back through the trampoline to the
+            caller.  */
+         keep_going (ecs);
+         return;
+       }
+      else if (in_solib_dynsym_resolve_code (stop_pc))
+       {
+         /* 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);
+         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);
+         keep_going (ecs);
+         return;
+       }
+    }
+
   /* If we're in the return path from a shared library trampoline,
      we want to proceed through the trampoline when stepping.  */
   if (gdbarch_in_solib_return_trampoline (gdbarch,
@@ -3894,11 +4358,13 @@ infrun: not switching back to stepped thread, it has vanished\n");
          init_sal (&sr_sal);   /* initialize to zeroes */
          sr_sal.pc = real_stop_pc;
          sr_sal.section = find_pc_overlay (sr_sal.pc);
+         sr_sal.pspace = get_frame_program_space (frame);
 
          /* Do not specify what the fp should be when we stop since
             on some machines the prologue is where the new fp value
             is established.  */
-         insert_step_resume_breakpoint_at_sal (sr_sal, null_frame_id);
+         insert_step_resume_breakpoint_at_sal (gdbarch,
+                                               sr_sal, null_frame_id);
 
          /* Restart without fiddling with the step ranges or
             other state.  */
@@ -3928,7 +4394,7 @@ infrun: not switching back to stepped thread, it has vanished\n");
          set step-mode) or we no longer know how to get back
          to the call site.  */
       if (step_stop_if_no_debug
-         || !frame_id_p (frame_unwind_id (frame)))
+         || !frame_id_p (frame_unwind_caller_id (frame)))
        {
          /* If we have no line number and the step-stop-if-no-debug
             is set, we stop the step so that the user has a chance to
@@ -3974,6 +4440,82 @@ infrun: not switching back to stepped thread, it has vanished\n");
       return;
     }
 
+  /* Look for "calls" to inlined functions, part one.  If the inline
+     frame machinery detected some skipped call sites, we have entered
+     a new inline function.  */
+
+  if (frame_id_eq (get_frame_id (get_current_frame ()),
+                  ecs->event_thread->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);
+
+      if (ecs->event_thread->step_over_calls != STEP_OVER_ALL)
+       {
+         /* For "step", we're going to stop.  But if the call site
+            for this inlined function is on the same source line as
+            we were previously stepping, go down into the function
+            first.  Otherwise stop at the call site.  */
+
+         if (call_sal.line == ecs->event_thread->current_line
+             && call_sal.symtab == ecs->event_thread->current_symtab)
+           step_into_inline_frame (ecs->ptid);
+
+         ecs->event_thread->stop_step = 1;
+         print_stop_reason (END_STEPPING_RANGE, 0);
+         stop_stepping (ecs);
+         return;
+       }
+      else
+       {
+         /* For "next", we should stop at the call site if it is on a
+            different source line.  Otherwise continue through the
+            inlined function.  */
+         if (call_sal.line == ecs->event_thread->current_line
+             && call_sal.symtab == ecs->event_thread->current_symtab)
+           keep_going (ecs);
+         else
+           {
+             ecs->event_thread->stop_step = 1;
+             print_stop_reason (END_STEPPING_RANGE, 0);
+             stop_stepping (ecs);
+           }
+         return;
+       }
+    }
+
+  /* Look for "calls" to inlined functions, part two.  If we are still
+     in the same real function we were stepping through, but we have
+     to go further up to find the exact frame ID, we are stepping
+     through a more inlined call beyond its call site.  */
+
+  if (get_frame_type (get_current_frame ()) == INLINE_FRAME
+      && !frame_id_eq (get_frame_id (get_current_frame ()),
+                      ecs->event_thread->step_frame_id)
+      && stepped_in_from (get_current_frame (),
+                         ecs->event_thread->step_frame_id))
+    {
+      if (debug_infrun)
+       fprintf_unfiltered (gdb_stdlog,
+                           "infrun: stepping through inlined function\n");
+
+      if (ecs->event_thread->step_over_calls == STEP_OVER_ALL)
+       keep_going (ecs);
+      else
+       {
+         ecs->event_thread->stop_step = 1;
+         print_stop_reason (END_STEPPING_RANGE, 0);
+         stop_stepping (ecs);
+       }
+      return;
+    }
+
   if ((stop_pc == stop_pc_sal.pc)
       && (ecs->event_thread->current_line != stop_pc_sal.line
          || ecs->event_thread->current_symtab != stop_pc_sal.symtab))
@@ -3999,9 +4541,7 @@ infrun: not switching back to stepped thread, it has vanished\n");
 
   ecs->event_thread->step_range_start = stop_pc_sal.pc;
   ecs->event_thread->step_range_end = stop_pc_sal.end;
-  ecs->event_thread->step_frame_id = get_frame_id (frame);
-  ecs->event_thread->current_line = stop_pc_sal.line;
-  ecs->event_thread->current_symtab = stop_pc_sal.symtab;
+  set_step_info (frame, stop_pc_sal);
 
   if (debug_infrun)
      fprintf_unfiltered (gdb_stdlog, "infrun: keep going\n");
@@ -4098,11 +4638,12 @@ handle_step_into_function (struct gdbarch *gdbarch,
       init_sal (&sr_sal);      /* initialize to zeroes */
       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 ());
 
       /* Do not specify what the fp should be when we stop since on
          some machines the prologue is where the new fp value is
          established.  */
-      insert_step_resume_breakpoint_at_sal (sr_sal, null_frame_id);
+      insert_step_resume_breakpoint_at_sal (gdbarch, sr_sal, null_frame_id);
 
       /* And make sure stepping stops right away then.  */
       ecs->event_thread->step_range_end = ecs->event_thread->step_range_start;
@@ -4152,7 +4693,8 @@ handle_step_into_function_backward (struct gdbarch *gdbarch,
    This is used to both functions and to skip over code.  */
 
 static void
-insert_step_resume_breakpoint_at_sal (struct symtab_and_line sr_sal,
+insert_step_resume_breakpoint_at_sal (struct gdbarch *gdbarch,
+                                     struct symtab_and_line sr_sal,
                                      struct frame_id sr_id)
 {
   /* There should never be more than one step-resume or longjmp-resume
@@ -4162,11 +4704,11 @@ insert_step_resume_breakpoint_at_sal (struct symtab_and_line sr_sal,
 
   if (debug_infrun)
     fprintf_unfiltered (gdb_stdlog,
-                       "infrun: inserting step-resume breakpoint at 0x%s\n",
-                       paddr_nz (sr_sal.pc));
+                       "infrun: inserting step-resume breakpoint at %s\n",
+                       paddress (gdbarch, sr_sal.pc));
 
   inferior_thread ()->step_resume_breakpoint
-    = set_momentary_breakpoint (sr_sal, sr_id, bp_step_resume);
+    = set_momentary_breakpoint (gdbarch, sr_sal, sr_id, bp_step_resume);
 }
 
 /* Insert a "step-resume breakpoint" at RETURN_FRAME.pc.  This is used
@@ -4179,16 +4721,19 @@ insert_step_resume_breakpoint_at_sal (struct symtab_and_line sr_sal,
 static void
 insert_step_resume_breakpoint_at_frame (struct frame_info *return_frame)
 {
-  struct gdbarch *gdbarch = get_frame_arch (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);
   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);
 
-  insert_step_resume_breakpoint_at_sal (sr_sal, get_frame_id (return_frame));
+  insert_step_resume_breakpoint_at_sal (gdbarch, sr_sal,
+                                       get_stack_frame_id (return_frame));
 }
 
 /* Similar to insert_step_resume_breakpoint_at_frame, except
@@ -4204,24 +4749,28 @@ insert_step_resume_breakpoint_at_frame (struct frame_info *return_frame)
    This is a separate function rather than reusing
    insert_step_resume_breakpoint_at_frame in order to avoid
    get_prev_frame, which may stop prematurely (see the implementation
-   of frame_unwind_id for an example).  */
+   of frame_unwind_caller_id for an example).  */
 
 static void
 insert_step_resume_breakpoint_at_caller (struct frame_info *next_frame)
 {
-  struct gdbarch *gdbarch = get_frame_arch (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_id (next_frame)));
+  gdb_assert (frame_id_p (frame_unwind_caller_id (next_frame)));
 
   init_sal (&sr_sal);          /* initialize to zeros */
 
-  sr_sal.pc = gdbarch_addr_bits_remove (gdbarch, frame_pc_unwind (next_frame));
+  gdbarch = frame_unwind_caller_arch (next_frame);
+  sr_sal.pc = gdbarch_addr_bits_remove (gdbarch,
+                                       frame_unwind_caller_pc (next_frame));
   sr_sal.section = find_pc_overlay (sr_sal.pc);
+  sr_sal.pspace = frame_unwind_program_space (next_frame);
 
-  insert_step_resume_breakpoint_at_sal (sr_sal, frame_unwind_id (next_frame));
+  insert_step_resume_breakpoint_at_sal (gdbarch, sr_sal,
+                                       frame_unwind_caller_id (next_frame));
 }
 
 /* Insert a "longjmp-resume" breakpoint at PC.  This is used to set a
@@ -4230,7 +4779,7 @@ insert_step_resume_breakpoint_at_caller (struct frame_info *next_frame)
    "step-resume" breakpoints.  */
 
 static void
-insert_longjmp_resume_breakpoint (CORE_ADDR pc)
+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
@@ -4239,11 +4788,11 @@ insert_longjmp_resume_breakpoint (CORE_ADDR pc)
 
   if (debug_infrun)
     fprintf_unfiltered (gdb_stdlog,
-                       "infrun: inserting longjmp-resume breakpoint at 0x%s\n",
-                       paddr_nz (pc));
+                       "infrun: inserting longjmp-resume breakpoint at %s\n",
+                       paddress (gdbarch, pc));
 
   inferior_thread ()->step_resume_breakpoint =
-    set_momentary_breakpoint_at_pc (pc, bp_longjmp_resume);
+    set_momentary_breakpoint_at_pc (gdbarch, pc, bp_longjmp_resume);
 }
 
 static void
@@ -4353,19 +4902,7 @@ prepare_to_wait (struct execution_control_state *ecs)
 {
   if (debug_infrun)
     fprintf_unfiltered (gdb_stdlog, "infrun: prepare_to_wait\n");
-  if (infwait_state == infwait_normal_state)
-    {
-      overlay_cache_invalid = 1;
-
-      /* We have to invalidate the registers BEFORE calling
-         target_wait because they can be loaded from the target while
-         in target_wait.  This makes remote debugging a bit more
-         efficient for those targets that provide critical registers
-         as part of their normal status mechanism. */
 
-      registers_changed ();
-      waiton_ptid = pid_to_ptid (-1);
-    }
   /* This is the old end of the while loop.  Let everybody know we
      want to wait for the inferior some more and get called again
      soon.  */
@@ -4734,6 +5271,11 @@ done:
           Delete any breakpoint that is to be deleted at the next stop.  */
        breakpoint_auto_delete (inferior_thread ()->stop_bpstat);
     }
+
+  /* Try to get rid of automatically added inferiors that are no
+     longer needed.  Keeping those around slows down things linearly.
+     Note that this never removes the current inferior.  */
+  prune_inferiors ();
 }
 
 static int
@@ -5151,29 +5693,21 @@ static struct lval_funcs siginfo_value_funcs =
   };
 
 /* Return a new value with the correct type for the siginfo object of
-   the current thread.  Return a void value if there's no object
-   available.  */
+   the current thread using architecture GDBARCH.  Return a void value
+   if there's no object available.  */
 
 static struct value *
-siginfo_make_value (struct internalvar *var)
+siginfo_make_value (struct gdbarch *gdbarch, struct internalvar *var)
 {
-  struct type *type;
-  struct gdbarch *gdbarch;
-
   if (target_has_stack
-      && !ptid_equal (inferior_ptid, null_ptid))
+      && !ptid_equal (inferior_ptid, null_ptid)
+      && gdbarch_get_siginfo_type_p (gdbarch))
     {
-      gdbarch = get_frame_arch (get_current_frame ());
-
-      if (gdbarch_get_siginfo_type_p (gdbarch))
-       {
-         type = gdbarch_get_siginfo_type (gdbarch);
-
-         return allocate_computed_value (type, &siginfo_value_funcs, NULL);
-       }
+      struct type *type = gdbarch_get_siginfo_type (gdbarch);
+      return allocate_computed_value (type, &siginfo_value_funcs, NULL);
     }
 
-  return allocate_value (builtin_type_void);
+  return allocate_value (builtin_type (gdbarch)->builtin_void);
 }
 
 \f
@@ -5264,6 +5798,7 @@ struct inferior_status
   CORE_ADDR step_range_start;
   CORE_ADDR step_range_end;
   struct frame_id step_frame_id;
+  struct frame_id step_stack_frame_id;
   enum step_over_calls_kind step_over_calls;
   CORE_ADDR step_resume_break_address;
   int stop_after_trap;
@@ -5293,6 +5828,7 @@ save_inferior_status (void)
   inf_status->step_range_start = tp->step_range_start;
   inf_status->step_range_end = tp->step_range_end;
   inf_status->step_frame_id = tp->step_frame_id;
+  inf_status->step_stack_frame_id = tp->step_stack_frame_id;
   inf_status->step_over_calls = tp->step_over_calls;
   inf_status->stop_after_trap = stop_after_trap;
   inf_status->stop_soon = inf->stop_soon;
@@ -5346,6 +5882,7 @@ restore_inferior_status (struct inferior_status *inf_status)
   tp->step_range_start = inf_status->step_range_start;
   tp->step_range_end = inf_status->step_range_end;
   tp->step_frame_id = inf_status->step_frame_id;
+  tp->step_stack_frame_id = inf_status->step_stack_frame_id;
   tp->step_over_calls = inf_status->step_over_calls;
   stop_after_trap = inf_status->stop_after_trap;
   inf->stop_soon = inf_status->stop_soon;
@@ -5446,6 +5983,25 @@ inferior_has_execd (ptid_t pid, char **execd_pathname)
   return 1;
 }
 
+int
+inferior_has_called_syscall (ptid_t pid, int *syscall_number)
+{
+  struct target_waitstatus last;
+  ptid_t last_ptid;
+
+  get_last_target_status (&last_ptid, &last);
+
+  if (last.kind != TARGET_WAITKIND_SYSCALL_ENTRY &&
+      last.kind != TARGET_WAITKIND_SYSCALL_RETURN)
+    return 0;
+
+  if (!ptid_equal (last_ptid, pid))
+    return 0;
+
+  *syscall_number = last.value.syscall_number;
+  return 1;
+}
+
 /* Oft used ptids */
 ptid_t null_ptid;
 ptid_t minus_one_ptid;
@@ -5791,6 +6347,30 @@ By default, the debugger will follow the parent process."),
                        show_follow_fork_mode_string,
                        &setlist, &showlist);
 
+  add_setshow_enum_cmd ("follow-exec-mode", class_run,
+                       follow_exec_mode_names,
+                       &follow_exec_mode_string, _("\
+Set debugger response to a program call of exec."), _("\
+Show debugger response to a program call of exec."), _("\
+An exec call replaces the program image of a process.\n\
+\n\
+follow-exec-mode can be:\n\
+\n\
+  new - the debugger creates a new inferior and rebinds the process \n\
+to this new inferior.  The program the process was running before\n\
+the exec call can be restarted afterwards by restarting the original\n\
+inferior.\n\
+\n\
+  same - the debugger keeps the process bound to the same inferior.\n\
+The new executable image replaces the previous executable loaded in\n\
+the inferior.  Restarting the inferior after the exec call restarts\n\
+the executable the process was running after the exec call.\n\
+\n\
+By default, the debugger will use the same inferior."),
+                       NULL,
+                       show_follow_exec_mode_string,
+                       &setlist, &showlist);
+
   add_setshow_enum_cmd ("scheduler-locking", class_run, 
                        scheduler_enums, &scheduler_mode, _("\
 Set mode for locking scheduler during execution."), _("\
@@ -5849,6 +6429,14 @@ Options are 'forward' or 'reverse'."),
                        set_exec_direction_func, show_exec_direction_func,
                        &setlist, &showlist);
 
+  /* Set/show detach-on-fork: user-settable mode.  */
+
+  add_setshow_boolean_cmd ("detach-on-fork", class_run, &detach_fork, _("\
+Set whether gdb will detach the child of a fork."), _("\
+Show whether gdb will detach the child of a fork."), _("\
+Tells gdb whether to detach the child of a fork."),
+                          NULL, NULL, &setlist, &showlist);
+
   /* ptid initializations */
   null_ptid = ptid_build (0, 0, 0);
   minus_one_ptid = ptid_build (-1, 0, 0);
This page took 0.078992 seconds and 4 git commands to generate.