* config/i386/nm-nbsd.h (FLOAT_INFO): Comment out.
[deliverable/binutils-gdb.git] / gdb / infrun.c
index 3fc8cf176745579b05351f73418c0b77c9168583..623e1da8b9ac859f374a1719fae3b7c94d1d4e79 100644 (file)
@@ -1,5 +1,5 @@
 /* Target-struct-independent code to start (run) and stop an inferior process.
-   Copyright 1986, 1987, 1988, 1989, 1991, 1992, 1993, 1994
+   Copyright 1986, 1987, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996
    Free Software Foundation, Inc.
 
 This file is part of GDB.
@@ -16,10 +16,10 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 #include "defs.h"
-#include <string.h>
+#include "gdb_string.h"
 #include <ctype.h>
 #include "symtab.h"
 #include "frame.h"
@@ -30,6 +30,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "gdbcmd.h"
 #include "target.h"
 #include "thread.h"
+#include "annotate.h"
 
 #include <signal.h>
 
@@ -42,26 +43,22 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 /* Prototypes for local functions */
 
-static void
-signals_info PARAMS ((char *, int));
+static void signals_info PARAMS ((char *, int));
 
-static void
-handle_command PARAMS ((char *, int));
+static void handle_command PARAMS ((char *, int));
 
 static void sig_print_info PARAMS ((enum target_signal));
 
-static void
-sig_print_header PARAMS ((void));
+static void sig_print_header PARAMS ((void));
 
-static void
-resume_cleanups PARAMS ((int));
+static void resume_cleanups PARAMS ((int));
 
-static int
-hook_stop_stub PARAMS ((char *));
+static int hook_stop_stub PARAMS ((char *));
 
 /* GET_LONGJMP_TARGET returns the PC at which longjmp() will resume the
    program.  It needs to examine the jmp_buf argument and extract the PC
    from it.  The return value is non-zero on success, zero otherwise. */
+
 #ifndef GET_LONGJMP_TARGET
 #define GET_LONGJMP_TARGET(PC_ADDR) 0
 #endif
@@ -70,22 +67,39 @@ hook_stop_stub PARAMS ((char *));
 /* Some machines have trampoline code that sits between function callers
    and the actual functions themselves.  If this machine doesn't have
    such things, disable their processing.  */
+
 #ifndef SKIP_TRAMPOLINE_CODE
 #define        SKIP_TRAMPOLINE_CODE(pc)        0
 #endif
 
-/* On Irix 5, some function calls automatically skip the first few
-   instructions, so we need a more complicated test to see if we are
-   the start of a function.  */
-#ifndef AT_FUNCTION_START
-#define AT_FUNCTION_START(pc,func_name,func_addr)      0
+/* Dynamic function trampolines are similar to solib trampolines in that they
+   are between the caller and the callee.  The difference is that when you
+   enter a dynamic trampoline, you can't determine the callee's address.  Some
+   (usually complex) code needs to run in the dynamic trampoline to figure out
+   the callee's address.  This macro is usually called twice.  First, when we
+   enter the trampoline (looks like a normal function call at that point).  It
+   should return the PC of a point within the trampoline where the callee's
+   address is known.  Second, when we hit the breakpoint, this routine returns
+   the callee's address.  At that point, things proceed as per a step resume
+   breakpoint.  */
+
+#ifndef DYNAMIC_TRAMPOLINE_NEXTPC
+#define DYNAMIC_TRAMPOLINE_NEXTPC(pc) 0
 #endif
 
 /* For SVR4 shared libraries, each call goes through a small piece of
-   trampoline code in the ".init" section.  IN_SOLIB_TRAMPOLINE evaluates
+   trampoline code in the ".plt" section.  IN_SOLIB_CALL_TRAMPOLINE evaluates
    to nonzero if we are current stopped in one of these. */
-#ifndef IN_SOLIB_TRAMPOLINE
-#define IN_SOLIB_TRAMPOLINE(pc,name)   0
+
+#ifndef IN_SOLIB_CALL_TRAMPOLINE
+#define IN_SOLIB_CALL_TRAMPOLINE(pc,name)      0
+#endif
+
+/* In some shared library schemes, the return path from a shared library
+   call may need to go through a trampoline too.  */
+
+#ifndef IN_SOLIB_RETURN_TRAMPOLINE
+#define IN_SOLIB_RETURN_TRAMPOLINE(pc,name)    0
 #endif
 
 /* On some systems, the PC may be left pointing at an instruction that  won't
@@ -137,11 +151,17 @@ static struct symbol *step_start_function;
 
 static int trap_expected;
 
+/* Nonzero if we want to give control to the user when we're notified
+   of shared library events by the dynamic linker.  */
+static int stop_on_solib_events;
+
+#ifdef HP_OS_BUG
 /* Nonzero if the next time we try to continue the inferior, it will
    step one instruction and generate a spurious trace trap.
    This is used to compensate for a bug in HP-UX.  */
 
 static int trap_expected_after_continue;
+#endif
 
 /* Nonzero means expecting a trace trap
    and should stop the inferior and return silently when it happens.  */
@@ -287,10 +307,38 @@ proceed (addr, siggnal, step)
 
       if (breakpoint_here_p (read_pc ()))
        oneproc = 1;
+
+#ifdef STEP_SKIPS_DELAY
+      /* Check breakpoint_here_p first, because breakpoint_here_p is fast
+        (it just checks internal GDB data structures) and STEP_SKIPS_DELAY
+        is slow (it needs to read memory from the target).  */
+      if (breakpoint_here_p (read_pc () + 4)
+         && STEP_SKIPS_DELAY (read_pc ()))
+       oneproc = 1;
+#endif /* STEP_SKIPS_DELAY */
     }
   else
     write_pc (addr);
 
