Phase 1 of the ptid_t changes.
[deliverable/binutils-gdb.git] / gdb / infrun.c
index 96a659ebf4a2f5d639c5c8ac909626f18ae6868d..a62a72c069cc673e16f22eee8cfa48808ce0011e 100644 (file)
@@ -1,5 +1,6 @@
 /* Target-struct-independent code to start (run) and stop an inferior process.
 /* Target-struct-independent code to start (run) and stop an inferior process.
-   Copyright 1986-1989, 1991-2000 Free Software Foundation, Inc.
+   Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+   1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 
    This file is part of GDB.
 
 #include "target.h"
 #include "gdbthread.h"
 #include "annotate.h"
 #include "target.h"
 #include "gdbthread.h"
 #include "annotate.h"
-#include "symfile.h"           /* for overlay functions */
+#include "symfile.h"
 #include "top.h"
 #include <signal.h>
 #include "inf-loop.h"
 #include "top.h"
 #include <signal.h>
 #include "inf-loop.h"
+#include "regcache.h"
 
 /* Prototypes for local functions */
 
 
 /* Prototypes for local functions */
 
@@ -46,7 +48,7 @@ static void sig_print_info (enum target_signal);
 
 static void sig_print_header (void);
 
 
 static void sig_print_header (void);
 
-static void resume_cleanups (int);
+static void resume_cleanups (void *);
 
 static int hook_stop_stub (void *);
 
 
 static int hook_stop_stub (void *);
 
@@ -84,6 +86,11 @@ void _initialize_infrun (void);
 int inferior_ignoring_startup_exec_events = 0;
 int inferior_ignoring_leading_exec_events = 0;
 
 int inferior_ignoring_startup_exec_events = 0;
 int inferior_ignoring_leading_exec_events = 0;
 
+/* When set, stop the 'step' command if we enter a function which has
+   no line number information.  The normal behavior is that we step
+   over such function.  */
+int step_stop_if_no_debug = 0;
+
 /* In asynchronous mode, but simulating synchronous execution. */
 
 int sync_execution = 0;
 /* In asynchronous mode, but simulating synchronous execution. */
 
 int sync_execution = 0;
@@ -92,7 +99,7 @@ int sync_execution = 0;
    when the inferior stopped in a different thread than it had been
    running in.  */
 
    when the inferior stopped in a different thread than it had been
    running in.  */
 
-static int previous_inferior_pid;
+static ptid_t previous_inferior_ptid;
 
 /* This is true for configurations that may follow through execl() and
    similar functions.  At present this is only true for HP-UX native.  */
 
 /* This is true for configurations that may follow through execl() and
    similar functions.  At present this is only true for HP-UX native.  */
@@ -296,6 +303,13 @@ a command like `return' or `jump' to continue execution.\n");
 #define HAVE_CONTINUABLE_WATCHPOINT 1
 #endif
 
 #define HAVE_CONTINUABLE_WATCHPOINT 1
 #endif
 
+#ifndef CANNOT_STEP_HW_WATCHPOINTS
+#define CANNOT_STEP_HW_WATCHPOINTS 0
+#else
+#undef  CANNOT_STEP_HW_WATCHPOINTS
+#define CANNOT_STEP_HW_WATCHPOINTS 1
+#endif
+
 /* Tables of how to react to signals; the user sets them.  */
 
 static unsigned char *signal_stop;
 /* Tables of how to react to signals; the user sets them.  */
 
 static unsigned char *signal_stop;
@@ -318,6 +332,9 @@ static unsigned char *signal_program;
        (flags)[signum] = 0; \
   } while (0)
 
        (flags)[signum] = 0; \
   } while (0)
 
+/* Value to pass to target_resume() to cause all threads to resume */
+
+#define RESUME_ALL (pid_to_ptid (-1))
 
 /* Command list pointer for the "stop" placeholder.  */
 
 
 /* Command list pointer for the "stop" placeholder.  */
 
@@ -392,6 +409,12 @@ static struct breakpoint *through_sigtramp_breakpoint = NULL;
    currently be running in a syscall. */
 static int number_of_threads_in_syscalls;
 
    currently be running in a syscall. */
 static int number_of_threads_in_syscalls;
 
+/* This is a cached copy of the pid/waitstatus of the last event
+   returned by target_wait()/target_wait_hook().  This information is
+   returned by get_last_target_status(). */
+static ptid_t target_last_wait_ptid;
+static struct target_waitstatus target_last_waitstatus;
+
 /* This is used to remember when a fork, vfork or exec event
    was caught by a catchpoint, and thus the event is to be
    followed at the next resume of the inferior, and not
 /* This is used to remember when a fork, vfork or exec event
    was caught by a catchpoint, and thus the event is to be
    followed at the next resume of the inferior, and not
@@ -421,23 +444,31 @@ pending_follow;
    set to 1, a vfork event has been seen, but cannot be followed
    until the exec is seen.
 
    set to 1, a vfork event has been seen, but cannot be followed
    until the exec is seen.
 
-   (In the latter case, inferior_pid is still the parent of the
+   (In the latter case, inferior_ptid is still the parent of the
    vfork, and pending_follow.fork_event.child_pid is the child.  The
    appropriate process is followed, according to the setting of
    follow-fork-mode.) */
 static int follow_vfork_when_exec;
 
    vfork, and pending_follow.fork_event.child_pid is the child.  The
    appropriate process is followed, according to the setting of
    follow-fork-mode.) */
 static int follow_vfork_when_exec;
 
-static char *follow_fork_mode_kind_names[] =
+static const char follow_fork_mode_ask[] = "ask";
+static const char follow_fork_mode_both[] = "both";
+static const char follow_fork_mode_child[] = "child";
+static const char follow_fork_mode_parent[] = "parent";
+
+static const char *follow_fork_mode_kind_names[] =
 {
 {
-/* ??rehrauer:  The "both" option is broken, by what may be a 10.20
-   kernel problem.  It's also not terribly useful without a GUI to
-   help the user drive two debuggers.  So for now, I'm disabling
-   the "both" option.
-   "parent", "child", "both", "ask" };
- */
-  "parent", "child", "ask"};
+  follow_fork_mode_ask,
+  /* ??rehrauer: The "both" option is broken, by what may be a 10.20
+     kernel problem.  It's also not terribly useful without a GUI to
+     help the user drive two debuggers.  So for now, I'm disabling the
+     "both" option. */
+  /* follow_fork_mode_both, */
+  follow_fork_mode_child,
+  follow_fork_mode_parent,
+  NULL
+};
 
 
-static char *follow_fork_mode_string = NULL;
+static const char *follow_fork_mode_string = follow_fork_mode_parent;
 \f
 
 static void
 \f
 
 static void