+#ifdef PREPARE_TO_PROCEED
+  /* In a multi-threaded task we may select another thread and then continue.
+     
+     In this case the thread that stopped at a breakpoint will immediately
+     cause another stop, if it is not stepped over first. On the other hand,
+     if (ADDR != -1) we only want to single step over the breakpoint if we did
+     switch to another thread.
+
+     If we are single stepping, don't do any of the above.
+     (Note that in the current implementation single stepping another
+     thread after a breakpoint and then continuing will cause the original
+     breakpoint to be hit again, but you can always continue, so it's not
+     a big deal.)  */
+
+  if (! step && PREPARE_TO_PROCEED (1) && breakpoint_here_p (read_pc ()))
+    oneproc = 1;
+#endif /* PREPARE_TO_PROCEED */
+
+#ifdef HP_OS_BUG
   if (trap_expected_after_continue)
     {
       /* If (step == 0), a trap will be automatically generated after
@@ -300,6 +348,7 @@ proceed (addr, siggnal, step)
       oneproc = 1;
       trap_expected_after_continue = 0;
     }
+#endif /* HP_OS_BUG */
 
   if (oneproc)
     /* We will get a trace trap after one instruction.
@@ -324,6 +373,12 @@ The same program may be running in another process.");
   else if (!signal_program[stop_signal])
     stop_signal = TARGET_SIGNAL_0;
 
+  annotate_starting ();
+
+  /* Make sure that output from GDB appears before output from the
+     inferior.  */
+  gdb_flush (gdb_stdout);
+
   /* Resume inferior.  */
   resume (oneproc || step || bpstat_should_step (), stop_signal);
 
@@ -339,7 +394,6 @@ The same program may be running in another process.");
    to be preserved over calls to it and cleared when the inferior
    is started.  */
 static CORE_ADDR prev_pc;
-static CORE_ADDR prev_sp;
 static CORE_ADDR prev_func_start;
 static char *prev_func_name;
 
@@ -349,6 +403,7 @@ static char *prev_func_name;
 void
 start_remote ()
 {
+  init_thread_list ();
   init_wait_for_inferior ();
   clear_proceed_status ();
   stop_soon_quietly = 1;
@@ -364,11 +419,12 @@ init_wait_for_inferior ()
 {
   /* These are meaningless until the first time through wait_for_inferior.  */
   prev_pc = 0;
-  prev_sp = 0;
   prev_func_start = 0;
   prev_func_name = NULL;
 
+#ifdef HP_OS_BUG
   trap_expected_after_continue = 0;
+#endif
   breakpoints_inserted = 0;
   breakpoint_init_inferior ();
 
@@ -398,7 +454,6 @@ wait_for_inferior ()
   struct target_waitstatus w;
   int another_trap;
   int random_signal;
-  CORE_ADDR stop_sp = 0;
   CORE_ADDR stop_func_start;
   CORE_ADDR stop_func_end;
   char *stop_func_name;
@@ -409,28 +464,65 @@ wait_for_inferior ()
   struct symtab *current_symtab;
   int handling_longjmp = 0;    /* FIXME */
   struct breakpoint *step_resume_breakpoint = NULL;
+  struct breakpoint *through_sigtramp_breakpoint = NULL;
   int pid;
+  int update_step_sp = 0;
 
   old_cleanups = make_cleanup (delete_breakpoint_current_contents,
                               &step_resume_breakpoint);
+  make_cleanup (delete_breakpoint_current_contents,
+               &through_sigtramp_breakpoint);
   sal = find_pc_line(prev_pc, 0);
   current_line = sal.line;
   current_symtab = sal.symtab;
 
   /* Are we stepping?  */
-#define CURRENTLY_STEPPING() ((step_resume_breakpoint == NULL \
-                              && !handling_longjmp \
-                              && (step_range_end \
-                                  || trap_expected)) \
-                             || bpstat_should_step ())
+#define CURRENTLY_STEPPING() \
+  ((through_sigtramp_breakpoint == NULL \
+    && !handling_longjmp \
+    && ((step_range_end && step_resume_breakpoint == NULL) \
+       || trap_expected)) \
+   || bpstat_should_step ())
 
   while (1)
     {
-      /* Clean up saved state that will become invalid.  */
-      flush_cached_frames ();
+      /* 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 ();
 
-      pid = target_wait (-1, &w);
+      if (target_wait_hook)
+       pid = target_wait_hook (-1, &w);
+      else
+       pid = target_wait (-1, &w);
+
+#ifdef HAVE_NONSTEPPABLE_WATCHPOINT
+    have_waited:
+#endif
+
+      flush_cached_frames ();
+
+      /* If it's a new process, add it to the thread database */
+
+      if (pid != inferior_pid
+         && !in_thread_list (pid))
+       {
+         fprintf_unfiltered (gdb_stderr, "[New %s]\n", target_pid_to_str (pid));
+         add_thread (pid);
+
+         /* We may want to consider not doing a resume here in order to give
+            the user a chance to play with the new thread.  It might be good
+            to make that a user-settable option.  */
+
+         /* At this point, all threads are stopped (happens automatically in
+            either the OS or the native code).  Therefore we need to continue
+            all threads in order to make progress.  */
+
+         target_resume (-1, 0, TARGET_SIGNAL_0);
+         continue;
+       }
 
       switch (w.kind)
        {
@@ -450,12 +542,18 @@ wait_for_inferior ()
 
        case TARGET_WAITKIND_EXITED:
          target_terminal_ours ();      /* Must do this before mourn anyway */
+         annotate_exited (w.value.integer);
          if (w.value.integer)
            printf_filtered ("\nProgram exited with code 0%o.\n", 
                             (unsigned int)w.value.integer);
          else
-           if (!batch_mode())
-             printf_filtered ("\nProgram exited normally.\n");
+           printf_filtered ("\nProgram exited normally.\n");
+
+         /* Record the exit code in the convenience variable $_exitcode, so
+            that the user can inspect this again later.  */
+         set_internalvar (lookup_internalvar ("_exitcode"),
+                          value_from_longest (builtin_type_int, 
+                                              (LONGEST) w.value.integer));
          gdb_flush (gdb_stdout);
          target_mourn_inferior ();
 #ifdef NO_SINGLE_STEP
@@ -468,10 +566,24 @@ wait_for_inferior ()
          stop_print_frame = 0;
          stop_signal = w.value.sig;
          target_terminal_ours ();      /* Must do this before mourn anyway */
+         annotate_signalled ();
+
+         /* 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 */
-         printf_filtered ("\nProgram terminated with signal %s, %s.\n",
-                          target_signal_to_name (stop_signal),
-                          target_signal_to_string (stop_signal));
+
+         printf_filtered ("\nProgram terminated with signal ");
+         annotate_signal_name ();
+         printf_filtered ("%s", target_signal_to_name (stop_signal));
+         annotate_signal_name_end ();
+         printf_filtered (", ");
+         annotate_signal_string ();
+         printf_filtered ("%s", target_signal_to_string (stop_signal));
+         annotate_signal_string_end ();
+         printf_filtered (".\n");
 
          printf_filtered ("The program no longer exists.\n");
          gdb_flush (gdb_stdout);
@@ -488,118 +600,105 @@ wait_for_inferior ()
 
       stop_signal = w.value.sig;
 
-      if (pid != inferior_pid)
-       {
-         int save_pid = inferior_pid;
+      stop_pc = read_pc_pid (pid);
 
-         inferior_pid = pid;   /* Setup for target memory/regs */
-         registers_changed ();
-         stop_pc = read_pc ();
-         inferior_pid = save_pid;
-         registers_changed ();
-       }
-      else
-       stop_pc = read_pc ();
+      /* See if a thread hit a thread-specific breakpoint that was meant for
+        another thread.  If so, then step that thread past the breakpoint,
+        and continue it.  */
 
       if (stop_signal == TARGET_SIGNAL_TRAP
+         && breakpoints_inserted
          && breakpoint_here_p (stop_pc - DECR_PC_AFTER_BREAK))
        {
+         random_signal = 0;
          if (!breakpoint_thread_match (stop_pc - DECR_PC_AFTER_BREAK, pid))
            {
              /* Saw a breakpoint, but it was hit by the wrong thread.  Just continue. */
-             if (breakpoints_inserted)
-               {
-                 if (pid != inferior_pid)
-                   {
-                     int save_pid = inferior_pid;
-
-                     inferior_pid = pid;
-                     registers_changed ();
-                     write_pc (stop_pc - DECR_PC_AFTER_BREAK);
-                     inferior_pid = save_pid;
-                     registers_changed ();
-                   }
-                 else
-                   write_pc (stop_pc - DECR_PC_AFTER_BREAK);
-
-                 remove_breakpoints ();
-                 target_resume (pid, 1, TARGET_SIGNAL_0); /* Single step */
-                 /* FIXME: What if a signal arrives instead of the single-step
-                    happening?  */
-                 target_wait (pid, &w);
-                 insert_breakpoints ();
-               }
+             write_pc_pid (stop_pc - DECR_PC_AFTER_BREAK, pid);
+
+             remove_breakpoints ();
+             target_resume (pid, 1, TARGET_SIGNAL_0); /* Single step */
+             /* FIXME: What if a signal arrives instead of the single-step
+                happening?  */
+
+             if (target_wait_hook)
+               target_wait_hook (pid, &w);
+             else
+               target_wait (pid, &w);
+             insert_breakpoints ();
+
+             /* We need to restart all the threads now.  */
              target_resume (-1, 0, TARGET_SIGNAL_0);
              continue;
            }
-         else
-           if (pid != inferior_pid)
-             goto switch_thread;
        }
+      else
+       random_signal = 1;
+
+      /* See if something interesting happened to the non-current thread.  If
+         so, then switch to that thread, and eventually give control back to
+        the user.  */
 
       if (pid != inferior_pid)
        {
          int printed = 0;
 
-         if (!in_thread_list (pid))
-           {
-             fprintf_unfiltered (gdb_stderr, "[New %s]\n", target_pid_to_str (pid));
-             add_thread (pid);
+         /* If it's a random signal for a non-current thread, notify user
+            if he's expressed an interest.  */
 
-             target_resume (-1, 0, TARGET_SIGNAL_0);
-             continue;
-           }
-         else
+         if (random_signal
+             && signal_print[stop_signal])
            {
-             if (signal_print[stop_signal])
-               {
-                 char *signame;
-
-                 printed = 1;
-                 target_terminal_ours_for_output ();
-                 printf_filtered ("\nProgram received signal %s, %s.\n",
-                                  target_signal_to_name (stop_signal),
-                                  target_signal_to_string (stop_signal));
-                 gdb_flush (gdb_stdout);
-               }
+             printed = 1;
+             target_terminal_ours_for_output ();
+             printf_filtered ("\nProgram received signal %s, %s.\n",
+                              target_signal_to_name (stop_signal),
+                              target_signal_to_string (stop_signal));
+             gdb_flush (gdb_stdout);
+           }
 
-             if (stop_signal == TARGET_SIGNAL_TRAP
-                 || signal_stop[stop_signal])
-               {
-switch_thread:
-                 inferior_pid = pid;
-                 printf_filtered ("[Switching to %s]\n", target_pid_to_str (pid));
-
-                 flush_cached_frames ();
-                 registers_changed ();
-                 trap_expected = 0;
-                 if (step_resume_breakpoint)
-                   {
-                     delete_breakpoint (step_resume_breakpoint);
-                     step_resume_breakpoint = NULL;
-                   }
-                 prev_pc = 0;
-                 prev_sp = 0;
-                 prev_func_name = NULL;
-                 step_range_start = 0;
-                 step_range_end = 0;
-                 step_frame_address = 0;
-                 handling_longjmp = 0;
-                 another_trap = 0;
-               }
-             else
-               {
-                 if (printed)
-                   target_terminal_inferior ();
+         /* If it's not SIGTRAP and not a signal we want to stop for, then
+            continue the thread. */
+
+         if (stop_signal != TARGET_SIGNAL_TRAP
+             && !signal_stop[stop_signal])
+           {
+             if (printed)
+               target_terminal_inferior ();
 
-                 /* Clear the signal if it should not be passed.  */
-                 if (signal_program[stop_signal] == 0)
-                   stop_signal = TARGET_SIGNAL_0;
+             /* Clear the signal if it should not be passed.  */
+             if (signal_program[stop_signal] == 0)
+               stop_signal = TARGET_SIGNAL_0;
 
-                 target_resume (pid, 0, stop_signal);
-                 continue;
-               }
+             target_resume (pid, 0, stop_signal);
+             continue;
            }
+
+         /* It's a SIGTRAP or a signal we're interested in.  Switch threads,
+            and fall into the rest of wait_for_inferior().  */
+
+         /* Save infrun state for the old thread.  */
+         save_infrun_state (inferior_pid, prev_pc,
+                            prev_func_start, prev_func_name,
+                            trap_expected, step_resume_breakpoint,
+                            through_sigtramp_breakpoint,
+                            step_range_start, step_range_end,
+                            step_frame_address, handling_longjmp,
+                            another_trap);
+
+         inferior_pid = pid;
+
+         /* Load infrun state for the new thread.  */
+         load_infrun_state (inferior_pid, &prev_pc,
+                            &prev_func_start, &prev_func_name,
+                            &trap_expected, &step_resume_breakpoint,
+                            &through_sigtramp_breakpoint,
+                            &step_range_start, &step_range_end,
+                            &step_frame_address, &handling_longjmp,
+                            &another_trap);
+         printf_filtered ("[Switching to %s]\n", target_pid_to_str (pid));
+
+         flush_cached_frames ();
        }
 
 #ifdef NO_SINGLE_STEP
@@ -607,8 +706,9 @@ switch_thread:
        single_step (0);        /* This actually cleans up the ss */
 #endif /* NO_SINGLE_STEP */
       
-/* If PC is pointing at a nullified instruction, then step beyond it so that
-   the user won't be confused when GDB appears to be ready to execute it. */
+      /* If PC is pointing at a nullified instruction, then step beyond
+        it so that the user won't be confused when GDB appears to be ready
+        to execute it. */
 
       if (INSTRUCTION_NULLIFIED)
        {
@@ -616,10 +716,60 @@ switch_thread:
          continue;
        }
 
-      set_current_frame ( create_new_frame (read_fp (), stop_pc));
+#ifdef HAVE_STEPPABLE_WATCHPOINT
+      /* It may not be necessary to disable the watchpoint to stop over
+        it.  For example, the PA can (with some kernel cooperation) 
+        single step over a watchpoint without disabling the watchpoint.  */
+      if (STOPPED_BY_WATCHPOINT (w))
+       {
+         resume (1, 0);
+         continue;
+       }
+#endif
+
+#ifdef HAVE_NONSTEPPABLE_WATCHPOINT
+      /* It is far more common to need to disable a watchpoint
+        to step the inferior over it.  FIXME.  What else might
+        a debug register or page protection watchpoint scheme need
+        here?  */
+      if (STOPPED_BY_WATCHPOINT (w))
+       {
+/* At this point, we are stopped at an instruction which has attempted to write
+   to a piece of memory under control of a watchpoint.  The instruction hasn't
+   actually executed yet.  If we were to evaluate the watchpoint expression
+   now, we would get the old value, and therefore no change would seem to have
+   occurred.
+
+   In order to make watchpoints work `right', we really need to complete the
+   memory write, and then evaluate the watchpoint expression.  The following
+   code does that by removing the watchpoint (actually, all watchpoints and
+   breakpoints), single-stepping the target, re-inserting watchpoints, and then
+   falling through to let normal single-step processing handle proceed.  Since
+   this includes evaluating watchpoints, things will come to a stop in the
+   correct manner.  */
+
+         write_pc (stop_pc - DECR_PC_AFTER_BREAK);
+
+         remove_breakpoints ();
+         target_resume (pid, 1, TARGET_SIGNAL_0); /* Single step */
+
+         if (target_wait_hook)
+           target_wait_hook (pid, &w);
+         else
+           target_wait (pid, &w);
+         insert_breakpoints ();
+         /* FIXME-maybe: is this cleaner than setting a flag?  Does it
+            handle things like signals arriving and other things happening
+            in combination correctly?  */
+         goto have_waited;
+       }
+#endif
+
+#ifdef HAVE_CONTINUABLE_WATCHPOINT
+      /* It may be possible to simply continue after a watchpoint.  */
+      STOPPED_BY_WATCHPOINT (w);
+#endif
 
-      stop_frame_address = FRAME_FP (get_current_frame ());
-      stop_sp = read_sp ();
       stop_func_start = 0;
       stop_func_name = 0;
       /* Don't care about return value; stop_func_start and stop_func_name
@@ -670,17 +820,17 @@ switch_thread:
             if just proceeded over a breakpoint.
 
             However, if we are trying to proceed over a breakpoint
-            and end up in sigtramp, then step_resume_breakpoint
+            and end up in sigtramp, then through_sigtramp_breakpoint
             will be set and we should check whether we've hit the
             step breakpoint.  */
          if (stop_signal == TARGET_SIGNAL_TRAP && trap_expected
-             && step_resume_breakpoint == NULL)
+             && through_sigtramp_breakpoint == NULL)
            bpstat_clear (&stop_bpstat);
          else
            {
              /* See if there is a breakpoint at the current PC.  */
              stop_bpstat = bpstat_stop_status
-               (&stop_pc, stop_frame_address,
+               (&stop_pc,
 #if DECR_PC_AFTER_BREAK
                 /* Notice the case of stepping through a jump
                    that lands just after a breakpoint.
@@ -704,7 +854,8 @@ switch_thread:
              = !(bpstat_explains_signal (stop_bpstat)
                  || trap_expected
 #ifndef CALL_DUMMY_BREAKPOINT_OFFSET
-                 || PC_IN_CALL_DUMMY (stop_pc, stop_sp, stop_frame_address)
+                 || PC_IN_CALL_DUMMY (stop_pc, read_sp (),
+                                      FRAME_FP (get_current_frame ()))
 #endif /* No CALL_DUMMY_BREAKPOINT_OFFSET.  */
                  || (step_range_end && step_resume_breakpoint == NULL));
          else
@@ -715,7 +866,8 @@ switch_thread:
                       news) give another signal besides SIGTRAP,
                       so check here as well as above.  */
 #ifndef CALL_DUMMY_BREAKPOINT_OFFSET
-                   || PC_IN_CALL_DUMMY (stop_pc, stop_sp, stop_frame_address)
+                   || PC_IN_CALL_DUMMY (stop_pc, read_sp (),
+                                        FRAME_FP (get_current_frame ()))
 #endif /* No CALL_DUMMY_BREAKPOINT_OFFSET.  */
                    );
              if (!random_signal)
@@ -737,12 +889,18 @@ switch_thread:
          
          if (signal_print[stop_signal])
            {
-             char *signame;
              printed = 1;
              target_terminal_ours_for_output ();
-             printf_filtered ("\nProgram received signal %s, %s.\n",
-                              target_signal_to_name (stop_signal),
-                              target_signal_to_string (stop_signal));
+             annotate_signal ();
+             printf_filtered ("\nProgram received signal ");
+             annotate_signal_name ();
+             printf_filtered ("%s", target_signal_to_name (stop_signal));
+             annotate_signal_name_end ();
+             printf_filtered (", ");
+             annotate_signal_string ();
+             printf_filtered ("%s", target_signal_to_string (stop_signal));
+             annotate_signal_string_end ();
+             printf_filtered (".\n");
              gdb_flush (gdb_stdout);
            }
          if (signal_stop[stop_signal])
@@ -793,7 +951,13 @@ switch_thread:
              {
                delete_breakpoint (step_resume_breakpoint);
                step_resume_breakpoint = NULL;
-               what.step_resume = 0;
+             }
+           /* Not sure whether we need to blow this away too, but probably
+              it is like the step-resume breakpoint.  */
+           if (through_sigtramp_breakpoint != NULL)
+             {
+               delete_breakpoint (through_sigtramp_breakpoint);
+               through_sigtramp_breakpoint = NULL;
              }
 
 #if 0
@@ -814,7 +978,7 @@ switch_thread:
 #if 0
            /* FIXME - Need to implement nested temporary breakpoints */
            if (step_over_calls
-               && (stop_frame_address
+               && (FRAME_FP (get_current_frame ())
                    INNER_THAN step_frame_address))
              {
                another_trap = 1;
@@ -838,32 +1002,84 @@ switch_thread:
 
          case BPSTAT_WHAT_STOP_NOISY:
            stop_print_frame = 1;
-           /* We are about to nuke the step_resume_breakpoint via the
-              cleanup chain, so no need to worry about it here.  */
+
+           /* We are about to nuke the step_resume_breakpoint and
+              through_sigtramp_breakpoint via the cleanup chain, so
+              no need to worry about it here.  */
+
            goto stop_stepping;
 
          case BPSTAT_WHAT_STOP_SILENT:
            stop_print_frame = 0;
-           /* We are about to nuke the step_resume_breakpoint via the
-              cleanup chain, so no need to worry about it here.  */
-           goto stop_stepping;
 
-         case BPSTAT_WHAT_LAST:
-           /* Not a real code, but listed here to shut up gcc -Wall.  */
+           /* We are about to nuke the step_resume_breakpoint and
+              through_sigtramp_breakpoint via the cleanup chain, so
+              no need to worry about it here.  */
 
-         case BPSTAT_WHAT_KEEP_CHECKING:
-           break;
-         }
+           goto stop_stepping;
 
-       if (what.step_resume)
-         {
+         case BPSTAT_WHAT_STEP_RESUME:
            delete_breakpoint (step_resume_breakpoint);
            step_resume_breakpoint = NULL;
+           break;
+
+         case BPSTAT_WHAT_THROUGH_SIGTRAMP:
+           if (through_sigtramp_breakpoint)
+             delete_breakpoint (through_sigtramp_breakpoint);
+           through_sigtramp_breakpoint = NULL;
 
            /* If were waiting for a trap, hitting the step_resume_break
               doesn't count as getting it.  */
            if (trap_expected)
              another_trap = 1;
+           break;
+
+#ifdef SOLIB_ADD
+         case BPSTAT_WHAT_CHECK_SHLIBS:
+           {
+             extern int auto_solib_add;
+
+             /* Check for any newly added shared libraries if we're
+                supposed to be adding them automatically.  */
+             if (auto_solib_add)
+               {
+                 /* Remove breakpoints, SOLIB_ADD might adjust breakpoint
+                    addresses via breakpoint_re_set.  */
+                 if (breakpoints_inserted)
+                   remove_breakpoints ();
+                 breakpoints_inserted = 0;
+
+                 /* Switch terminal for any messages produced by
+                    breakpoint_re_set.  */
+                 target_terminal_ours_for_output ();
+                 SOLIB_ADD (NULL, 0, NULL);
+                 target_terminal_inferior ();
+               }
+
+             /* If requested, stop when the dynamic linker notifies
+                gdb of events.  This allows the user to get control
+                and place breakpoints in initializer routines for
+                dynamically loaded objects (among other things).  */
+             if (stop_on_solib_events)
+               {
+                 stop_print_frame = 0;
+                 goto stop_stepping;
+               }
+             else
+               {
+                 /* We want to step over this breakpoint, then keep going.  */
+                 another_trap = 1;
+                 remove_breakpoints_on_following_step = 1;
+                 break;
+               }
+           }
+#endif
+
+         case BPSTAT_WHAT_LAST:
+           /* Not a real code, but listed here to shut up gcc -Wall.  */
+
+         case BPSTAT_WHAT_KEEP_CHECKING:
+           break;
          }
       }
 
@@ -883,7 +1099,7 @@ switch_thread:
         just stop silently, unless the user was doing an si/ni, in which
         case she'd better know what she's doing.  */
 
-      if (PC_IN_CALL_DUMMY (stop_pc, stop_sp, stop_frame_address)
+      if (PC_IN_CALL_DUMMY (stop_pc, read_sp (), FRAME_FP (get_current_frame ()))
          && !step_range_end)
        {
          stop_print_frame = 0;
@@ -899,10 +1115,8 @@ switch_thread:
        /* Having a step-resume breakpoint overrides anything
           else having to do with stepping commands until
           that breakpoint is reached.  */
-       /* I suspect this could/should be keep_going, because if the
-          check_sigtramp2 check succeeds, then it will put in another
-          step_resume_breakpoint, and we aren't (yet) prepared to nest
-          them.  */
+       /* I'm not sure whether this needs to be check_sigtramp2 or
+          whether it could/should be keep_going.  */
        goto check_sigtramp2;
 
       if (step_range_end == 0)
@@ -914,41 +1128,59 @@ switch_thread:
       /* If stepping through a line, keep going if still within it.  */
       if (stop_pc >= step_range_start
          && stop_pc < step_range_end
+#if 0
+/* I haven't a clue what might trigger this clause, and it seems wrong anyway,
+   so I've disabled it until someone complains.  -Stu 10/24/95 */
+
          /* The step range might include the start of the
             function, so if we are at the start of the
             step range and either the stack or frame pointers
             just changed, we've stepped outside */
          && !(stop_pc == step_range_start
-              && stop_frame_address
-              && (stop_sp INNER_THAN prev_sp
-                  || stop_frame_address != step_frame_address)))
+              && FRAME_FP (get_current_frame ())
+              && (read_sp () INNER_THAN step_sp
+                  || FRAME_FP (get_current_frame ()) != step_frame_address))
+#endif
+)
        {
          /* We might be doing a BPSTAT_WHAT_SINGLE and getting a signal.
             So definately need to check for sigtramp here.  */
          goto check_sigtramp2;
        }
 
-      /* We stepped out of the stepping range.  See if that was due
-        to a subroutine call that we should proceed to the end of.  */
+      /* We stepped out of the stepping range.  */
+
+      /* We can't update step_sp every time through the loop, because
+        reading the stack pointer would slow down stepping too much.
+        But we can update it every time we leave the step range.  */
+      update_step_sp = 1;
 
       /* Did we just take a signal?  */
       if (IN_SIGTRAMP (stop_pc, stop_func_name)
          && !IN_SIGTRAMP (prev_pc, prev_func_name))
        {
+         /* We've just taken a signal; go until we are back to
+            the point where we took it and one more.  */
+
          /* This code is needed at least in the following case:
             The user types "next" and then a signal arrives (before
             the "next" is done).  */
-         /* We've just taken a signal; go until we are back to
-            the point where we took it and one more.  */
+
+         /* Note that if we are stopped at a breakpoint, then we need
+            the step_resume breakpoint to override any breakpoints at
+            the same location, so that we will still step over the
+            breakpoint even though the signal happened.  */
+
          {
            struct symtab_and_line sr_sal;
 
            sr_sal.pc = prev_pc;
            sr_sal.symtab = NULL;
            sr_sal.line = 0;
+           /* We could probably be setting the frame to
+              step_frame_address; I don't think anyone thought to try it.  */
            step_resume_breakpoint =
-             set_momentary_breakpoint (sr_sal, get_current_frame (),
-                                       bp_step_resume);
+             set_momentary_breakpoint (sr_sal, NULL, bp_step_resume);
            if (breakpoints_inserted)
              insert_breakpoints ();
          }
@@ -965,12 +1197,28 @@ switch_thread:
          goto keep_going;
        }
 
+#if 0
+      /* I disabled this test because it was too complicated and slow.  The
+        SKIP_PROLOGUE was especially slow, because it caused unnecessary
+        prologue examination on various architectures.  The code in the #else
+        clause has been tested on the Sparc, Mips, PA, and Power
+        architectures, so it's pretty likely to be correct.  -Stu 10/24/95 */
+
+      /* See if we left the step range due to a subroutine call that
+        we should proceed to the end of.  */
+
       if (stop_func_start)
        {
+         struct symtab *s;
+
          /* Do this after the IN_SIGTRAMP check; it might give
             an error.  */
          prologue_pc = stop_func_start;
-         SKIP_PROLOGUE (prologue_pc);
+
+         /* Don't skip the prologue if this is assembly source */
+         s = find_pc_symtab (stop_pc);
+         if (s && s->language != language_asm)
+           SKIP_PROLOGUE (prologue_pc);
        }
 
       if ((/* Might be a non-recursive call.  If the symbols are missing
@@ -982,22 +1230,13 @@ switch_thread:
           /* Might be a recursive call if either we have a prologue
              or the call instruction itself saves the PC on the stack.  */
           || prologue_pc != stop_func_start
-          || stop_sp != prev_sp)
+          || read_sp () != step_sp)
          && (/* PC is completely out of bounds of any known objfiles.  Treat
                 like a subroutine call. */
              ! stop_func_start
 
              /* If we do a call, we will be at the start of a function...  */
              || stop_pc == stop_func_start
-#if 0
-             /* Should be taken care of by the stop_pc < prologue_pc check
-                below.  Also, on irix5 where this checks for stop_pc
-                equal to stop_func_start plus 12, it would seem to be
-                wrong for a function with a 4 byte prologue, and an 8 byte
-                call; a "return" could end up at stop_func_start+12.  */
-
-             || AT_FUNCTION_START (stop_pc, stop_func_name, stop_func_start)
-#endif
 
              /* ...except on the Alpha with -O (and also Irix 5 and
                 perhaps others), in which we might call the address
@@ -1007,17 +1246,38 @@ switch_thread:
 
              || stop_pc < prologue_pc
 
+             /* ...and if it is a leaf function, the prologue might
+                consist of gp loading only, so the call transfers to
+                the first instruction after the prologue.  */
+             || (stop_pc == prologue_pc
+
+                 /* Distinguish this from the case where we jump back
+                    to the first instruction after the prologue,
+                    within a function.  */
+                  && stop_func_start != prev_func_start)
+
              /* If we end up in certain places, it means we did a subroutine
                 call.  I'm not completely sure this is necessary now that we
                 have the above checks with stop_func_start (and now that
                 find_pc_partial_function is pickier).  */
-             || IN_SOLIB_TRAMPOLINE (stop_pc, stop_func_name)
+             || IN_SOLIB_CALL_TRAMPOLINE (stop_pc, stop_func_name)
 
              /* If none of the above apply, it is a jump within a function,
                 or a return from a subroutine.  The other case is longjmp,
                 which can no longer happen here as long as the
                 handling_longjmp stuff is working.  */
              ))
+#else
+       /* This test is a much more streamlined, (but hopefully correct)
+          replacement for the code above.  It's been tested on the Sparc,
+          Mips, PA, and Power architectures with good results.  */
+
+       if (stop_pc == stop_func_start /* Quick test */
+           || in_prologue (stop_pc, stop_func_start)
+           || IN_SOLIB_CALL_TRAMPOLINE (stop_pc, stop_func_name)
+           || stop_func_start == 0)
+#endif
+
        {
          /* It's a subroutine call.  */
 
@@ -1042,6 +1302,22 @@ switch_thread:
          tmp = SKIP_TRAMPOLINE_CODE (stop_pc);
          if (tmp != 0)
            stop_func_start = tmp;
+         else
+           {
+             tmp = DYNAMIC_TRAMPOLINE_NEXTPC (stop_pc);
+             if (tmp)
+               {
+                 struct symtab_and_line xxx;
+
+                 xxx.pc = tmp;
+                 xxx.symtab = NULL;
+                 xxx.line = 0;
+                 step_resume_breakpoint = 
+                   set_momentary_breakpoint (xxx, NULL, bp_step_resume);
+                 insert_breakpoints ();
+                 goto keep_going;
+               }
+           }
 
          /* If we have line number information for the function we
             are thinking of stepping into, step into it.
@@ -1070,6 +1346,7 @@ step_over_function:
            step_resume_breakpoint =
              set_momentary_breakpoint (sr_sal, get_current_frame (),
                                        bp_step_resume);
+           step_resume_breakpoint->frame = step_frame_address;
            if (breakpoints_inserted)
              insert_breakpoints ();
          }
@@ -1078,7 +1355,13 @@ step_over_function:
 step_into_function:
          /* Subroutine call with source code we should not step over.
             Do step to the first line of code in it.  */
-         SKIP_PROLOGUE (stop_func_start);
+         {
+           struct symtab *s;
+
+           s = find_pc_symtab (stop_pc);
+           if (s && s->language != language_asm)
+             SKIP_PROLOGUE (stop_func_start);
+         }
          sal = find_pc_line (stop_func_start, 0);
          /* Use the step_resume_break to step until
             the end of the prologue, even if that involves jumps
@@ -1134,6 +1417,38 @@ step_into_function:
          break;
        }
 
+      /* If we're in the return path from a shared library trampoline,
+        we want to proceed through the trampoline when stepping.  */
+      if (IN_SOLIB_RETURN_TRAMPOLINE(stop_pc, stop_func_name))
+       {
+         CORE_ADDR tmp;
+
+         /* Determine where this trampoline returns.  */
+         tmp = SKIP_TRAMPOLINE_CODE (stop_pc);
+
+         /* Only proceed through if we know where it's going.  */
+         if (tmp)
+           {
+             /* And put the step-breakpoint there and go until there. */
+             struct symtab_and_line sr_sal;
+
+             sr_sal.pc = tmp;
+             sr_sal.symtab = NULL;
+             sr_sal.line = 0;
+             /* 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.  */
+             step_resume_breakpoint =
+               set_momentary_breakpoint (sr_sal, NULL, bp_step_resume);
+             if (breakpoints_inserted)
+               insert_breakpoints ();
+
+             /* Restart without fiddling with the step ranges or
+                other state.  */
+             goto keep_going;
+           }
+       }
+        
       if (sal.line == 0)
        {
          /* We have no line number information.  That means to stop
@@ -1196,9 +1511,11 @@ step_into_function:
          sr_sal.pc = prev_pc;
          sr_sal.symtab = NULL;
          sr_sal.line = 0;
-         step_resume_breakpoint =
-           set_momentary_breakpoint (sr_sal, get_current_frame (),
-                                     bp_step_resume);
+         /* We perhaps could set the frame if we kept track of what
+            the frame corresponding to prev_pc was.  But we don't,
+            so don't.  */
+         through_sigtramp_breakpoint =
+           set_momentary_breakpoint (sr_sal, NULL, bp_through_sigtramp);
          if (breakpoints_inserted)
            insert_breakpoints ();
 
@@ -1219,7 +1536,10 @@ step_into_function:
                                          been at the start of a
                                          function. */
       prev_func_name = stop_func_name;
-      prev_sp = stop_sp;
+
+      if (update_step_sp)
+       step_sp = read_sp ();
+      update_step_sp = 0;
 
       /* If we did not do break;, it means we should keep
         running the inferior and not return to debugger.  */
@@ -1246,15 +1566,16 @@ step_into_function:
             to one-proceed past a breakpoint.  */
          /* If we've just finished a special step resume and we don't
             want to hit a breakpoint, pull em out.  */
-         if (step_resume_breakpoint == NULL &&
-             remove_breakpoints_on_following_step)
+         if (step_resume_breakpoint == NULL
+             && through_sigtramp_breakpoint == NULL
+             && remove_breakpoints_on_following_step)
            {
              remove_breakpoints_on_following_step = 0;
              remove_breakpoints ();
              breakpoints_inserted = 0;
            }
          else if (!breakpoints_inserted &&
-                  (step_resume_breakpoint != NULL || !another_trap))
+                  (through_sigtramp_breakpoint != NULL || !another_trap))
            {
              breakpoints_failed = insert_breakpoints ();
              if (breakpoints_failed)
@@ -1293,7 +1614,6 @@ step_into_function:
       prev_pc = read_pc ();
       prev_func_start = stop_func_start;
       prev_func_name = stop_func_name;
-      prev_sp = stop_sp;
     }
   do_cleanups (old_cleanups);
 }
@@ -1346,10 +1666,15 @@ Further execution is probably impossible.\n");
     disable_current_display ();
 
   if (step_multi && stop_step)
-    return;
+    goto done;
 
   target_terminal_ours ();
 
+  if (stop_bpstat
+      && stop_bpstat->breakpoint_at
+      && stop_bpstat->breakpoint_at->type == bp_shlib_event)
+    printf_filtered ("Stopped due to shared library event\n");
+
   /* Look up the hook_stop and run it if it exists.  */
 
   if (stop_command->hook)
@@ -1359,7 +1684,7 @@ Further execution is probably impossible.\n");
     }
 
   if (!target_has_stack)
-    return;
+    goto done;
 
   /* Select innermost stack frame except on return from a stack dummy routine,
      or if the program has exited.  Print it without a level number if
@@ -1376,7 +1701,7 @@ Further execution is probably impossible.\n");
          source_only = bpstat_print (stop_bpstat);
          source_only = source_only ||
                (   stop_step
-                && step_frame_address == stop_frame_address
+                && step_frame_address == FRAME_FP (get_current_frame ())
                 && step_start_function == find_pc_function (stop_pc));
 
           print_stack_frame (selected_frame, -1, source_only? -1: 1);
@@ -1397,8 +1722,14 @@ Further execution is probably impossible.\n");
          POP_FRAME ends with a setting of the current frame, so we
         can use that next. */
       POP_FRAME;
+      /* Set stop_pc to what it was before we called the function.  Can't rely
+        on restore_inferior_status because that only gets called if we don't
+        stop in the called function.  */
+      stop_pc = read_pc();
       select_frame (get_current_frame (), 0);
     }
+ done:
+  annotate_stopped ();
 }
 
 static int
@@ -1546,10 +1877,11 @@ handle_command (args, from_tty)
             anyway, and the common ones like SIGHUP, SIGINT, SIGALRM, etc.
             will work right anyway.  */
 
-         sigfirst = siglast = atoi (*argv);
+         sigfirst = siglast = (int) target_signal_from_command (atoi (*argv));
          if ((*argv)[digits] == '-')
            {
-             siglast = atoi ((*argv) + digits + 1);
+             siglast =
+               (int) target_signal_from_command (atoi ((*argv) + digits + 1));
            }
          if (sigfirst > siglast)
            {
@@ -1558,14 +1890,6 @@ handle_command (args, from_tty)
              sigfirst = siglast;
              siglast = signum;
            }