@@ -448,23 +479,20 @@ follow_inferior_fork (int parent_pid, int child_pid, int has_forked,
   int followed_child = 0;
 
   /* Which process did the user want us to follow? */
   int followed_child = 0;
 
   /* Which process did the user want us to follow? */
-  char *follow_mode =
-    savestring (follow_fork_mode_string, strlen (follow_fork_mode_string));
+  const char *follow_mode = follow_fork_mode_string;
 
   /* Or, did the user not know, and want us to ask? */
 
   /* Or, did the user not know, and want us to ask? */
-  if (STREQ (follow_fork_mode_string, "ask"))
+  if (follow_fork_mode_string == follow_fork_mode_ask)
     {
     {
-      char requested_mode[100];
-
-      free (follow_mode);
-      error ("\"ask\" mode NYI");
-      follow_mode = savestring (requested_mode, strlen (requested_mode));
+      internal_error (__FILE__, __LINE__,
+                     "follow_inferior_fork: \"ask\" mode not implemented");
+      /* follow_mode = follow_fork_mode_...; */
     }
 
   /* If we're to be following the parent, then detach from child_pid.
      We're already following the parent, so need do nothing explicit
      for it. */
     }
 
   /* If we're to be following the parent, then detach from child_pid.
      We're already following the parent, so need do nothing explicit
      for it. */
-  if (STREQ (follow_mode, "parent"))
+  if (follow_mode == follow_fork_mode_parent)
     {
       followed_parent = 1;
 
     {
       followed_parent = 1;
 
@@ -488,8 +516,8 @@ follow_inferior_fork (int parent_pid, int child_pid, int has_forked,
     }
 
   /* If we're to be following the child, then attach to it, detach
     }
 
   /* If we're to be following the child, then attach to it, detach
-     from inferior_pid, and set inferior_pid to child_pid. */
-  else if (STREQ (follow_mode, "child"))
+     from inferior_ptid, and set inferior_ptid to child_pid. */
+  else if (follow_mode == follow_fork_mode_child)
     {
       char child_pid_spelling[100];    /* Arbitrary length. */
 
     {
       char child_pid_spelling[100];    /* Arbitrary length. */
 
@@ -511,7 +539,7 @@ follow_inferior_fork (int parent_pid, int child_pid, int has_forked,
 
       /* Also reset the solib inferior hook from the parent. */
 #ifdef SOLIB_REMOVE_INFERIOR_HOOK
 
       /* Also reset the solib inferior hook from the parent. */
 #ifdef SOLIB_REMOVE_INFERIOR_HOOK
-      SOLIB_REMOVE_INFERIOR_HOOK (inferior_pid);
+      SOLIB_REMOVE_INFERIOR_HOOK (PIDGET (inferior_ptid));
 #endif
 
       /* Detach from the parent. */
 #endif
 
       /* Detach from the parent. */
@@ -519,7 +547,7 @@ follow_inferior_fork (int parent_pid, int child_pid, int has_forked,
       target_detach (NULL, 1);
 
       /* Attach to the child. */
       target_detach (NULL, 1);
 
       /* Attach to the child. */
-      inferior_pid = child_pid;
+      inferior_ptid = pid_to_ptid (child_pid);
       sprintf (child_pid_spelling, "%d", child_pid);
       dont_repeat ();
 
       sprintf (child_pid_spelling, "%d", child_pid);
       dont_repeat ();
 
@@ -551,7 +579,7 @@ follow_inferior_fork (int parent_pid, int child_pid, int has_forked,
 
   /* If we're to be following both parent and child, then fork ourselves,
      and attach the debugger clone to the child. */
 
   /* If we're to be following both parent and child, then fork ourselves,
      and attach the debugger clone to the child. */
-  else if (STREQ (follow_mode, "both"))
+  else if (follow_mode == follow_fork_mode_both)
     {
       char pid_suffix[100];    /* Arbitrary length. */
 
     {
       char pid_suffix[100];    /* Arbitrary length. */
 
@@ -563,7 +591,7 @@ follow_inferior_fork (int parent_pid, int child_pid, int has_forked,
 
       /* We continue to follow the parent.  To help distinguish the two
          debuggers, though, both we and our clone will reset our prompts. */
 
       /* We continue to follow the parent.  To help distinguish the two
          debuggers, though, both we and our clone will reset our prompts. */
-      sprintf (pid_suffix, "[%d] ", inferior_pid);
+      sprintf (pid_suffix, "[%d] ", PIDGET (inferior_ptid));
       set_prompt (strcat (get_prompt (), pid_suffix));
     }
 
       set_prompt (strcat (get_prompt (), pid_suffix));
     }
 
@@ -607,8 +635,6 @@ follow_inferior_fork (int parent_pid, int child_pid, int has_forked,
 
   pending_follow.fork_event.saw_parent_fork = 0;
   pending_follow.fork_event.saw_child_fork = 0;
 
   pending_follow.fork_event.saw_parent_fork = 0;
   pending_follow.fork_event.saw_child_fork = 0;
-
-  free (follow_mode);
 }
 
 static void
 }
 
 static void
@@ -627,15 +653,18 @@ follow_vfork (int parent_pid, int child_pid)
   follow_inferior_fork (parent_pid, child_pid, 0, 1);
 
   /* Did we follow the child?  Had it exec'd before we saw the parent vfork? */
   follow_inferior_fork (parent_pid, child_pid, 0, 1);
 
   /* Did we follow the child?  Had it exec'd before we saw the parent vfork? */
-  if (pending_follow.fork_event.saw_child_exec && (inferior_pid == child_pid))
+  if (pending_follow.fork_event.saw_child_exec
+      && (PIDGET (inferior_ptid) == child_pid))
     {
       pending_follow.fork_event.saw_child_exec = 0;
       pending_follow.kind = TARGET_WAITKIND_SPURIOUS;
     {
       pending_follow.fork_event.saw_child_exec = 0;
       pending_follow.kind = TARGET_WAITKIND_SPURIOUS;
-      follow_exec (inferior_pid, pending_follow.execd_pathname);
-      free (pending_follow.execd_pathname);
+      follow_exec (PIDGET (inferior_ptid), pending_follow.execd_pathname);
+      xfree (pending_follow.execd_pathname);
     }
 }
 
     }
 }
 
+/* EXECD_PATHNAME is assumed to be non-NULL. */
+
 static void
 follow_exec (int pid, char *execd_pathname)
 {
 static void
 follow_exec (int pid, char *execd_pathname)
 {
@@ -651,13 +680,14 @@ follow_exec (int pid, char *execd_pathname)
       (pending_follow.kind == TARGET_WAITKIND_VFORKED))
     {
       pending_follow.kind = TARGET_WAITKIND_SPURIOUS;
       (pending_follow.kind == TARGET_WAITKIND_VFORKED))
     {
       pending_follow.kind = TARGET_WAITKIND_SPURIOUS;
-      follow_vfork (inferior_pid, pending_follow.fork_event.child_pid);
+      follow_vfork (PIDGET (inferior_ptid),
+                    pending_follow.fork_event.child_pid);
       follow_vfork_when_exec = 0;
       follow_vfork_when_exec = 0;
-      saved_pid = inferior_pid;
+      saved_pid = PIDGET (inferior_ptid);
 
       /* Did we follow the parent?  If so, we're done.  If we followed
          the child then we must also follow its exec(). */
 
       /* Did we follow the parent?  If so, we're done.  If we followed
          the child then we must also follow its exec(). */
-      if (inferior_pid == pending_follow.fork_event.parent_pid)
+      if (PIDGET (inferior_ptid) == pending_follow.fork_event.parent_pid)
        return;
     }
 
        return;
     }
 
@@ -706,14 +736,15 @@ follow_exec (int pid, char *execd_pathname)
 
   gdb_flush (gdb_stdout);
   target_mourn_inferior ();
 
   gdb_flush (gdb_stdout);
   target_mourn_inferior ();
-  inferior_pid = saved_pid;    /* Because mourn_inferior resets inferior_pid. */
+  inferior_ptid = pid_to_ptid (saved_pid);
+                       /* Because mourn_inferior resets inferior_ptid. */
   push_target (tgt);
 
   /* That a.out is now the one to use. */
   exec_file_attach (execd_pathname, 0);
 
   /* And also is where symbols can be found. */
   push_target (tgt);
 
   /* That a.out is now the one to use. */
   exec_file_attach (execd_pathname, 0);
 
   /* And also is where symbols can be found. */
-  symbol_file_command (execd_pathname, 0);
+  symbol_file_add_main (execd_pathname, 0);
 
   /* Reset the shared library package.  This ensures that we get
      a shlib event when the child reaches "_start", at which point
 
   /* Reset the shared library package.  This ensures that we get
      a shlib event when the child reaches "_start", at which point
@@ -722,7 +753,7 @@ follow_exec (int pid, char *execd_pathname)
   SOLIB_RESTART ();
 #endif
 #ifdef SOLIB_CREATE_INFERIOR_HOOK
   SOLIB_RESTART ();
 #endif
 #ifdef SOLIB_CREATE_INFERIOR_HOOK
-  SOLIB_CREATE_INFERIOR_HOOK (inferior_pid);
+  SOLIB_CREATE_INFERIOR_HOOK (PIDGET (inferior_ptid));
 #endif
 
   /* Reinsert all breakpoints.  (Those which were symbolic have
 #endif
 
   /* Reinsert all breakpoints.  (Those which were symbolic have
@@ -745,17 +776,22 @@ static int singlestep_breakpoints_inserted_p = 0;
 /* Things to clean up if we QUIT out of resume ().  */
 /* ARGSUSED */
 static void
 /* Things to clean up if we QUIT out of resume ().  */
 /* ARGSUSED */
 static void
-resume_cleanups (int arg)
+resume_cleanups (void *ignore)
 {
   normal_stop ();
 }
 
 {
   normal_stop ();
 }
 
-static char schedlock_off[] = "off";
-static char schedlock_on[] = "on";
-static char schedlock_step[] = "step";
-static char *scheduler_mode = schedlock_off;
-static char *scheduler_enums[] =
-{schedlock_off, schedlock_on, schedlock_step};
+static const char schedlock_off[] = "off";
+static const char schedlock_on[] = "on";
+static const char schedlock_step[] = "step";
+static const char *scheduler_mode = schedlock_off;
+static const char *scheduler_enums[] =
+{
+  schedlock_off,
+  schedlock_on,
+  schedlock_step,
+  NULL
+};
 
 static void
 set_schedlock_func (char *args, int from_tty, struct cmd_list_element *c)
 
 static void
 set_schedlock_func (char *args, int from_tty, struct cmd_list_element *c)
@@ -784,8 +820,7 @@ void
 resume (int step, enum target_signal sig)
 {
   int should_resume = 1;
 resume (int step, enum target_signal sig)
 {
   int should_resume = 1;
-  struct cleanup *old_cleanups = make_cleanup ((make_cleanup_func)
-                                              resume_cleanups, 0);
+  struct cleanup *old_cleanups = make_cleanup (resume_cleanups, 0);
   QUIT;
 
 #ifdef CANNOT_STEP_BREAKPOINT
   QUIT;
 
 #ifdef CANNOT_STEP_BREAKPOINT
@@ -796,6 +831,18 @@ resume (int step, enum target_signal sig)
     step = 0;
 #endif
 
     step = 0;
 #endif
 
+  /* Some targets (e.g. Solaris x86) have a kernel bug when stepping
+     over an instruction that causes a page fault without triggering
+     a hardware watchpoint. The kernel properly notices that it shouldn't
+     stop, because the hardware watchpoint is not triggered, but it forgets
+     the step request and continues the program normally.
+     Work around the problem by removing hardware watchpoints if a step is
+     requested, GDB will check for a hardware watchpoint trigger after the
+     step anyway.  */
+  if (CANNOT_STEP_HW_WATCHPOINTS && step && breakpoints_inserted)
+    remove_hw_watchpoints ();
+     
+
   /* Normally, by the time we reach `resume', the breakpoints are either
      removed or inserted, as appropriate.  The exception is if we're sitting
      at a permanent breakpoint; we need to step over it, but permanent
   /* Normally, by the time we reach `resume', the breakpoints are either
      removed or inserted, as appropriate.  The exception is if we're sitting
      at a permanent breakpoint; we need to step over it, but permanent
@@ -803,7 +850,7 @@ resume (int step, enum target_signal sig)
   if (breakpoint_here_p (read_pc ()) == permanent_breakpoint_here)
     SKIP_PERMANENT_BREAKPOINT ();
 
   if (breakpoint_here_p (read_pc ()) == permanent_breakpoint_here)
     SKIP_PERMANENT_BREAKPOINT ();
 
-  if (SOFTWARE_SINGLE_STEP_P && step)
+  if (SOFTWARE_SINGLE_STEP_P () && step)
     {
       /* Do it the hard way, w/temp breakpoints */
       SOFTWARE_SINGLE_STEP (sig, 1 /*insert-breakpoints */ );
     {
       /* Do it the hard way, w/temp breakpoints */
       SOFTWARE_SINGLE_STEP (sig, 1 /*insert-breakpoints */ );
@@ -825,7 +872,8 @@ resume (int step, enum target_signal sig)
     {
     case (TARGET_WAITKIND_FORKED):
       pending_follow.kind = TARGET_WAITKIND_SPURIOUS;
     {
     case (TARGET_WAITKIND_FORKED):
       pending_follow.kind = TARGET_WAITKIND_SPURIOUS;
-      follow_fork (inferior_pid, pending_follow.fork_event.child_pid);
+      follow_fork (PIDGET (inferior_ptid),
+                   pending_follow.fork_event.child_pid);
       break;
 
     case (TARGET_WAITKIND_VFORKED):
       break;
 
     case (TARGET_WAITKIND_VFORKED):
@@ -833,14 +881,15 @@ resume (int step, enum target_signal sig)
        int saw_child_exec = pending_follow.fork_event.saw_child_exec;
 
        pending_follow.kind = TARGET_WAITKIND_SPURIOUS;
        int saw_child_exec = pending_follow.fork_event.saw_child_exec;
 
        pending_follow.kind = TARGET_WAITKIND_SPURIOUS;
-       follow_vfork (inferior_pid, pending_follow.fork_event.child_pid);
+       follow_vfork (PIDGET (inferior_ptid),
+                     pending_follow.fork_event.child_pid);
 
        /* Did we follow the child, but not yet see the child's exec event?
           If so, then it actually ought to be waiting for us; we respond to
           parent vfork events.  We don't actually want to resume the child
           in this situation; we want to just get its exec event. */
        if (!saw_child_exec &&
 
        /* Did we follow the child, but not yet see the child's exec event?
           If so, then it actually ought to be waiting for us; we respond to
           parent vfork events.  We don't actually want to resume the child
           in this situation; we want to just get its exec event. */
        if (!saw_child_exec &&
-           (inferior_pid == pending_follow.fork_event.child_pid))
+           (PIDGET (inferior_ptid) == pending_follow.fork_event.child_pid))
          should_resume = 0;
       }
       break;
          should_resume = 0;
       }
       break;
@@ -861,7 +910,7 @@ resume (int step, enum target_signal sig)
 
   if (should_resume)
     {
 
   if (should_resume)
     {
-      int resume_pid;
+      ptid_t resume_ptid;
 
       if (use_thread_step_needed && thread_step_needed)
        {
 
       if (use_thread_step_needed && thread_step_needed)
        {
@@ -874,7 +923,7 @@ resume (int step, enum target_signal sig)
            {
              /* Breakpoint deleted: ok to do regular resume
                 where all the threads either step or continue. */
            {
              /* Breakpoint deleted: ok to do regular resume
                 where all the threads either step or continue. */
-             resume_pid = -1;
+             resume_ptid = RESUME_ALL;
            }
          else
            {
            }
          else
            {
@@ -886,7 +935,7 @@ resume (int step, enum target_signal sig)
                  trap_expected = 1;
                  step = 1;
                }
                  trap_expected = 1;
                  step = 1;
                }
-             resume_pid = inferior_pid;
+             resume_ptid = inferior_ptid;
            }
        }
       else
            }
        }
       else
@@ -894,11 +943,11 @@ resume (int step, enum target_signal sig)
          /* Vanilla resume. */
          if ((scheduler_mode == schedlock_on) ||
              (scheduler_mode == schedlock_step && step != 0))
          /* Vanilla resume. */
          if ((scheduler_mode == schedlock_on) ||
              (scheduler_mode == schedlock_step && step != 0))
-           resume_pid = inferior_pid;
+           resume_ptid = inferior_ptid;
          else
          else
-           resume_pid = -1;
+           resume_ptid = RESUME_ALL;
        }
        }
-      target_resume (resume_pid, step, sig);
+      target_resume (resume_ptid, step, sig);
     }
 
   discard_cleanups (old_cleanups);
     }
 
   discard_cleanups (old_cleanups);
@@ -915,7 +964,7 @@ clear_proceed_status (void)
   step_range_start = 0;
   step_range_end = 0;
   step_frame_address = 0;
   step_range_start = 0;
   step_range_end = 0;
   step_frame_address = 0;
-  step_over_calls = -1;
+  step_over_calls = STEP_OVER_UNDEBUGGABLE;
   stop_after_trap = 0;
   stop_soon_quietly = 0;
   proceed_to_finish = 0;
   stop_after_trap = 0;
   stop_soon_quietly = 0;
   proceed_to_finish = 0;
@@ -1025,9 +1074,11 @@ proceed (CORE_ADDR addr, enum target_signal siggnal, int step)
       int temp = insert_breakpoints ();
       if (temp)
        {
       int temp = insert_breakpoints ();
       if (temp)
        {
-         print_sys_errmsg ("ptrace", temp);
+         print_sys_errmsg ("insert_breakpoints", temp);
          error ("Cannot insert breakpoints.\n\
          error ("Cannot insert breakpoints.\n\
-The same program may be running in another process.");
+The same program may be running in another process,\n\
+or you may have requested too many hardware\n\
+breakpoints and/or watchpoints.\n");
        }
 
       breakpoints_inserted = 1;
        }
 
       breakpoints_inserted = 1;
@@ -1081,7 +1132,7 @@ start_remote (void)
 
   /* Always go on waiting for the target, regardless of the mode. */
   /* FIXME: cagney/1999-09-23: At present it isn't possible to
 
   /* Always go on waiting for the target, regardless of the mode. */
   /* FIXME: cagney/1999-09-23: At present it isn't possible to
-     indicate th wait_for_inferior that a target should timeout if
+     indicate to wait_for_inferior that a target should timeout if
      nothing is returned (instead of just blocking).  Because of this,
      targets expecting an immediate response need to, internally, set
      things up so that the target_wait() is forced to eventually
      nothing is returned (instead of just blocking).  Because of this,
      targets expecting an immediate response need to, internally, set
      things up so that the target_wait() is forced to eventually
@@ -1187,8 +1238,8 @@ struct execution_control_state
     int current_line;
     struct symtab *current_symtab;
     int handling_longjmp;      /* FIXME */
     int current_line;
     struct symtab *current_symtab;
     int handling_longjmp;      /* FIXME */
-    int pid;
-    int saved_inferior_pid;
+    ptid_t ptid;
+    ptid_t saved_inferior_ptid;
     int update_step_sp;
     int stepping_through_solib_after_catch;
     bpstat stepping_through_solib_catchpoints;
     int update_step_sp;
     int stepping_through_solib_after_catch;
     bpstat stepping_through_solib_catchpoints;
@@ -1197,7 +1248,7 @@ struct execution_control_state
     int new_thread_event;
     struct target_waitstatus tmpstatus;
     enum infwait_states infwait_state;
     int new_thread_event;
     struct target_waitstatus tmpstatus;
     enum infwait_states infwait_state;
-    int waiton_pid;
+    ptid_t waiton_ptid;
     int wait_some_more;
   };
 
     int wait_some_more;
   };
 
@@ -1241,7 +1292,7 @@ wait_for_inferior (void)
   thread_step_needed = 0;
 
   /* We'll update this if & when we switch to a new thread. */
   thread_step_needed = 0;
 
   /* We'll update this if & when we switch to a new thread. */
-  previous_inferior_pid = inferior_pid;
+  previous_inferior_ptid = inferior_ptid;
 
   overlay_cache_invalid = 1;
 
 
   overlay_cache_invalid = 1;
 
@@ -1256,9 +1307,9 @@ wait_for_inferior (void)
   while (1)
     {
       if (target_wait_hook)
   while (1)
     {
       if (target_wait_hook)
-       ecs->pid = target_wait_hook (ecs->waiton_pid, ecs->wp);
+       ecs->ptid = target_wait_hook (ecs->waiton_ptid, ecs->wp);
       else
       else
-       ecs->pid = target_wait (ecs->waiton_pid, ecs->wp);
+       ecs->ptid = target_wait (ecs->waiton_ptid, ecs->wp);
 
       /* Now figure out what to do with the result of the result.  */
       handle_inferior_event (ecs);
 
       /* Now figure out what to do with the result of the result.  */
       handle_inferior_event (ecs);
@@ -1282,8 +1333,7 @@ struct execution_control_state async_ecss;
 struct execution_control_state *async_ecs;
 
 void
 struct execution_control_state *async_ecs;
 
 void
-fetch_inferior_event (client_data)
-     void *client_data;
+fetch_inferior_event (void *client_data)
 {
   static struct cleanup *old_cleanups;
 
 {
   static struct cleanup *old_cleanups;
 
@@ -1302,7 +1352,7 @@ fetch_inferior_event (client_data)
       thread_step_needed = 0;
 
       /* We'll update this if & when we switch to a new thread. */
       thread_step_needed = 0;
 
       /* We'll update this if & when we switch to a new thread. */
-      previous_inferior_pid = inferior_pid;
+      previous_inferior_ptid = inferior_ptid;
 
       overlay_cache_invalid = 1;
 
 
       overlay_cache_invalid = 1;
 
@@ -1316,9 +1366,9 @@ fetch_inferior_event (client_data)
     }
 
   if (target_wait_hook)
     }
 
   if (target_wait_hook)
-    async_ecs->pid = target_wait_hook (async_ecs->waiton_pid, async_ecs->wp);
+    async_ecs->ptid = target_wait_hook (async_ecs->waiton_ptid, async_ecs->wp);
   else
   else
-    async_ecs->pid = target_wait (async_ecs->waiton_pid, async_ecs->wp);
+    async_ecs->ptid = target_wait (async_ecs->waiton_ptid, async_ecs->wp);
 
   /* Now figure out what to do with the result of the result.  */
   handle_inferior_event (async_ecs);
 
   /* Now figure out what to do with the result of the result.  */
   handle_inferior_event (async_ecs);
@@ -1356,7 +1406,7 @@ init_execution_control_state (struct execution_control_state *ecs)
   ecs->current_line = ecs->sal.line;
   ecs->current_symtab = ecs->sal.symtab;
   ecs->infwait_state = infwait_normal_state;
   ecs->current_line = ecs->sal.line;
   ecs->current_symtab = ecs->sal.symtab;
   ecs->infwait_state = infwait_normal_state;
-  ecs->waiton_pid = -1;
+  ecs->waiton_ptid = pid_to_ptid (-1);
   ecs->wp = &(ecs->ws);
 }
 
   ecs->wp = &(ecs->ws);
 }
 
@@ -1371,6 +1421,18 @@ check_for_old_step_resume_breakpoint (void)
     warning ("GDB bug: infrun.c (wait_for_inferior): dropping old step_resume breakpoint");
 }
 
     warning ("GDB bug: infrun.c (wait_for_inferior): dropping old step_resume breakpoint");
 }
 
+/* Return the cached copy of the last pid/waitstatus returned by
+   target_wait()/target_wait_hook().  The data is actually cached by
+   handle_inferior_event(), which gets called immediately after
+   target_wait()/target_wait_hook().  */
+
+void
+get_last_target_status(ptid_t *ptidp, struct target_waitstatus *status)
+{
+  *ptidp = target_last_wait_ptid;
+  *status = target_last_waitstatus;
+}
+
 /* 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.  */
 /* 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.  */
@@ -1381,6 +1443,10 @@ handle_inferior_event (struct execution_control_state *ecs)
   CORE_ADDR tmp;
   int stepped_after_stopped_by_watchpoint;
 
   CORE_ADDR tmp;
   int stepped_after_stopped_by_watchpoint;
 
+  /* Cache the last pid/waitstatus. */
+  target_last_wait_ptid = ecs->ptid;
+  target_last_waitstatus = *ecs->wp;
+
   /* Keep this extra brace for now, minimizes diffs.  */
   {
     switch (ecs->infwait_state)
   /* Keep this extra brace for now, minimizes diffs.  */
   {
     switch (ecs->infwait_state)
@@ -1395,7 +1461,7 @@ handle_inferior_event (struct execution_control_state *ecs)
           is serviced in this loop, below. */
        if (ecs->enable_hw_watchpoints_after_wait)
          {
           is serviced in this loop, below. */
        if (ecs->enable_hw_watchpoints_after_wait)
          {
-           TARGET_ENABLE_HW_WATCHPOINTS (inferior_pid);
+           TARGET_ENABLE_HW_WATCHPOINTS (PIDGET (inferior_ptid));
            ecs->enable_hw_watchpoints_after_wait = 0;
          }
        stepped_after_stopped_by_watchpoint = 0;
            ecs->enable_hw_watchpoints_after_wait = 0;
          }
        stepped_after_stopped_by_watchpoint = 0;
@@ -1405,13 +1471,13 @@ handle_inferior_event (struct execution_control_state *ecs)
        insert_breakpoints ();
 
        /* We need to restart all the threads now,
        insert_breakpoints ();
 
        /* We need to restart all the threads now,
-        * unles we're running in scheduler-locked mode. 
+        * unless we're running in scheduler-locked mode. 
         * FIXME: shouldn't we look at currently_stepping ()?
         */
        if (scheduler_mode == schedlock_on)
         * FIXME: shouldn't we look at currently_stepping ()?
         */
        if (scheduler_mode == schedlock_on)
-         target_resume (ecs->pid, 0, TARGET_SIGNAL_0);
+         target_resume (ecs->ptid, 0, TARGET_SIGNAL_0);
        else
        else
-         target_resume (-1, 0, TARGET_SIGNAL_0);
+         target_resume (RESUME_ALL, 0, TARGET_SIGNAL_0);
        ecs->infwait_state = infwait_normal_state;
        prepare_to_wait (ecs);
        return;
        ecs->infwait_state = infwait_normal_state;
        prepare_to_wait (ecs);
        return;
@@ -1434,20 +1500,21 @@ handle_inferior_event (struct execution_control_state *ecs)
 
     /* If it's a new process, add it to the thread database */
 
 
     /* If it's a new process, add it to the thread database */
 
-    ecs->new_thread_event = ((ecs->pid != inferior_pid) && !in_thread_list (ecs->pid));
+    ecs->new_thread_event = (! ptid_equal (ecs->ptid, inferior_ptid) 
+                             && ! in_thread_list (ecs->ptid));
 
     if (ecs->ws.kind != TARGET_WAITKIND_EXITED
        && ecs->ws.kind != TARGET_WAITKIND_SIGNALLED
        && ecs->new_thread_event)
       {
 
     if (ecs->ws.kind != TARGET_WAITKIND_EXITED
        && ecs->ws.kind != TARGET_WAITKIND_SIGNALLED
        && ecs->new_thread_event)
       {
-       add_thread (ecs->pid);
+       add_thread (ecs->ptid);
 
 #ifdef UI_OUT
        ui_out_text (uiout, "[New ");
 
 #ifdef UI_OUT
        ui_out_text (uiout, "[New ");
-       ui_out_text (uiout, target_pid_or_tid_to_str (ecs->pid));
+       ui_out_text (uiout, target_pid_or_tid_to_str (ecs->ptid));
        ui_out_text (uiout, "]\n");
 #else
        ui_out_text (uiout, "]\n");
 #else
-       printf_filtered ("[New %s]\n", target_pid_or_tid_to_str (ecs->pid));
+       printf_filtered ("[New %s]\n", target_pid_or_tid_to_str (ecs->ptid));
 #endif
 
 #if 0
 #endif
 
 #if 0
@@ -1470,7 +1537,7 @@ handle_inferior_event (struct execution_control_state *ecs)
           Therefore we need to continue all threads in order to
           make progress.  */
 
           Therefore we need to continue all threads in order to
           make progress.  */
 
-       target_resume (-1, 0, TARGET_SIGNAL_0);
+       target_resume (RESUME_ALL, 0, TARGET_SIGNAL_0);
        prepare_to_wait (ecs);
        return;
 #endif
        prepare_to_wait (ecs);
        return;
 #endif
@@ -1526,7 +1593,7 @@ handle_inferior_event (struct execution_control_state *ecs)
                                          (LONGEST) ecs->ws.value.integer));
        gdb_flush (gdb_stdout);
        target_mourn_inferior ();
                                          (LONGEST) ecs->ws.value.integer));
        gdb_flush (gdb_stdout);
        target_mourn_inferior ();
-       singlestep_breakpoints_inserted_p = 0;  /*SOFTWARE_SINGLE_STEP_P */
+       singlestep_breakpoints_inserted_p = 0;  /*SOFTWARE_SINGLE_STEP_P() */
        stop_print_frame = 0;
        stop_stepping (ecs);
        return;
        stop_print_frame = 0;
        stop_stepping (ecs);
        return;
@@ -1536,15 +1603,15 @@ handle_inferior_event (struct execution_control_state *ecs)
        stop_signal = ecs->ws.value.sig;
        target_terminal_ours ();        /* Must do this before mourn anyway */
 
        stop_signal = ecs->ws.value.sig;
        target_terminal_ours ();        /* Must do this before mourn anyway */
 
-       /* This looks pretty bogus to me.  Doesn't TARGET_WAITKIND_SIGNALLED
-          mean it is already dead?  This has been here since GDB 2.8, so
-          perhaps it means rms didn't understand unix waitstatuses?
-          For the moment I'm just kludging around this in remote.c
-          rather than trying to change it here --kingdon, 5 Dec 1994.  */
-       target_kill ();         /* kill mourns as well */
+       /* 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_stop_reason (SIGNAL_EXITED, stop_signal);
 
        print_stop_reason (SIGNAL_EXITED, stop_signal);
-       singlestep_breakpoints_inserted_p = 0;  /*SOFTWARE_SINGLE_STEP_P */
+       singlestep_breakpoints_inserted_p = 0;  /*SOFTWARE_SINGLE_STEP_P() */
        stop_stepping (ecs);
        return;
 
        stop_stepping (ecs);
        return;
 
@@ -1558,10 +1625,10 @@ handle_inferior_event (struct execution_control_state *ecs)
           interested in reacting to forks of the child.  Note that
           we expect the child's fork event to be available if we
           waited for it now. */
           interested in reacting to forks of the child.  Note that
           we expect the child's fork event to be available if we
           waited for it now. */
-       if (inferior_pid == ecs->pid)
+       if (ptid_equal (inferior_ptid, ecs->ptid))
          {
            pending_follow.fork_event.saw_parent_fork = 1;
          {
            pending_follow.fork_event.saw_parent_fork = 1;
-           pending_follow.fork_event.parent_pid = ecs->pid;
+           pending_follow.fork_event.parent_pid = PIDGET (ecs->ptid);
            pending_follow.fork_event.child_pid = ecs->ws.value.related_pid;
            prepare_to_wait (ecs);
            return;
            pending_follow.fork_event.child_pid = ecs->ws.value.related_pid;
            prepare_to_wait (ecs);
            return;
@@ -1569,16 +1636,16 @@ handle_inferior_event (struct execution_control_state *ecs)
        else
          {
            pending_follow.fork_event.saw_child_fork = 1;
        else
          {
            pending_follow.fork_event.saw_child_fork = 1;
-           pending_follow.fork_event.child_pid = ecs->pid;
+           pending_follow.fork_event.child_pid = PIDGET (ecs->ptid);
            pending_follow.fork_event.parent_pid = ecs->ws.value.related_pid;
          }
 
            pending_follow.fork_event.parent_pid = ecs->ws.value.related_pid;
          }
 
-       stop_pc = read_pc_pid (ecs->pid);
-       ecs->saved_inferior_pid = inferior_pid;
-       inferior_pid = ecs->pid;
+       stop_pc = read_pc_pid (ecs->ptid);
+       ecs->saved_inferior_ptid = inferior_ptid;
+       inferior_ptid = ecs->ptid;
        stop_bpstat = bpstat_stop_status (&stop_pc, currently_stepping (ecs));
        ecs->random_signal = !bpstat_explains_signal (stop_bpstat);
        stop_bpstat = bpstat_stop_status (&stop_pc, currently_stepping (ecs));
        ecs->random_signal = !bpstat_explains_signal (stop_bpstat);
-       inferior_pid = ecs->saved_inferior_pid;
+       inferior_ptid = ecs->saved_inferior_ptid;
        goto process_event_stop_test;
 
        /* If this a platform which doesn't allow a debugger to touch a
        goto process_event_stop_test;
 
        /* If this a platform which doesn't allow a debugger to touch a
@@ -1598,10 +1665,10 @@ handle_inferior_event (struct execution_control_state *ecs)
           it execs, and the child has not yet exec'd.  We probably
           should warn the user to that effect when the catchpoint
           triggers...) */
           it execs, and the child has not yet exec'd.  We probably
           should warn the user to that effect when the catchpoint
           triggers...) */
-       if (ecs->pid == inferior_pid)
+       if (ptid_equal (ecs->ptid, inferior_ptid))
          {
            pending_follow.fork_event.saw_parent_fork = 1;
          {
            pending_follow.fork_event.saw_parent_fork = 1;
-           pending_follow.fork_event.parent_pid = ecs->pid;
+           pending_follow.fork_event.parent_pid = PIDGET (ecs->ptid);
            pending_follow.fork_event.child_pid = ecs->ws.value.related_pid;
          }
 
            pending_follow.fork_event.child_pid = ecs->ws.value.related_pid;
          }
 
@@ -1611,13 +1678,14 @@ handle_inferior_event (struct execution_control_state *ecs)
        else
          {
            pending_follow.fork_event.saw_child_fork = 1;
        else
          {
            pending_follow.fork_event.saw_child_fork = 1;
-           pending_follow.fork_event.child_pid = ecs->pid;
+           pending_follow.fork_event.child_pid = PIDGET (ecs->ptid);
            pending_follow.fork_event.parent_pid = ecs->ws.value.related_pid;
            pending_follow.fork_event.parent_pid = ecs->ws.value.related_pid;
-           target_post_startup_inferior (pending_follow.fork_event.child_pid);
+           target_post_startup_inferior (
+             pid_to_ptid (pending_follow.fork_event.child_pid));
            follow_vfork_when_exec = !target_can_follow_vfork_prior_to_exec ();
            if (follow_vfork_when_exec)
              {
            follow_vfork_when_exec = !target_can_follow_vfork_prior_to_exec ();
            if (follow_vfork_when_exec)
              {
-               target_resume (ecs->pid, 0, TARGET_SIGNAL_0);
+               target_resume (ecs->ptid, 0, TARGET_SIGNAL_0);
                prepare_to_wait (ecs);
                return;
              }
                prepare_to_wait (ecs);
                return;
              }
@@ -1640,7 +1708,7 @@ handle_inferior_event (struct execution_control_state *ecs)
            inferior_ignoring_leading_exec_events--;
            if (pending_follow.kind == TARGET_WAITKIND_VFORKED)
              ENSURE_VFORKING_PARENT_REMAINS_STOPPED (pending_follow.fork_event.parent_pid);
            inferior_ignoring_leading_exec_events--;
            if (pending_follow.kind == TARGET_WAITKIND_VFORKED)
              ENSURE_VFORKING_PARENT_REMAINS_STOPPED (pending_follow.fork_event.parent_pid);
-           target_resume (ecs->pid, 0, TARGET_SIGNAL_0);
+           target_resume (ecs->ptid, 0, TARGET_SIGNAL_0);
            prepare_to_wait (ecs);
            return;
          }
            prepare_to_wait (ecs);
            return;
          }
@@ -1651,7 +1719,7 @@ handle_inferior_event (struct execution_control_state *ecs)
          savestring (ecs->ws.value.execd_pathname,
                      strlen (ecs->ws.value.execd_pathname));
 
          savestring (ecs->ws.value.execd_pathname,
                      strlen (ecs->ws.value.execd_pathname));
 
-       /* Did inferior_pid exec, or did a (possibly not-yet-followed)
+       /* Did inferior_ptid exec, or did a (possibly not-yet-followed)
           child of a vfork exec?
 
           ??rehrauer: This is unabashedly an HP-UX specific thing.  On
           child of a vfork exec?
 
           ??rehrauer: This is unabashedly an HP-UX specific thing.  On
@@ -1675,7 +1743,7 @@ handle_inferior_event (struct execution_control_state *ecs)
               the parent vfork event is delivered.  A single-step
               suffices. */
            if (RESUME_EXECD_VFORKING_CHILD_TO_GET_PARENT_VFORK ())
               the parent vfork event is delivered.  A single-step
               suffices. */
            if (RESUME_EXECD_VFORKING_CHILD_TO_GET_PARENT_VFORK ())
-             target_resume (ecs->pid, 1, TARGET_SIGNAL_0);
+             target_resume (ecs->ptid, 1, TARGET_SIGNAL_0);
            /* We expect the parent vfork event to be available now. */
            prepare_to_wait (ecs);
            return;
            /* We expect the parent vfork event to be available now. */
            prepare_to_wait (ecs);
            return;
@@ -1683,15 +1751,15 @@ handle_inferior_event (struct execution_control_state *ecs)
 
        /* This causes the eventpoints and symbol table to be reset.  Must
           do this now, before trying to determine whether to stop. */
 
        /* This causes the eventpoints and symbol table to be reset.  Must
           do this now, before trying to determine whether to stop. */
-       follow_exec (inferior_pid, pending_follow.execd_pathname);
-       free (pending_follow.execd_pathname);
+       follow_exec (PIDGET (inferior_ptid), pending_follow.execd_pathname);
+       xfree (pending_follow.execd_pathname);
 
 
-       stop_pc = read_pc_pid (ecs->pid);
-       ecs->saved_inferior_pid = inferior_pid;
-       inferior_pid = ecs->pid;
+       stop_pc = read_pc_pid (ecs->ptid);
+       ecs->saved_inferior_ptid = inferior_ptid;
+       inferior_ptid = ecs->ptid;
        stop_bpstat = bpstat_stop_status (&stop_pc, currently_stepping (ecs));
        ecs->random_signal = !bpstat_explains_signal (stop_bpstat);
        stop_bpstat = bpstat_stop_status (&stop_pc, currently_stepping (ecs));
        ecs->random_signal = !bpstat_explains_signal (stop_bpstat);
-       inferior_pid = ecs->saved_inferior_pid;
+       inferior_ptid = ecs->saved_inferior_ptid;
        goto process_event_stop_test;
 
        /* These syscall events are returned on HP-UX, as part of its
        goto process_event_stop_test;
 
        /* These syscall events are returned on HP-UX, as part of its
@@ -1715,7 +1783,7 @@ handle_inferior_event (struct execution_control_state *ecs)
        number_of_threads_in_syscalls++;
        if (number_of_threads_in_syscalls == 1)
          {
        number_of_threads_in_syscalls++;
        if (number_of_threads_in_syscalls == 1)
          {
-           TARGET_DISABLE_HW_WATCHPOINTS (inferior_pid);
+           TARGET_DISABLE_HW_WATCHPOINTS (PIDGET (inferior_ptid));
          }
        resume (0, TARGET_SIGNAL_0);
        prepare_to_wait (ecs);
          }
        resume (0, TARGET_SIGNAL_0);
        prepare_to_wait (ecs);
@@ -1736,7 +1804,7 @@ handle_inferior_event (struct execution_control_state *ecs)
           here, which will be serviced immediately after the target
           is waited on. */
       case TARGET_WAITKIND_SYSCALL_RETURN:
           here, which will be serviced immediately after the target
           is waited on. */
       case TARGET_WAITKIND_SYSCALL_RETURN:
-       target_resume (ecs->pid, 1, TARGET_SIGNAL_0);
+       target_resume (ecs->ptid, 1, TARGET_SIGNAL_0);
 
        if (number_of_threads_in_syscalls > 0)
          {
 
        if (number_of_threads_in_syscalls > 0)
          {
@@ -1772,12 +1840,12 @@ handle_inferior_event (struct execution_control_state *ecs)
        all threads in order to make progress.  */
     if (ecs->new_thread_event)
       {
        all threads in order to make progress.  */
     if (ecs->new_thread_event)
       {
-       target_resume (-1, 0, TARGET_SIGNAL_0);
+       target_resume (RESUME_ALL, 0, TARGET_SIGNAL_0);
        prepare_to_wait (ecs);
        return;
       }
 
        prepare_to_wait (ecs);
        return;
       }
 
-    stop_pc = read_pc_pid (ecs->pid);
+    stop_pc = read_pc_pid (ecs->ptid);
 
     /* See if a thread hit a thread-specific breakpoint that was meant for
        another thread.  If so, then step that thread past the breakpoint,
 
     /* See if a thread hit a thread-specific breakpoint that was meant for
        another thread.  If so, then step that thread past the breakpoint,
@@ -1785,20 +1853,20 @@ handle_inferior_event (struct execution_control_state *ecs)
 
     if (stop_signal == TARGET_SIGNAL_TRAP)
       {
 
     if (stop_signal == TARGET_SIGNAL_TRAP)
       {
-       if (SOFTWARE_SINGLE_STEP_P && singlestep_breakpoints_inserted_p)
+       if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
          ecs->random_signal = 0;
        else if (breakpoints_inserted
                 && breakpoint_here_p (stop_pc - DECR_PC_AFTER_BREAK))
          {
            ecs->random_signal = 0;
            if (!breakpoint_thread_match (stop_pc - DECR_PC_AFTER_BREAK,
          ecs->random_signal = 0;
        else if (breakpoints_inserted
                 && breakpoint_here_p (stop_pc - DECR_PC_AFTER_BREAK))
          {
            ecs->random_signal = 0;
            if (!breakpoint_thread_match (stop_pc - DECR_PC_AFTER_BREAK,
-                                         ecs->pid))
+                                         ecs->ptid))
              {
                int remove_status;
 
                /* Saw a breakpoint, but it was hit by the wrong thread.
                   Just continue. */
              {
                int remove_status;
 
                /* Saw a breakpoint, but it was hit by the wrong thread.
                   Just continue. */
-               write_pc_pid (stop_pc - DECR_PC_AFTER_BREAK, ecs->pid);
+               write_pc_pid (stop_pc - DECR_PC_AFTER_BREAK, ecs->ptid);
 
                remove_status = remove_breakpoints ();
                /* Did we fail to remove breakpoints?  If so, try
 
                remove_status = remove_breakpoints ();
                /* Did we fail to remove breakpoints?  If so, try
@@ -1810,15 +1878,15 @@ handle_inferior_event (struct execution_control_state *ecs)
                   then either :-) or execs. */
                if (remove_status != 0)
                  {
                   then either :-) or execs. */
                if (remove_status != 0)
                  {
-                   write_pc_pid (stop_pc - DECR_PC_AFTER_BREAK + 4, ecs->pid);
+                   write_pc_pid (stop_pc - DECR_PC_AFTER_BREAK + 4, ecs->ptid);
                  }
                else
                  {             /* Single step */
                  }
                else
                  {             /* Single step */
-                   target_resume (ecs->pid, 1, TARGET_SIGNAL_0);
+                   target_resume (ecs->ptid, 1, TARGET_SIGNAL_0);
                    /* FIXME: What if a signal arrives instead of the
                       single-step happening?  */
 
                    /* FIXME: What if a signal arrives instead of the
                       single-step happening?  */
 
-                   ecs->waiton_pid = ecs->pid;
+                   ecs->waiton_ptid = ecs->ptid;
                    ecs->wp = &(ecs->ws);
                    ecs->infwait_state = infwait_thread_hop_state;
                    prepare_to_wait (ecs);
                    ecs->wp = &(ecs->ws);
                    ecs->infwait_state = infwait_thread_hop_state;
                    prepare_to_wait (ecs);
@@ -1830,9 +1898,9 @@ handle_inferior_event (struct execution_control_state *ecs)
                 * FIXME: shouldn't we look at currently_stepping ()?
                 */
                if (scheduler_mode == schedlock_on)
                 * FIXME: shouldn't we look at currently_stepping ()?
                 */
                if (scheduler_mode == schedlock_on)
-                 target_resume (ecs->pid, 0, TARGET_SIGNAL_0);
+                 target_resume (ecs->ptid, 0, TARGET_SIGNAL_0);
                else
                else
-                 target_resume (-1, 0, TARGET_SIGNAL_0);
+                 target_resume (RESUME_ALL, 0, TARGET_SIGNAL_0);
                prepare_to_wait (ecs);
                return;
              }
                prepare_to_wait (ecs);
                return;
              }
@@ -1856,7 +1924,7 @@ handle_inferior_event (struct execution_control_state *ecs)
        Note that if there's any kind of pending follow (i.e., of a fork,
        vfork or exec), we don't want to do this now.  Rather, we'll let
        the next resume handle it. */
        Note that if there's any kind of pending follow (i.e., of a fork,
        vfork or exec), we don't want to do this now.  Rather, we'll let
        the next resume handle it. */
-    if ((ecs->pid != inferior_pid) &&
+    if (! ptid_equal (ecs->ptid, inferior_ptid) &&
        (pending_follow.kind == TARGET_WAITKIND_SPURIOUS))
       {
        int printed = 0;
        (pending_follow.kind == TARGET_WAITKIND_SPURIOUS))
       {
        int printed = 0;
@@ -1899,7 +1967,7 @@ handle_inferior_event (struct execution_control_state *ecs)
            if (signal_program[stop_signal] == 0)
              stop_signal = TARGET_SIGNAL_0;
 
            if (signal_program[stop_signal] == 0)
              stop_signal = TARGET_SIGNAL_0;
 
-           target_resume (ecs->pid, 0, stop_signal);
+           target_resume (ecs->ptid, 0, stop_signal);
            prepare_to_wait (ecs);
            return;
          }
            prepare_to_wait (ecs);
            return;
          }
@@ -1913,10 +1981,10 @@ handle_inferior_event (struct execution_control_state *ecs)
           be lost.  This may happen as a result of the target module
           mishandling thread creation.  */
 
           be lost.  This may happen as a result of the target module
           mishandling thread creation.  */
 
-       if (in_thread_list (inferior_pid) && in_thread_list (ecs->pid))
+       if (in_thread_list (inferior_ptid) && in_thread_list (ecs->ptid))
          { /* Perform infrun state context switch: */
            /* Save infrun state for the old thread.  */
          { /* Perform infrun state context switch: */
            /* Save infrun state for the old thread.  */
-           save_infrun_state (inferior_pid, prev_pc,
+           save_infrun_state (inferior_ptid, prev_pc,
                               prev_func_start, prev_func_name,
                               trap_expected, step_resume_breakpoint,
                               through_sigtramp_breakpoint,
                               prev_func_start, prev_func_name,
                               trap_expected, step_resume_breakpoint,
                               through_sigtramp_breakpoint,
@@ -1928,7 +1996,7 @@ handle_inferior_event (struct execution_control_state *ecs)
                               ecs->stepping_through_sigtramp);
 
            /* Load infrun state for the new thread.  */
                               ecs->stepping_through_sigtramp);
 
            /* Load infrun state for the new thread.  */
-           load_infrun_state (ecs->pid, &prev_pc,
+           load_infrun_state (ecs->ptid, &prev_pc,
                               &prev_func_start, &prev_func_name,
                               &trap_expected, &step_resume_breakpoint,
                               &through_sigtramp_breakpoint,
                               &prev_func_start, &prev_func_name,
                               &trap_expected, &step_resume_breakpoint,
                               &through_sigtramp_breakpoint,
@@ -1940,15 +2008,15 @@ handle_inferior_event (struct execution_control_state *ecs)
                               &ecs->stepping_through_sigtramp);
          }
 
                               &ecs->stepping_through_sigtramp);
          }
 
-       inferior_pid = ecs->pid;
+       inferior_ptid = ecs->ptid;
 
        if (context_hook)
 
        if (context_hook)
-         context_hook (pid_to_thread_id (ecs->pid));
+         context_hook (pid_to_thread_id (ecs->ptid));
 
        flush_cached_frames ();
       }
 
 
        flush_cached_frames ();
       }
 
-    if (SOFTWARE_SINGLE_STEP_P && singlestep_breakpoints_inserted_p)
+    if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
       {
        /* Pull the single step breakpoints out of the target. */
        SOFTWARE_SINGLE_STEP (0, 0);
       {
        /* Pull the single step breakpoints out of the target. */
        SOFTWARE_SINGLE_STEP (0, 0);
@@ -1963,14 +2031,14 @@ handle_inferior_event (struct execution_control_state *ecs)
     if (INSTRUCTION_NULLIFIED)
       {
        registers_changed ();
     if (INSTRUCTION_NULLIFIED)
       {
        registers_changed ();
-       target_resume (ecs->pid, 1, TARGET_SIGNAL_0);
+       target_resume (ecs->ptid, 1, TARGET_SIGNAL_0);
 
        /* We may have received a signal that we want to pass to
           the inferior; therefore, we must not clobber the waitstatus
           in WS. */
 
        ecs->infwait_state = infwait_nullified_state;
 
        /* We may have received a signal that we want to pass to
           the inferior; therefore, we must not clobber the waitstatus
           in WS. */
 
        ecs->infwait_state = infwait_nullified_state;
-       ecs->waiton_pid = ecs->pid;
+       ecs->waiton_ptid = ecs->ptid;
        ecs->wp = &(ecs->tmpstatus);
        prepare_to_wait (ecs);
        return;
        ecs->wp = &(ecs->tmpstatus);
        prepare_to_wait (ecs);
        return;
@@ -2012,9 +2080,9 @@ handle_inferior_event (struct execution_control_state *ecs)
 
        remove_breakpoints ();
        registers_changed ();
 
        remove_breakpoints ();
        registers_changed ();
-       target_resume (ecs->pid, 1, TARGET_SIGNAL_0);   /* Single step */
+       target_resume (ecs->ptid, 1, TARGET_SIGNAL_0);  /* Single step */
 
 
-       ecs->waiton_pid = ecs->pid;
+       ecs->waiton_ptid = ecs->ptid;
        ecs->wp = &(ecs->ws);
        ecs->infwait_state = infwait_nonstep_watch_state;
        prepare_to_wait (ecs);
        ecs->wp = &(ecs->ws);
        ecs->infwait_state = infwait_nonstep_watch_state;
        prepare_to_wait (ecs);
@@ -2248,6 +2316,8 @@ handle_inferior_event (struct execution_control_state *ecs)
            the HP-UX maintainer to furnish a fix that doesn't break other
            platforms.  --JimB, 20 May 1999 */
        check_sigtramp2 (ecs);
            the HP-UX maintainer to furnish a fix that doesn't break other
            platforms.  --JimB, 20 May 1999 */
        check_sigtramp2 (ecs);
+       keep_going (ecs);
+       return;
       }
 
     /* Handle cases caused by hitting a breakpoint.  */
       }
 
     /* Handle cases caused by hitting a breakpoint.  */
@@ -2498,7 +2568,7 @@ handle_inferior_event (struct execution_control_state *ecs)
       {
 #if defined(SOLIB_ADD)
        /* Have we reached our destination?  If not, keep going. */
       {
 #if defined(SOLIB_ADD)
        /* Have we reached our destination?  If not, keep going. */
-       if (SOLIB_IN_DYNAMIC_LINKER (ecs->pid, stop_pc))
+       if (SOLIB_IN_DYNAMIC_LINKER (PIDGET (ecs->ptid), stop_pc))
          {
            ecs->another_trap = 1;
            keep_going (ecs);
          {
            ecs->another_trap = 1;
            keep_going (ecs);
@@ -2584,7 +2654,7 @@ handle_inferior_event (struct execution_control_state *ecs)
        loader dynamic symbol resolution code, we keep on single stepping
        until we exit the run time loader code and reach the callee's
        address.  */
        loader dynamic symbol resolution code, we keep on single stepping
        until we exit the run time loader code and reach the callee's
        address.  */
-    if (step_over_calls < 0 && IN_SOLIB_DYNSYM_RESOLVE_CODE (stop_pc))
+    if (step_over_calls == STEP_OVER_UNDEBUGGABLE && IN_SOLIB_DYNSYM_RESOLVE_CODE (stop_pc))
       {
        CORE_ADDR pc_after_resolver = SKIP_SOLIB_RESOLVER (stop_pc);
 
       {
        CORE_ADDR pc_after_resolver = SKIP_SOLIB_RESOLVER (stop_pc);
 
@@ -2705,7 +2775,7 @@ handle_inferior_event (struct execution_control_state *ecs)
       {
        /* It's a subroutine call.  */
 
       {
        /* It's a subroutine call.  */
 
-       if (step_over_calls == 0)
+       if (step_over_calls == STEP_OVER_NONE)
          {
            /* I presume that step_over_calls is only 0 when we're
               supposed to be stepping at the assembly language level
          {
            /* I presume that step_over_calls is only 0 when we're
               supposed to be stepping at the assembly language level
@@ -2716,9 +2786,23 @@ handle_inferior_event (struct execution_control_state *ecs)
            return;
          }
 
            return;
          }
 
-       if (step_over_calls > 0 || IGNORE_HELPER_CALL (stop_pc))
+       if (step_over_calls == STEP_OVER_ALL || IGNORE_HELPER_CALL (stop_pc))
          {
            /* We're doing a "next".  */
          {
            /* We're doing a "next".  */
+
+           if (IN_SIGTRAMP (stop_pc, ecs->stop_func_name)
+               && INNER_THAN (step_frame_address, read_sp()))
+             /* We stepped out of a signal handler, and into its
+                 calling trampoline.  This is misdetected as a
+                 subroutine call, but stepping over the signal
+                 trampoline isn't such a bad idea.  In order to do
+                 that, we have to ignore the value in
+                 step_frame_address, since that doesn't represent the
+                 frame that'll reach when we return from the signal
+                 trampoline.  Otherwise we'll probably continue to the
+                 end of the program.  */
+             step_frame_address = 0;
+
            step_over_function (ecs);
            keep_going (ecs);
            return;
            step_over_function (ecs);
            keep_going (ecs);
            return;
@@ -2768,6 +2852,18 @@ handle_inferior_event (struct execution_control_state *ecs)
              return;
            }
        }
              return;
            }
        }
+
+       /* 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
+          switch in assembly mode.  */
+       if (step_over_calls == STEP_OVER_UNDEBUGGABLE && step_stop_if_no_debug)
+         {
+           stop_step = 1;
+           print_stop_reason (END_STEPPING_RANGE, 0);
+           stop_stepping (ecs);
+           return;
+         }
+
        step_over_function (ecs);
        keep_going (ecs);
        return;
        step_over_function (ecs);
        keep_going (ecs);
        return;
@@ -3019,7 +3115,7 @@ step_over_function (struct execution_control_state *ecs)
   step_resume_breakpoint =
     set_momentary_breakpoint (sr_sal, get_current_frame (), bp_step_resume);
 
   step_resume_breakpoint =
     set_momentary_breakpoint (sr_sal, get_current_frame (), bp_step_resume);
 
-  if (!IN_SOLIB_DYNSYM_RESOLVE_CODE (sr_sal.pc))
+  if (step_frame_address && !IN_SOLIB_DYNSYM_RESOLVE_CODE (sr_sal.pc))
     step_resume_breakpoint->frame = step_frame_address;
 
   if (breakpoints_inserted)
     step_resume_breakpoint->frame = step_frame_address;
 
   if (breakpoints_inserted)
@@ -3033,26 +3129,26 @@ stop_stepping (struct execution_control_state *ecs)
     {
       /* Are we stopping for a vfork event?  We only stop when we see
          the child's event.  However, we may not yet have seen the
     {
       /* Are we stopping for a vfork event?  We only stop when we see
          the child's event.  However, we may not yet have seen the
-         parent's event.  And, inferior_pid is still set to the
+         parent's event.  And, inferior_ptid is still set to the
          parent's pid, until we resume again and follow either the
          parent or child.
 
          parent's pid, until we resume again and follow either the
          parent or child.
 
-         To ensure that we can really touch inferior_pid (aka, the
+         To ensure that we can really touch inferior_ptid (aka, the
          parent process) -- which calls to functions like read_pc
          implicitly do -- wait on the parent if necessary. */
       if ((pending_follow.kind == TARGET_WAITKIND_VFORKED)
          && !pending_follow.fork_event.saw_parent_fork)
        {
          parent process) -- which calls to functions like read_pc
          implicitly do -- wait on the parent if necessary. */
       if ((pending_follow.kind == TARGET_WAITKIND_VFORKED)
          && !pending_follow.fork_event.saw_parent_fork)
        {
-         int parent_pid;
+         ptid_t parent_ptid;
 
          do
            {
              if (target_wait_hook)
 
          do
            {
              if (target_wait_hook)
-               parent_pid = target_wait_hook (-1, &(ecs->ws));
+               parent_ptid = target_wait_hook (pid_to_ptid (-1), &(ecs->ws));
              else
              else
-               parent_pid = target_wait (-1, &(ecs->ws));
+               parent_ptid = target_wait (pid_to_ptid (-1), &(ecs->ws));
            }
            }
-         while (parent_pid != inferior_pid);
+         while (! ptid_equal (parent_ptid, inferior_ptid));
        }
 
       /* Assuming the inferior still exists, set these up for next
        }
 
       /* Assuming the inferior still exists, set these up for next
@@ -3197,7 +3293,7 @@ prepare_to_wait (struct execution_control_state *ecs)
         as part of their normal status mechanism. */
 
       registers_changed ();
         as part of their normal status mechanism. */
 
       registers_changed ();
-      ecs->waiton_pid = -1;
+      ecs->waiton_ptid = pid_to_ptid (-1);
       ecs->wp = &(ecs->ws);
     }
   /* This is the old end of the while loop.  Let everybody know we
       ecs->wp = &(ecs->ws);
     }
   /* This is the old end of the while loop.  Let everybody know we
@@ -3323,7 +3419,8 @@ print_stop_reason (enum inferior_stop_reason stop_reason, int stop_info)
 #endif
       break;
     default:
 #endif
       break;
     default:
-      internal_error ("print_stop_reason: unrecognized enum value");
+      internal_error (__FILE__, __LINE__,
+                     "print_stop_reason: unrecognized enum value");
       break;
     }
 }
       break;
     }
 }
@@ -3346,13 +3443,13 @@ normal_stop (void)
 
      (Note that there's no point in saying anything if the inferior
      has exited!) */
 
      (Note that there's no point in saying anything if the inferior
      has exited!) */
-  if ((previous_inferior_pid != inferior_pid)
+  if (! ptid_equal (previous_inferior_ptid, inferior_ptid)
       && target_has_execution)
     {
       target_terminal_ours_for_output ();
       printf_filtered ("[Switching to %s]\n",
       && target_has_execution)
     {
       target_terminal_ours_for_output ();
       printf_filtered ("[Switching to %s]\n",
-                      target_pid_or_tid_to_str (inferior_pid));
-      previous_inferior_pid = inferior_pid;
+                      target_pid_or_tid_to_str (inferior_ptid));
+      previous_inferior_ptid = inferior_ptid;
     }
 
   /* Make sure that the current_frame's pc is correct.  This
     }
 
   /* Make sure that the current_frame's pc is correct.  This
@@ -3364,9 +3461,11 @@ normal_stop (void)
   if (breakpoints_failed)
     {
       target_terminal_ours_for_output ();
   if (breakpoints_failed)
     {
       target_terminal_ours_for_output ();
-      print_sys_errmsg ("ptrace", breakpoints_failed);
+      print_sys_errmsg ("While inserting breakpoints", breakpoints_failed);
       printf_filtered ("Stopped; cannot insert breakpoints.\n\
       printf_filtered ("Stopped; cannot insert breakpoints.\n\
-The same program may be running in another process.\n");
+The same program may be running in another process,\n\
+or you may have requested too many hardware breakpoints\n\
+and/or watchpoints.\n");
     }
 
   if (target_has_execution && breakpoints_inserted)
     }
 
   if (target_has_execution && breakpoints_inserted)
@@ -3402,9 +3501,9 @@ The same program may be running in another process.\n");
 
   /* Look up the hook_stop and run it if it exists.  */
 
 
   /* Look up the hook_stop and run it if it exists.  */
 
-  if (stop_command && stop_command->hook)
+  if (stop_command && stop_command->hook_pre)
     {
     {
-      catch_errors (hook_stop_stub, stop_command->hook,
+      catch_errors (hook_stop_stub, stop_command->hook_pre,
                    "Error while running hook_stop:\n", RETURN_MASK_ALL);
     }
 
                    "Error while running hook_stop:\n", RETURN_MASK_ALL);
     }
 
@@ -3454,10 +3553,12 @@ The same program may be running in another process.\n");
              source_flag = SRC_LINE;
              break;
            case PRINT_NOTHING:
              source_flag = SRC_LINE;
              break;
            case PRINT_NOTHING:
+             source_flag = SRC_LINE; /* something bogus */
              do_frame_printing = 0;
              break;
            default:
              do_frame_printing = 0;
              break;
            default:
-             internal_error ("Unknown value.");
+             internal_error (__FILE__, __LINE__,
+                             "Unknown value.");
            }
 #ifdef UI_OUT
          /* For mi, have the same behavior every time we stop:
            }
 #ifdef UI_OUT
          /* For mi, have the same behavior every time we stop:
@@ -3468,7 +3569,8 @@ The same program may be running in another process.\n");
 
 #ifdef UI_OUT
          if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
 
 #ifdef UI_OUT
          if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
-           ui_out_field_int (uiout, "thread-id", pid_to_thread_id (inferior_pid));
+           ui_out_field_int (uiout, "thread-id",
+                             pid_to_thread_id (inferior_ptid));
 #endif
          /* The behavior of this routine with respect to the source
             flag is:
 #endif
          /* The behavior of this routine with respect to the source
             flag is:
@@ -3751,7 +3853,7 @@ Are you sure you want to change it? ",
       argv++;
     }
 
       argv++;
     }
 
-  target_notice_signals (inferior_pid);
+  target_notice_signals (inferior_ptid);
 
   if (from_tty)
     {
 
   if (from_tty)
     {
@@ -3830,7 +3932,7 @@ xdb_handle_command (char *args, int from_tty)
          else
            printf_filtered ("Invalid signal handling flag.\n");
          if (argBuf)
          else
            printf_filtered ("Invalid signal handling flag.\n");
          if (argBuf)
-           free (argBuf);
+           xfree (argBuf);
        }
     }
   do_cleanups (old_chain);
        }
     }
   do_cleanups (old_chain);
@@ -3855,7 +3957,7 @@ signals_info (char *signum_exp, int from_tty)
        {
          /* No, try numeric.  */
          oursig =
        {
          /* No, try numeric.  */
          oursig =
-           target_signal_from_command (parse_and_eval_address (signum_exp));
+           target_signal_from_command (parse_and_eval_long (signum_exp));
        }
       sig_print_info (oursig);
       return;
        }
       sig_print_info (oursig);
       return;
@@ -3890,7 +3992,7 @@ struct inferior_status
   CORE_ADDR step_range_start;
   CORE_ADDR step_range_end;
   CORE_ADDR step_frame_address;
   CORE_ADDR step_range_start;
   CORE_ADDR step_range_end;
   CORE_ADDR step_frame_address;
-  int step_over_calls;
+  enum step_over_calls_kind step_over_calls;
   CORE_ADDR step_resume_break_address;
   int stop_after_trap;
   int stop_soon_quietly;
   CORE_ADDR step_resume_break_address;
   int stop_after_trap;
   int stop_soon_quietly;
@@ -3921,9 +4023,9 @@ xmalloc_inferior_status (void)
 static void
 free_inferior_status (struct inferior_status *inf_status)
 {
 static void
 free_inferior_status (struct inferior_status *inf_status)
 {
-  free (inf_status->registers);
-  free (inf_status->stop_registers);
-  free (inf_status);
+  xfree (inf_status->registers);
+  xfree (inf_status->stop_registers);
+  xfree (inf_status);
 }
 
 void
 }
 
 void
@@ -4070,6 +4172,18 @@ restore_inferior_status (struct inferior_status *inf_status)
   free_inferior_status (inf_status);
 }
 
   free_inferior_status (inf_status);
 }
 
+static void
+do_restore_inferior_status_cleanup (void *sts)
+{
+  restore_inferior_status (sts);
+}
+
+struct cleanup *
+make_cleanup_restore_inferior_status (struct inferior_status *inf_status)
+{
+  return make_cleanup (do_restore_inferior_status_cleanup, inf_status);
+}
+
 void
 discard_inferior_status (struct inferior_status *inf_status)
 {
 void
 discard_inferior_status (struct inferior_status *inf_status)
 {
@@ -4078,20 +4192,6 @@ discard_inferior_status (struct inferior_status *inf_status)
   free_inferior_status (inf_status);
 }
 
   free_inferior_status (inf_status);
 }
 
-static void
-set_follow_fork_mode_command (char *arg, int from_tty,
-                             struct cmd_list_element *c)
-{
-  if (!STREQ (arg, "parent") &&
-      !STREQ (arg, "child") &&
-      !STREQ (arg, "both") &&
-      !STREQ (arg, "ask"))
-    error ("follow-fork-mode must be one of \"parent\", \"child\", \"both\" or \"ask\".");
-
-  if (follow_fork_mode_string != NULL)
-    free (follow_fork_mode_string);
-  follow_fork_mode_string = savestring (arg, strlen (arg));
-}
 \f
 static void
 build_infrun (void)
 \f
 static void
 build_infrun (void)
@@ -4223,7 +4323,7 @@ to the user would be loading/unloading of a new library.\n",
   c = add_set_enum_cmd ("follow-fork-mode",
                        class_run,
                        follow_fork_mode_kind_names,
   c = add_set_enum_cmd ("follow-fork-mode",
                        class_run,
                        follow_fork_mode_kind_names,
-                       (char *) &follow_fork_mode_string,
+                       &follow_fork_mode_string,
 /* ??rehrauer:  The "both" option is broken, by what may be a 10.20
    kernel problem.  It's also not terribly useful without a GUI to
    help the user drive two debuggers.  So for now, I'm disabling
 /* ??rehrauer:  The "both" option is broken, by what may be a 10.20
    kernel problem.  It's also not terribly useful without a GUI to
    help the user drive two debuggers.  So for now, I'm disabling
@@ -4254,11 +4354,9 @@ By default, the debugger will follow the parent process.",
 /*  c->function.sfunc = ; */
   add_show_from_set (c, &showlist);
 
 /*  c->function.sfunc = ; */
   add_show_from_set (c, &showlist);
 
-  set_follow_fork_mode_command ("parent", 0, NULL);
-
   c = add_set_enum_cmd ("scheduler-locking", class_run,
                        scheduler_enums,        /* array of string names */
   c = add_set_enum_cmd ("scheduler-locking", class_run,
                        scheduler_enums,        /* array of string names */
-                       (char *) &scheduler_mode,       /* current mode  */
+                       &scheduler_mode,        /* current mode  */
                        "Set mode for locking scheduler during execution.\n\
 off  == no locking (threads may preempt at any time)\n\
 on   == full locking (no thread except the current thread may run)\n\
                        "Set mode for locking scheduler during execution.\n\
 off  == no locking (threads may preempt at any time)\n\
 on   == full locking (no thread except the current thread may run)\n\
@@ -4269,4 +4367,13 @@ step == scheduler locked during every single-step operation.\n\
 
   c->function.sfunc = set_schedlock_func;      /* traps on target vector */
   add_show_from_set (c, &showlist);
 
   c->function.sfunc = set_schedlock_func;      /* traps on target vector */
   add_show_from_set (c, &showlist);
+
+  c = add_set_cmd ("step-mode", class_run,
+                  var_boolean, (char*) &step_stop_if_no_debug,
+"Set mode of the step operation. When set, doing a step over a\n\
+function without debug line information will stop at the first\n\
+instruction of that function. Otherwise, the function is skipped and\n\
+the step command stops at a different source line.",
+                       &setlist);
+  add_show_from_set (c, &showlist);
 }
 }
This page took 0.044816 seconds and 4 git commands to generate.