-         if (sigfirst < 0 || sigfirst >= nsigs)
-           {
-             error ("Signal %d not in range 0-%d", sigfirst, nsigs - 1);
-           }
-         if (siglast < 0 || siglast >= nsigs)
-           {
-             error ("Signal %d not in range 0-%d", siglast, nsigs - 1);
-           }
        }
       else
        {
@@ -1606,6 +1930,11 @@ Are you sure you want to change it? ",
                      }
                  }
                break;
+             case TARGET_SIGNAL_0:
+             case TARGET_SIGNAL_DEFAULT:
+             case TARGET_SIGNAL_UNKNOWN:
+               /* Make sure that "all" doesn't print these.  */
+               break;
              default:
                sigs[signum] = 1;
                break;
@@ -1652,27 +1981,19 @@ signals_info (signum_exp, from_tty)
       oursig = target_signal_from_name (signum_exp);
       if (oursig == TARGET_SIGNAL_UNKNOWN)
        {
-         /* Nope, maybe it's an address which evaluates to a signal
-            number.  */
-         /* The numeric signal refers to our own internal
-            signal numbering from target.h, not to host/target signal number.
-            This is a feature; users really should be using symbolic names
-            anyway, and the common ones like SIGHUP, SIGINT, SIGALRM, etc.
-            will work right anyway.  */
-         int i = parse_and_eval_address (signum_exp);
-         if (i >= (int)TARGET_SIGNAL_LAST
-             || i < 0
-             || i == (int)TARGET_SIGNAL_UNKNOWN
-             || i == (int)TARGET_SIGNAL_DEFAULT)
-           error ("Signal number out of bounds.");
-         oursig = (enum target_signal)i;
+         /* No, try numeric.  */
+         oursig =
+           target_signal_from_command (parse_and_eval_address (signum_exp));
        }
       sig_print_info (oursig);
       return;
     }
 
   printf_filtered ("\n");
-  for (oursig = 0; oursig < TARGET_SIGNAL_LAST; ++oursig)
+  /* These ugly casts brought to you by the native VAX compiler.  */
+  for (oursig = TARGET_SIGNAL_FIRST;
+       (int)oursig < (int)TARGET_SIGNAL_LAST;
+       oursig = (enum target_signal)((int)oursig + 1))
     {
       QUIT;
 
@@ -1696,7 +2017,6 @@ save_inferior_status (inf_status, restore_stack_info)
 {
   inf_status->stop_signal = stop_signal;
   inf_status->stop_pc = stop_pc;
-  inf_status->stop_frame_address = stop_frame_address;
   inf_status->stop_step = stop_step;
   inf_status->stop_stack_dummy = stop_stack_dummy;
   inf_status->stopped_by_random_signal = stopped_by_random_signal;
@@ -1726,7 +2046,7 @@ save_inferior_status (inf_status, restore_stack_info)
 }
 
 struct restore_selected_frame_args {
-  FRAME_ADDR frame_address;
+  CORE_ADDR frame_address;
   int level;
 };
 
@@ -1736,27 +2056,28 @@ static int restore_selected_frame PARAMS ((char *));
    restore_selected_frame_args * (declared as char * for catch_errors)
    telling us what frame to restore.  Returns 1 for success, or 0 for
    failure.  An error message will have been printed on error.  */
+
 static int
 restore_selected_frame (args)
      char *args;
 {
   struct restore_selected_frame_args *fr =
     (struct restore_selected_frame_args *) args;
-  FRAME fid;
+  struct frame_info *frame;
   int level = fr->level;
 
-  fid = find_relative_frame (get_current_frame (), &level);
+  frame = find_relative_frame (get_current_frame (), &level);
 
   /* If inf_status->selected_frame_address is NULL, there was no
      previously selected frame.  */
-  if (fid == 0 ||
-      FRAME_FP (fid) != fr->frame_address ||
+  if (frame == NULL ||
+      FRAME_FP (frame) != fr->frame_address ||
       level != 0)
     {
       warning ("Unable to restore previously selected frame.\n");
       return 0;
     }
-  select_frame (fid, fr->level);
+  select_frame (frame, fr->level);
   return(1);
 }
 
@@ -1766,7 +2087,6 @@ restore_inferior_status (inf_status)
 {
   stop_signal = inf_status->stop_signal;
   stop_pc = inf_status->stop_pc;
-  stop_frame_address = inf_status->stop_frame_address;
   stop_step = inf_status->stop_step;
   stop_stack_dummy = inf_status->stop_stack_dummy;
   stopped_by_random_signal = inf_status->stopped_by_random_signal;
@@ -1825,23 +2145,24 @@ _initialize_infrun ()
 
   add_info ("signals", signals_info,
            "What debugger does when program gets various signals.\n\
-Specify a signal number as argument to print info on that signal only.");
+Specify a signal as argument to print info on that signal only.");
   add_info_alias ("handle", "signals", 0);
 
   add_com ("handle", class_run, handle_command,
-          "Specify how to handle a signal.\n\
-Args are signal numbers and actions to apply to those signals.\n\
-Signal numbers may be numeric (ex. 11) or symbolic (ex. SIGSEGV).\n\
-Numeric ranges may be specified with the form LOW-HIGH (ex. 14-21).\n\
+          concat ("Specify how to handle a signal.\n\
+Args are signals and actions to apply to those signals.\n\
+Symbolic signals (e.g. SIGSEGV) are recommended but numeric signals\n\
+from 1-15 are allowed for compatibility with old versions of GDB.\n\
+Numeric ranges may be specified with the form LOW-HIGH (e.g. 1-5).\n\
 The special arg \"all\" is recognized to mean all signals except those\n\
-used by the debugger, typically SIGTRAP and SIGINT.\n\
-Recognized actions include \"stop\", \"nostop\", \"print\", \"noprint\",\n\
+used by the debugger, typically SIGTRAP and SIGINT.\n",
+"Recognized actions include \"stop\", \"nostop\", \"print\", \"noprint\",\n\
 \"pass\", \"nopass\", \"ignore\", or \"noignore\".\n\
 Stop means reenter debugger if this signal happens (implies print).\n\
 Print means print a message if this signal happens.\n\
 Pass means let program see this signal; otherwise program doesn't know.\n\
 Ignore is a synonym for nopass and noignore is a synonym for pass.\n\
-Pass and Stop may be combined.");
+Pass and Stop may be combined.", NULL));
 
   stop_command = add_cmd ("stop", class_obscure, not_just_help_class_command,
           "There is no `stop' command, but you can set a hook on `stop'.\n\
@@ -1878,6 +2199,20 @@ of the program stops.", &cmdlist);
   signal_print[TARGET_SIGNAL_CHLD] = 0;
   signal_stop[TARGET_SIGNAL_IO] = 0;
   signal_print[TARGET_SIGNAL_IO] = 0;
+  signal_stop[TARGET_SIGNAL_POLL] = 0;
+  signal_print[TARGET_SIGNAL_POLL] = 0;
   signal_stop[TARGET_SIGNAL_URG] = 0;
   signal_print[TARGET_SIGNAL_URG] = 0;
+
+#ifdef SOLIB_ADD
+  add_show_from_set
+    (add_set_cmd ("stop-on-solib-events", class_support, var_zinteger,
+                  (char *) &stop_on_solib_events,
+                 "Set stopping for shared library events.\n\
+If nonzero, gdb will give control to the user when the dynamic linker\n\
+notifies gdb of shared library events.  The most common event of interest\n\
+to the user would be loading/unloading of a new library.\n",
+                  &setlist),
+     &showlist);
+#endif
 }
This page took 0.038331 seconds and 4 git commands to generate.