* symtab.c (find_pc_symtab): some object file formats, notably mips,
[deliverable/binutils-gdb.git] / gdb / breakpoint.c
index f6b136fc9a5412f84880f468274f79a5a2662a77..95e26047b93fce1e646cd00333613993bd5f4808 100644 (file)
@@ -1,5 +1,5 @@
 /* Everything about breakpoints, for GDB.
-   Copyright (C) 1986, 1987, 1989, 1990 Free Software Foundation, Inc.
+   Copyright 1986, 1987, 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
 
 This file is part of GDB.
 
@@ -17,13 +17,12 @@ 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.  */
 
-#include <stdio.h>
-#include <ctype.h>
 #include "defs.h"
-#include "param.h"
+#include <ctype.h>
 #include "symtab.h"
 #include "frame.h"
 #include "breakpoint.h"
+#include "gdbtypes.h"
 #include "expression.h"
 #include "gdbcore.h"
 #include "gdbcmd.h"
@@ -34,88 +33,124 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "target.h"
 #include "language.h"
 #include <string.h>
+#include "demangle.h"
+
+/* local function prototypes */
+
+static void
+catch_command_1 PARAMS ((char *, int, int));
+
+static void
+enable_delete_command PARAMS ((char *, int));
+
+static void
+enable_delete_breakpoint PARAMS ((struct breakpoint *));
+
+static void
+enable_once_command PARAMS ((char *, int));
+
+static void
+enable_once_breakpoint PARAMS ((struct breakpoint *));
+
+static void
+disable_command PARAMS ((char *, int));
+
+static void
+disable_breakpoint PARAMS ((struct breakpoint *));
+
+static void
+enable_command PARAMS ((char *, int));
+
+static void
+enable_breakpoint PARAMS ((struct breakpoint *));
+
+static void
+map_breakpoint_numbers PARAMS ((char *,        void (*)(struct breakpoint *)));
+
+static void
+ignore_command PARAMS ((char *, int));
+
+static int
+breakpoint_re_set_one PARAMS ((char *));
+
+static void
+delete_command PARAMS ((char *, int));
+
+static void
+clear_command PARAMS ((char *, int));
+
+static void
+catch_command PARAMS ((char *, int));
+
+static struct symtabs_and_lines
+get_catch_sals PARAMS ((int));
+
+static void
+watch_command PARAMS ((char *, int));
+
+static void
+tbreak_command PARAMS ((char *, int));
+
+static void
+break_command_1 PARAMS ((char *, int, int));
+
+static void
+mention PARAMS ((struct breakpoint *));
+
+static struct breakpoint *
+set_raw_breakpoint PARAMS ((struct symtab_and_line));
+
+static void
+check_duplicates PARAMS ((CORE_ADDR));
+
+static void
+describe_other_breakpoints PARAMS ((CORE_ADDR));
+
+static void
+breakpoints_info PARAMS ((char *, int));
+
+static void
+breakpoint_1 PARAMS ((int, int));
+
+static bpstat
+bpstat_alloc PARAMS ((struct breakpoint *, bpstat));
+
+static int
+breakpoint_cond_eval PARAMS ((char *));
+
+static void
+cleanup_executing_breakpoints PARAMS ((int));
+
+static void
+commands_command PARAMS ((char *, int));
+
+static void
+condition_command PARAMS ((char *, int));
+
+static int
+get_number PARAMS ((char **));
+
+static void
+set_breakpoint_count PARAMS ((int));
+
 
 extern int addressprint;               /* Print machine addresses? */
 extern int demangle;                   /* Print de-mangled symbol names? */
 
-extern int catch_errors ();
-extern void set_next_address ();       /* ...for x/ command */
-
 /* Are we executing breakpoint commands?  */
 static int executing_breakpoint_commands;
 
-/* States of enablement of breakpoint.
-   `temporary' means disable when hit.
-   `delete' means delete when hit.  */
-
-enum enable { disabled, enabled, temporary, delete};
-
-/* Not that the ->silent field is not currently used by any commands
-   (though the code is in there if it was to be, and set_raw_breakpoint
-   does set it to 0).  I implemented it because I thought it would be
-   useful for a hack I had to put in; I'm going to leave it in because
-   I can see how there might be times when it would indeed be useful */
-
-/* This is for a breakpoint or a watchpoint.  */
-
-struct breakpoint
-{
-  struct breakpoint *next;
-  /* Number assigned to distinguish breakpoints.  */
-  int number;
-  /* Address to break at, or NULL if not a breakpoint.  */
-  CORE_ADDR address;
-  /* Line number of this address.  Redundant.  Only matters if address
-     is non-NULL.  */
-  int line_number;
-  /* Symtab of file of this address.  Redundant.  Only matters if address
-     is non-NULL.  */
-  struct symtab *symtab;
-  /* Zero means disabled; remember the info but don't break here.  */
-  enum enable enable;
-  /* Non-zero means a silent breakpoint (don't print frame info
-     if we stop here). */
-  unsigned char silent;
-  /* Number of stops at this breakpoint that should
-     be continued automatically before really stopping.  */
-  int ignore_count;
-  /* "Real" contents of byte where breakpoint has been inserted.
-     Valid only when breakpoints are in the program.  Under the complete
-     control of the target insert_breakpoint and remove_breakpoint routines.
-     No other code should assume anything about the value(s) here.  */
-  char shadow_contents[BREAKPOINT_MAX];
-  /* Nonzero if this breakpoint is now inserted.  Only matters if address
-     is non-NULL.  */
-  char inserted;
-  /* Nonzero if this is not the first breakpoint in the list
-     for the given address.  Only matters if address is non-NULL.  */
-  char duplicate;
-  /* Chain of command lines to execute when this breakpoint is hit.  */
-  struct command_line *commands;
-  /* Stack depth (address of frame).  If nonzero, break only if fp
-     equals this.  */
-  FRAME_ADDR frame;
-  /* Conditional.  Break only if this expression's value is nonzero.  */
-  struct expression *cond;
-
-  /* String we used to set the breakpoint (malloc'd).  Only matters if
-     address is non-NULL.  */
-  char *addr_string;
-  /* String form of the breakpoint condition (malloc'd), or NULL if there
-     is no condition.  */
-  char *cond_string;
-
-  /* The expression we are watching, or NULL if not a watchpoint.  */
-  struct expression *exp;
-  /* The largest block within which it is valid, or NULL if it is
-     valid anywhere (e.g. consists just of global symbols).  */
-  struct block *exp_valid_block;
-  /* Value of the watchpoint the last time we checked it.  */
-  value val;
-};
+/* Walk the following statement or block through all breakpoints.
+   ALL_BREAKPOINTS_SAFE does so even if the statment deletes the current
+   breakpoint.  */
 
 #define ALL_BREAKPOINTS(b)  for (b = breakpoint_chain; b; b = b->next)
 
+#define ALL_BREAKPOINTS_SAFE(b,tmp)    \
+       for (b = breakpoint_chain;      \
+            b? (tmp=b->next, 1): 0;    \
+            b = tmp)
+
 /* Chain of all breakpoints defined.  */
 
 struct breakpoint *breakpoint_chain;
@@ -146,9 +181,6 @@ CORE_ADDR default_breakpoint_address;
 struct symtab *default_breakpoint_symtab;
 int default_breakpoint_line;
 
-static void delete_breakpoint ();
-void breakpoint_auto_delete ();
-
 /* Flag indicating extra verbosity for xgdb.  */
 extern int xgdb_verbose;
 \f
@@ -190,6 +222,8 @@ get_number (pp)
     }
   else
     {
+      if (*p == '-')
+       ++p;
       while (*p >= '0' && *p <= '9')
        ++p;
       if (p == *pp)
@@ -227,18 +261,18 @@ condition_command (arg, from_tty)
       {
        if (b->cond)
          {
-           free (b->cond);
+           free ((PTR)b->cond);
            b->cond = 0;
          }
        if (b->cond_string != NULL)
-         free (b->cond_string);
+         free ((PTR)b->cond_string);
 
        if (*p == 0)
          {
            b->cond = 0;
            b->cond_string = NULL;
            if (from_tty)
-             printf ("Breakpoint %d now unconditional.\n", bnum);
+             printf_filtered ("Breakpoint %d now unconditional.\n", bnum);
          }
        else
          {
@@ -283,11 +317,8 @@ commands_command (arg, from_tty)
     if (b->number == bnum)
       {
        if (from_tty && input_from_terminal_p ())
-         {
-           printf ("Type commands for when breakpoint %d is hit, one per line.\n\
+         printf_filtered ("Type commands for when breakpoint %d is hit, one per line.\n\
 End with a line saying just \"end\".\n", bnum);
-           fflush (stdout);
-         }
        l = read_command_lines ();
        free_command_lines (&b->commands);
        b->commands = l;
@@ -299,7 +330,13 @@ End with a line saying just \"end\".\n", bnum);
 extern int memory_breakpoint_size; /* from mem-break.c */
 
 /* Like target_read_memory() but if breakpoints are inserted, return
-   the shadow contents instead of the breakpoints themselves.  */
+   the shadow contents instead of the breakpoints themselves.
+
+   Read "memory data" from whatever target or inferior we have. 
+   Returns zero if successful, errno value if not.  EIO is used
+   for address out of bounds.  If breakpoints are inserted, returns
+   shadow contents, not the breakpoints themselves.  From breakpoint.c.  */
+
 int
 read_memory_nobpt (memaddr, myaddr, len)
      CORE_ADDR memaddr;
@@ -315,7 +352,7 @@ read_memory_nobpt (memaddr, myaddr, len)
   
   ALL_BREAKPOINTS (b)
     {
-      if (b->address == NULL || !b->inserted)
+      if (b->type == bp_watchpoint || !b->inserted)
        continue;
       else if (b->address + memory_breakpoint_size <= memaddr)
        /* The breakpoint is entirely before the chunk of memory
@@ -351,8 +388,8 @@ read_memory_nobpt (memaddr, myaddr, len)
              bptlen -= (membpt + bptlen) - (memaddr + len);
            }
 
-         bcopy (b->shadow_contents + bptoffset,
-                myaddr + membpt - memaddr, bptlen);
+         memcpy (myaddr + membpt - memaddr, 
+                 b->shadow_contents + bptoffset, bptlen);
 
          if (membpt > memaddr)
            {
@@ -392,7 +429,7 @@ insert_breakpoints ()
   int disabled_breaks = 0;
 
   ALL_BREAKPOINTS (b)
-    if (b->address != NULL
+    if (b->type != bp_watchpoint
        && b->enable != disabled
        && ! b->inserted
        && ! b->duplicate)
@@ -408,8 +445,8 @@ insert_breakpoints ()
                b->enable = disabled;
                if (!disabled_breaks)
                  {
-                   fprintf (stderr,
-                        "Cannot insert breakpoint %d:\n", b->number);
+                   fprintf_filtered (stderr, "Cannot insert breakpoint %d:\n",
+                                     b->number);
                    printf_filtered ("Disabling shared library breakpoints:\n");
                  }
                disabled_breaks = 1;
@@ -418,10 +455,11 @@ insert_breakpoints ()
            else
 #endif
              {
-               fprintf (stderr, "Cannot insert breakpoint %d:\n", b->number);
+               fprintf_filtered (stderr, "Cannot insert breakpoint %d:\n",
+                                 b->number);
 #ifdef ONE_PROCESS_WRITETEXT
-               fprintf (stderr,
-                 "The same program may be running in another process.\n");
+               fprintf_filtered (stderr,
+                                 "The same program may be running in another process.\n");
 #endif
                memory_error (val, b->address); /* which bombs us out */
              }
@@ -441,23 +479,23 @@ remove_breakpoints ()
   int val;
 
 #ifdef BREAKPOINT_DEBUG
-  printf ("Removing breakpoints.\n");
+  printf_filtered ("Removing breakpoints.\n");
 #endif /* BREAKPOINT_DEBUG */
 
   ALL_BREAKPOINTS (b)
-    if (b->address != NULL && b->inserted)
+    if (b->type != bp_watchpoint && b->inserted)
       {
        val = target_remove_breakpoint(b->address, b->shadow_contents);
        if (val)
          return val;
        b->inserted = 0;
 #ifdef BREAKPOINT_DEBUG
-       printf ("Removed breakpoint at %s",
-               local_hex_string(b->address));
-       printf (", shadow %s",
-               local_hex_string(b->shadow_contents[0]));
-       printf (", %s.\n",
-               local_hex_string(b->shadow_contents[1]));
+       printf_filtered ("Removed breakpoint at %s",
+                        local_hex_string(b->address));
+       printf_filtered (", shadow %s",
+                        local_hex_string(b->shadow_contents[0]));
+       printf_filtered (", %s.\n",
+                        local_hex_string(b->shadow_contents[1]));
 #endif /* BREAKPOINT_DEBUG */
       }
 
@@ -495,6 +533,10 @@ breakpoint_here_p (pc)
 \f
 /* bpstat stuff.  External routines' interfaces are documented
    in breakpoint.h.  */
+
+/* Clear a bpstat so that it says we are not at any breakpoint.
+   Also free any storage that is part of a bpstat.  */
+
 void
 bpstat_clear (bsp)
      bpstat *bsp;
@@ -510,12 +552,15 @@ bpstat_clear (bsp)
       q = p->next;
       if (p->old_val != NULL)
        value_free (p->old_val);
-      free (p);
+      free ((PTR)p);
       p = q;
     }
   *bsp = NULL;
 }
 
+/* Return a copy of a bpstat.  Like "bs1 = bs2" but all storage that
+   is part of the bpstat is copied as well.  */
+
 bpstat
 bpstat_copy (bs)
      bpstat bs;
@@ -530,7 +575,7 @@ bpstat_copy (bs)
   for (; bs != NULL; bs = bs->next)
     {
       tmp = (bpstat) xmalloc (sizeof (*tmp));
-      bcopy (bs, tmp, sizeof (*tmp));
+      memcpy (tmp, bs, sizeof (*tmp));
       if (p == NULL)
        /* This is the first thing in the chain.  */
        retval = tmp;
@@ -542,6 +587,27 @@ bpstat_copy (bs)
   return retval;
 }
 
+/* Find the bpstat associated with this breakpoint */
+
+bpstat
+bpstat_find_breakpoint(bsp, breakpoint)
+     bpstat bsp;
+     struct breakpoint *breakpoint;
+{
+  if (bsp == NULL) return NULL;
+
+  for (;bsp != NULL; bsp = bsp->next) {
+    if (bsp->breakpoint_at == breakpoint) return bsp;
+  }
+  return NULL;
+}
+
+/* Return the breakpoint number of the first breakpoint we are stopped
+   at.  *BSP upon return is a bpstat which points to the remaining
+   breakpoints stopped at (but which is not guaranteed to be good for
+   anything but further calls to bpstat_num).
+   Return 0 if passed a bpstat which does not indicate any breakpoints.  */
+
 int
 bpstat_num (bsp)
      bpstat *bsp;
@@ -561,6 +627,8 @@ bpstat_num (bsp)
     }
 }
 
+/* Modify BS so that the actions will not be performed.  */
+
 void
 bpstat_clear_actions (bs)
      bpstat bs;
@@ -589,6 +657,7 @@ cleanup_executing_breakpoints (ignore)
    location.  Any of these commands could cause the process to proceed
    beyond this point, etc.  We look out for such changes by checking
    the global "breakpoint_proceeded" after each command.  */
+
 void
 bpstat_do_actions (bsp)
      bpstat *bsp;
@@ -618,19 +687,25 @@ top:
            goto top;
        }
     }
-  clear_momentary_breakpoints ();
 
   executing_breakpoint_commands = 0;
   discard_cleanups (old_chain);
 }
 
+/* Print a message indicating what happened.  Returns nonzero to
+   say that only the source line should be printed after this (zero
+   return means print the frame as well as the source line).  */
+
 int
 bpstat_print (bs)
      bpstat bs;
 {
   /* bs->breakpoint_at can be NULL if it was a momentary breakpoint
      which has since been deleted.  */
-  if (bs == NULL || bs->breakpoint_at == NULL)
+  if (bs == NULL
+      || bs->breakpoint_at == NULL
+      || (bs->breakpoint_at->type != bp_breakpoint
+         && bs->breakpoint_at->type != bp_watchpoint))
     return 0;
   
   /* If bpstat_stop_status says don't print, OK, we won't.  An example
@@ -643,7 +718,7 @@ bpstat_print (bs)
   if (!bs->print)
     return 0;
 
-  if (bs->breakpoint_at->address != NULL)
+  if (bs->breakpoint_at->type == bp_breakpoint)
     {
       /* I think the user probably only wants to see one breakpoint
         number, not all of them.  */
@@ -703,7 +778,7 @@ bpstat_alloc (b, cbs)
   bs->breakpoint_at = b;
   /* If the condition is false, etc., don't do the commands.  */
   bs->commands = NULL;
-  bs->momentary = b->number == -3;
+  bs->momentary = b->disposition == delete;
   bs->old_val = NULL;
   return bs;
 }
@@ -741,7 +816,7 @@ bpstat_stop_status (pc, frame_address)
   int real_breakpoint = 0;
 #endif
   /* Root of the chain of bpstat's */
-  struct bpstat__struct root_bs[1];
+  struct bpstat root_bs[1];
   /* Pointer to the last thing in the chain currently.  */
   bpstat bs = root_bs;
 
@@ -755,15 +830,18 @@ bpstat_stop_status (pc, frame_address)
 
       if (b->enable == disabled)
        continue;
-      if (b->address != NULL && b->address != bp_addr)
+
+      if (b->type != bp_watchpoint && b->address != bp_addr)
        continue;
 
+      /* Come here if it's a watchpoint, or if the break address matches */
+
       bs = bpstat_alloc (b, bs);       /* Alloc a bpstat to explain stop */
 
       this_bp_stop = 1;
       this_bp_print = 1;
 
-      if (b->exp != NULL)              /* Watchpoint */
+      if (b->type == bp_watchpoint)
        {
          int within_current_scope;
          if (b->exp_valid_block != NULL)
@@ -849,7 +927,7 @@ which its expression is valid.\n", b->number);
          else
            {
              /* We will stop here */
-             if (b->enable == temporary)
+             if (b->disposition == disable)
                b->enable = disabled;
              bs->commands = b->commands;
              if (b->silent)
@@ -896,12 +974,16 @@ which its expression is valid.\n", b->number);
   return bs;
 }
 
+/* Nonzero if we should step constantly (e.g. watchpoints on machines
+   without hardware support).  This isn't related to a specific bpstat,
+   just to things like whether watchpoints are set.  */
+
 int 
 bpstat_should_step ()
 {
   struct breakpoint *b;
   ALL_BREAKPOINTS (b)
-    if (b->enable != disabled && b->exp != NULL)
+    if (b->enable == enabled && b->type == bp_watchpoint)
       return 1;
   return 0;
 }
@@ -911,50 +993,57 @@ bpstat_should_step ()
    is nonzero, process only watchpoints.  */
 
 static void
-breakpoint_1 (bnum, watchpoints)
+breakpoint_1 (bnum, allflag)
      int bnum;
-     int watchpoints;
+     int allflag;
 {
   register struct breakpoint *b;
   register struct command_line *l;
   register struct symbol *sym;
   CORE_ADDR last_addr = (CORE_ADDR)-1;
-  int header_printed = 0;
+  int found_a_breakpoint = 0;
+  static char *bptypes[] = {"breakpoint", "until", "finish", "watchpoint",
+                             "longjmp", "longjmp resume"};
+  static char *bpdisps[] = {"del", "dis", "keep"};
+  static char bpenables[] = "ny";
+
+  if (!breakpoint_chain)
+    {
+      printf_filtered ("No breakpoints or watchpoints.\n");
+      return;
+    }
   
   ALL_BREAKPOINTS (b)
-    if (bnum == -1 || bnum == b->number)
+    if (bnum == -1
+       || bnum == b->number)
       {
-       if (b->address == NULL && !watchpoints)
-         {
-           if (bnum == -1)
-             continue;
-           error ("That is a watchpoint, not a breakpoint.");
-         }
-       if (b->address != NULL && watchpoints)
-         {
-           if (bnum == -1)
-             continue;
-           error ("That is a breakpoint, not a watchpoint.");
-         }
-
-       if (!header_printed)
+/*  We only print out user settable breakpoints unless the allflag is set. */
+       if (!allflag
+           && b->type != bp_breakpoint
+           && b->type != bp_watchpoint)
+         continue;
+
+       if (!found_a_breakpoint++)
+         printf_filtered ("Num Type           Disp Enb %sWhat\n",
+                          addressprint ? "Address    " : "");
+
+       printf_filtered ("%-3d %-14s %-4s %-3c ",
+                        b->number,
+                        bptypes[(int)b->type],
+                        bpdisps[(int)b->disposition],
+                        bpenables[(int)b->enable]);
+       switch (b->type)
          {
-           if (watchpoints)
-             printf_filtered ("    Enb   Expression\n");
-           else if (addressprint)
-             printf_filtered ("    Enb   Address    Where\n");
-           else
-             printf_filtered ("    Enb   Where\n");
-           header_printed = 1;
-         }
-
-       printf_filtered ("#%-3d %c ", b->number, "nyod"[(int) b->enable]);
-       if (b->address == NULL) {
-         printf_filtered (" ");
-         print_expression (b->exp, stdout);
-       } else {
+         case bp_watchpoint:
+           print_expression (b->exp, stdout);
+           break;
+         case bp_breakpoint:
+         case bp_until:
+         case bp_finish:
+         case bp_longjmp:
+         case bp_longjmp_resume:
            if (addressprint)
-             printf_filtered (" %s ", local_hex_string_custom(b->address, "08"));
+             printf_filtered ("%s ", local_hex_string_custom(b->address, "08"));
 
            last_addr = b->address;
            if (b->symtab)
@@ -962,8 +1051,9 @@ breakpoint_1 (bnum, watchpoints)
                sym = find_pc_function (b->address);
                if (sym)
                  {
-                   fputs_filtered (" in ", stdout);
-                   fputs_demangled (SYMBOL_NAME (sym), stdout, 1);
+                   fputs_filtered ("in ", stdout);
+                   fputs_demangled (SYMBOL_NAME (sym), stdout, 
+                                    DMGL_ANSI | DMGL_PARAMS);
                    fputs_filtered (" at ", stdout);
                  }
                fputs_filtered (b->symtab->filename, stdout);
@@ -996,19 +1086,14 @@ breakpoint_1 (bnum, watchpoints)
            }
       }
 
-  if (!header_printed)
-    {
-      char *which = watchpoints ? "watch" : "break";
-      if (bnum == -1)
-       printf_filtered ("No %spoints.\n", which);
-      else
-       printf_filtered ("No %spoint numbered %d.\n", which, bnum);
-    }
-
-  /* Compare against (CORE_ADDR)-1 in case some compiler decides
-     that a comparison of an unsigned with -1 is always false.  */
-  if (last_addr != (CORE_ADDR)-1)
-    set_next_address (last_addr);
+  if (!found_a_breakpoint
+      && bnum != -1)
+    printf_filtered ("No breakpoint or watchpoint number %d.\n", bnum);
+  else
+    /* Compare against (CORE_ADDR)-1 in case some compiler decides
+       that a comparison of an unsigned with -1 is always false.  */
+    if (last_addr != (CORE_ADDR)-1)
+      set_next_address (last_addr);
 }
 
 /* ARGSUSED */
@@ -1025,9 +1110,11 @@ breakpoints_info (bnum_exp, from_tty)
   breakpoint_1 (bnum, 0);
 }
 
+#if MAINTENANCE_CMDS
+
 /* ARGSUSED */
 static void
-watchpoints_info (bnum_exp, from_tty)
+maintenance_info_breakpoints (bnum_exp, from_tty)
      char *bnum_exp;
      int from_tty;
 {
@@ -1039,6 +1126,8 @@ watchpoints_info (bnum_exp, from_tty)
   breakpoint_1 (bnum, 1);
 }
 
+#endif
+
 /* Print a message describing any breakpoints set at PC.  */
 
 static void
@@ -1053,17 +1142,18 @@ describe_other_breakpoints (pc)
       others++;
   if (others > 0)
     {
-      printf ("Note: breakpoint%s ", (others > 1) ? "s" : "");
+      printf_filtered ("Note: breakpoint%s ", (others > 1) ? "s" : "");
       ALL_BREAKPOINTS (b)
        if (b->address == pc)
          {
            others--;
-           printf ("%d%s%s ",
-                   b->number,
-                   (b->enable == disabled) ? " (disabled)" : "",
-                   (others > 1) ? "," : ((others == 1) ? " and" : ""));
+           printf_filtered ("%d%s%s ",
+                            b->number,
+                            (b->enable == disabled) ? " (disabled)" : "",
+                            (others > 1) ? "," :
+                              ((others == 1) ? " and" : ""));
          }
-      printf ("also set at pc %s.\n", local_hex_string(pc));
+      printf_filtered ("also set at pc %s.\n", local_hex_string(pc));
     }
 }
 \f
@@ -1094,7 +1184,7 @@ check_duplicates (address)
   register struct breakpoint *b;
   register int count = 0;
 
-  if (address == NULL)         /* Watchpoints are uninteresting */
+  if (address == 0)            /* Watchpoints are uninteresting */
     return;
 
   ALL_BREAKPOINTS (b)
@@ -1122,7 +1212,7 @@ set_raw_breakpoint (sal)
   register struct breakpoint *b, *b1;
 
   b = (struct breakpoint *) xmalloc (sizeof (struct breakpoint));
-  bzero (b, sizeof *b);
+  memset (b, 0, sizeof (*b));
   b->address = sal.pc;
   b->symtab = sal.symtab;
   b->line_number = sal.line;
@@ -1131,7 +1221,7 @@ set_raw_breakpoint (sal)
   b->silent = 0;
   b->ignore_count = 0;
   b->commands = NULL;
-  b->frame = NULL;
+  b->frame = 0;
 
   /* Add this breakpoint to the end of the chain
      so that a list of breakpoints will come out in order
@@ -1152,51 +1242,157 @@ set_raw_breakpoint (sal)
   return b;
 }
 
+static void
+create_longjmp_breakpoint(func_name)
+     char *func_name;
+{
+  struct symtab_and_line sal;
+  struct breakpoint *b;
+  static int internal_breakpoint_number = -1;
+
+  if (func_name != NULL)
+    {
+      struct minimal_symbol *m;
+
+      m = lookup_minimal_symbol(func_name, (struct objfile *)NULL);
+      if (m)
+       sal.pc = m->address;
+      else
+       return;
+    }
+  else
+    sal.pc = 0;
+
+  sal.symtab = NULL;
+  sal.line = 0;
+
+  b = set_raw_breakpoint(sal);
+  if (!b) return;
+
+  b->type = func_name != NULL ? bp_longjmp : bp_longjmp_resume;
+  b->disposition = donttouch;
+  b->enable = disabled;
+  b->silent = 1;
+  if (func_name)
+    b->addr_string = strsave(func_name);
+  b->number = internal_breakpoint_number--;
+}
+
+/* Call this routine when stepping and nexting to enable a breakpoint if we do
+   a longjmp().  When we hit that breakpoint, call
+   set_longjmp_resume_breakpoint() to figure out where we are going. */
+
+void
+enable_longjmp_breakpoint()
+{
+  register struct breakpoint *b;
+
+  ALL_BREAKPOINTS (b)
+    if (b->type == bp_longjmp)
+      {
+       b->enable = enabled;
+       check_duplicates (b->address);
+      }
+}
+
+void
+disable_longjmp_breakpoint()
+{
+  register struct breakpoint *b;
+
+  ALL_BREAKPOINTS (b)
+    if (   b->type == bp_longjmp
+       || b->type == bp_longjmp_resume)
+      {
+       b->enable = disabled;
+       check_duplicates (b->address);
+      }
+}
+
+/* Call this after hitting the longjmp() breakpoint.  Use this to set a new
+   breakpoint at the target of the jmp_buf.
+
+   FIXME - This ought to be done by setting a temporary breakpoint that gets
+   deleted automatically...
+*/
+
+void
+set_longjmp_resume_breakpoint(pc, frame)
+     CORE_ADDR pc;
+     FRAME frame;
+{
+  register struct breakpoint *b;
+
+  ALL_BREAKPOINTS (b)
+    if (b->type == bp_longjmp_resume)
+      {
+       b->address = pc;
+       b->enable = enabled;
+       if (frame != NULL)
+         b->frame = FRAME_FP(frame);
+       else
+         b->frame = 0;
+       check_duplicates (b->address);
+       return;
+      }
+}
+
 /* Set a breakpoint that will evaporate an end of command
    at address specified by SAL.
    Restrict it to frame FRAME if FRAME is nonzero.  */
 
-void
-set_momentary_breakpoint (sal, frame)
+struct breakpoint *
+set_momentary_breakpoint (sal, frame, type)
      struct symtab_and_line sal;
      FRAME frame;
+     enum bptype type;
 {
   register struct breakpoint *b;
   b = set_raw_breakpoint (sal);
-  b->number = -3;
-  b->enable = delete;
+  b->type = type;
+  b->enable = enabled;
+  b->disposition = donttouch;
   b->frame = (frame ? FRAME_FP (frame) : 0);
+  return b;
 }
 
+#if 0
 void
 clear_momentary_breakpoints ()
 {
   register struct breakpoint *b;
   ALL_BREAKPOINTS (b)
-    if (b->number == -3)
+    if (b->disposition == delete)
       {
        delete_breakpoint (b);
        break;
       }
 }
+#endif
 \f
 /* Tell the user we have just set a breakpoint B.  */
 static void
 mention (b)
      struct breakpoint *b;
 {
-  if (b->exp)
+  switch (b->type)
     {
+    case bp_watchpoint:
       printf_filtered ("Watchpoint %d: ", b->number);
       print_expression (b->exp, stdout);
-    }
-  else
-    {
+      break;
+    case bp_breakpoint:
       printf_filtered ("Breakpoint %d at %s", b->number,
                       local_hex_string(b->address));
       if (b->symtab)
        printf_filtered (": file %s, line %d.",
                         b->symtab->filename, b->line_number);
+      break;
+    case bp_until:
+    case bp_finish:
+    case bp_longjmp:
+    case bp_longjmp_resume:
+      break;
     }
   printf_filtered ("\n");
 }
@@ -1222,25 +1418,22 @@ set_breakpoint (s, line, tempflag, addr_string)
   
   sal.symtab = s;
   sal.line = line;
-  sal.pc = find_line_pc (sal.symtab, sal.line);
-  if (sal.pc == 0)
-    error ("No line %d in file \"%s\".\n", sal.line, sal.symtab->filename);
-  else
-    {
-      describe_other_breakpoints (sal.pc);
+  sal.pc = 0;
+  resolve_sal_pc (&sal);                       /* Might error out */
+  describe_other_breakpoints (sal.pc);
 
-      b = set_raw_breakpoint (sal);
-      set_breakpoint_count (breakpoint_count + 1);
-      b->number = breakpoint_count;
-      b->cond = 0;
-      b->addr_string = addr_string;
-      if (tempflag)
-       b->enable = temporary;
+  b = set_raw_breakpoint (sal);
+  set_breakpoint_count (breakpoint_count + 1);
+  b->number = breakpoint_count;
+  b->type = bp_breakpoint;
+  b->cond = 0;
+  b->addr_string = addr_string;
+  b->enable = enabled;
+  b->disposition = tempflag ? delete : donttouch;
 
-      mention (b);
-    }
+  mention (b);
 }
-#endif
+#endif /* 0 */
 \f
 /* Set a breakpoint according to ARG (function, linenum or *address)
    and make it temporary if TEMPFLAG is nonzero. */
@@ -1264,7 +1457,6 @@ break_command_1 (arg, tempflag, from_tty)
   char *addr_end;
   
   int i;
-  CORE_ADDR pc;
 
   sals.sals = NULL;
   sals.nelts = 0;
@@ -1312,18 +1504,11 @@ break_command_1 (arg, tempflag, from_tty)
   if (! sals.nelts) 
     return;
 
+  /* Resolve all line numbers to PC's, and verify that conditions
+     can be parsed, before setting any breakpoints.  */
   for (i = 0; i < sals.nelts; i++)
     {
-      sal = sals.sals[i];
-      if (sal.pc == 0 && sal.symtab != 0)
-       {
-         pc = find_line_pc (sal.symtab, sal.line);
-         if (pc == 0)
-           error ("No line %d in file \"%s\".",
-                  sal.line, sal.symtab->filename);
-       }
-      else 
-       pc = sal.pc;
+      resolve_sal_pc (&sals.sals[i]);
       
       while (arg && *arg)
        {
@@ -1332,15 +1517,15 @@ break_command_1 (arg, tempflag, from_tty)
            {
              arg += 2;
              cond_start = arg;
-             cond = parse_exp_1 (&arg, block_for_pc (pc), 0);
+             cond = parse_exp_1 (&arg, block_for_pc (sals.sals[i].pc), 0);
              cond_end = arg;
            }
          else
            error ("Junk at end of arguments.");
        }
-      sals.sals[i].pc = pc;
     }
 
+  /* Now set all the breakpoints.  */
   for (i = 0; i < sals.nelts; i++)
     {
       sal = sals.sals[i];
@@ -1351,6 +1536,7 @@ break_command_1 (arg, tempflag, from_tty)
       b = set_raw_breakpoint (sal);
       set_breakpoint_count (breakpoint_count + 1);
       b->number = breakpoint_count;
+      b->type = bp_breakpoint;
       b->cond = cond;
       
       if (addr_start)
@@ -1358,18 +1544,36 @@ break_command_1 (arg, tempflag, from_tty)
       if (cond_start)
        b->cond_string = savestring (cond_start, cond_end - cond_start);
                                     
-      if (tempflag)
-       b->enable = temporary;
+      b->enable = enabled;
+      b->disposition = tempflag ? delete : donttouch;
 
       mention (b);
     }
 
   if (sals.nelts > 1)
     {
-      printf ("Multiple breakpoints were set.\n");
-      printf ("Use the \"delete\" command to delete unwanted breakpoints.\n");
+      printf_filtered ("Multiple breakpoints were set.\n");
+      printf_filtered ("Use the \"delete\" command to delete unwanted breakpoints.\n");
+    }
+  free ((PTR)sals.sals);
+}
+
+/* Helper function for break_command_1 and disassemble_command.  */
+
+void
+resolve_sal_pc (sal)
+     struct symtab_and_line *sal;
+{
+  CORE_ADDR pc;
+
+  if (sal->pc == 0 && sal->symtab != 0)
+    {
+      pc = find_line_pc (sal->symtab, sal->line);
+      if (pc == 0)
+       error ("No line %d in file \"%s\".",
+              sal->line, sal->symtab->filename);
+      sal->pc = pc;
     }
-  free (sals.sals);
 }
 
 void
@@ -1400,7 +1604,7 @@ watch_command (arg, from_tty)
   struct block *exp_valid_block;
   struct value *val;
 
-  sal.pc = NULL;
+  sal.pc = 0;
   sal.symtab = NULL;
   sal.line = 0;
   
@@ -1415,6 +1619,8 @@ watch_command (arg, from_tty)
   b = set_raw_breakpoint (sal);
   set_breakpoint_count (breakpoint_count + 1);
   b->number = breakpoint_count;
+  b->type = bp_watchpoint;
+  b->disposition = donttouch;
   b->exp = exp;
   b->exp_valid_block = exp_valid_block;
   b->val = val;
@@ -1436,6 +1642,8 @@ until_break_command (arg, from_tty)
   struct symtabs_and_lines sals;
   struct symtab_and_line sal;
   FRAME prev_frame = get_prev_frame (selected_frame);
+  struct breakpoint *breakpoint;
+  struct cleanup *old_chain;
 
   clear_proceed_status ();
 
@@ -1452,19 +1660,17 @@ until_break_command (arg, from_tty)
     error ("Couldn't get information on specified line.");
   
   sal = sals.sals[0];
-  free (sals.sals);            /* malloc'd, so freed */
+  free ((PTR)sals.sals);               /* malloc'd, so freed */
   
   if (*arg)
     error ("Junk at end of arguments.");
   
-  if (sal.pc == 0 && sal.symtab != 0)
-    sal.pc = find_line_pc (sal.symtab, sal.line);
-  
-  if (sal.pc == 0)
-    error ("No line %d in file \"%s\".", sal.line, sal.symtab->filename);
+  resolve_sal_pc (&sal);
   
-  set_momentary_breakpoint (sal, selected_frame);
+  breakpoint = set_momentary_breakpoint (sal, selected_frame, bp_until);
   
+  old_chain = make_cleanup(delete_breakpoint, breakpoint);
+
   /* Keep within the current frame */
   
   if (prev_frame)
@@ -1474,10 +1680,12 @@ until_break_command (arg, from_tty)
       fi = get_frame_info (prev_frame);
       sal = find_pc_line (fi->pc, 0);
       sal.pc = fi->pc;
-      set_momentary_breakpoint (sal, prev_frame);
+      breakpoint = set_momentary_breakpoint (sal, prev_frame, bp_until);
+      make_cleanup(delete_breakpoint, breakpoint);
     }
   
   proceed (-1, -1, 0);
+  do_cleanups(old_chain);
 }
 \f
 #if 0
@@ -1563,7 +1771,7 @@ map_catch_names (args, function)
          goto win;
        }
 #endif
-      printf ("No catch clause for exception %s.\n", p);
+      printf_filtered ("No catch clause for exception %s.\n", p);
 #if 0
     win:
 #endif
@@ -1579,7 +1787,6 @@ static struct symtabs_and_lines
 get_catch_sals (this_level_only)
      int this_level_only;
 {
-  extern struct blockvector *blockvector_for_pc ();
   register struct blockvector *bl;
   register struct block *block;
   int index, have_default = 0;
@@ -1605,7 +1812,7 @@ get_catch_sals (this_level_only)
 
   bl = blockvector_for_pc (BLOCK_END (block) - 4, &index);
   blocks_searched = (char *) alloca (BLOCKVECTOR_NBLOCKS (bl) * sizeof (char));
-  bzero (blocks_searched, BLOCKVECTOR_NBLOCKS (bl) * sizeof (char));
+  memset (blocks_searched, 0, BLOCKVECTOR_NBLOCKS (bl) * sizeof (char));
 
   while (block != 0)
     {
@@ -1692,7 +1899,7 @@ get_catch_sals (this_level_only)
 
 /* Commands to deal with catching exceptions.  */
 
-void
+static void
 catch_command_1 (arg, tempflag, from_tty)
      char *arg;
      int tempflag;
@@ -1707,7 +1914,6 @@ catch_command_1 (arg, tempflag, from_tty)
   register struct breakpoint *b;
   char *save_arg;
   int i;
-  CORE_ADDR pc;
 
   sal.line = sal.pc = sal.end = 0;
   sal.symtab = 0;
@@ -1737,28 +1943,18 @@ catch_command_1 (arg, tempflag, from_tty)
   save_arg = arg;
   for (i = 0; i < sals.nelts; i++)
     {
-      sal = sals.sals[i];
-      if (sal.pc == 0 && sal.symtab != 0)
-       {
-         pc = find_line_pc (sal.symtab, sal.line);
-         if (pc == 0)
-           error ("No line %d in file \"%s\".",
-                  sal.line, sal.symtab->filename);
-       }
-      else 
-       pc = sal.pc;
+      resolve_sal_pc (&sals.sals[i]);
       
       while (arg && *arg)
        {
          if (arg[0] == 'i' && arg[1] == 'f'
              && (arg[2] == ' ' || arg[2] == '\t'))
-           cond = (struct expression *) parse_exp_1 ((arg += 2, &arg),
-                                                   block_for_pc (pc), 0);
+           cond = parse_exp_1 ((arg += 2, &arg), 
+                               block_for_pc (sals.sals[i].pc), 0);
          else
            error ("Junk at end of arguments.");
        }
       arg = save_arg;
-      sals.sals[i].pc = pc;
     }
 
   for (i = 0; i < sals.nelts; i++)
@@ -1769,23 +1965,27 @@ catch_command_1 (arg, tempflag, from_tty)
        describe_other_breakpoints (sal.pc);
 
       b = set_raw_breakpoint (sal);
-      b->number = ++breakpoint_count;
+      set_breakpoint_count (breakpoint_count + 1);
+      b->number = breakpoint_count;
+      b->type = bp_breakpoint;
       b->cond = cond;
-      if (tempflag)
-       b->enable = temporary;
+      b->enable = enabled;
+      b->disposition = tempflag ? delete : donttouch;
 
-      printf ("Breakpoint %d at %s", b->number, local_hex_string(b->address));
+      printf_filtered ("Breakpoint %d at %s", b->number,
+                      local_hex_string(b->address));
       if (b->symtab)
-       printf (": file %s, line %d.", b->symtab->filename, b->line_number);
-      printf ("\n");
+       printf_filtered (": file %s, line %d.",
+                        b->symtab->filename, b->line_number);
+      printf_filtered ("\n");
     }
 
   if (sals.nelts > 1)
     {
-      printf ("Multiple breakpoints were set.\n");
-      printf ("Use the \"delete\" command to delete unwanted breakpoints.\n");
+      printf_filtered ("Multiple breakpoints were set.\n");
+      printf_filtered ("Use the \"delete\" command to delete unwanted breakpoints.\n");
     }
-  free (sals.sals);
+  free ((PTR)sals.sals);
 }
 
 #if 0
@@ -1870,7 +2070,7 @@ clear_command (arg, from_tty)
 
       ALL_BREAKPOINTS (b)
        while (b->next
-              && b->next->address != NULL
+              && b->next->type != bp_watchpoint
               && (sal.pc ? b->next->address == sal.pc
                   : (b->next->symtab == sal.symtab
                      && b->next->line_number == sal.line)))
@@ -1890,17 +2090,18 @@ clear_command (arg, from_tty)
        }
 
       if (found->next) from_tty = 1; /* Always report if deleted more than one */
-      if (from_tty) printf ("Deleted breakpoint%s ", found->next ? "s" : "");
+      if (from_tty) printf_filtered ("Deleted breakpoint%s ",
+                                    found->next ? "s" : "");
       while (found)
        {
-         if (from_tty) printf ("%d ", found->number);
+         if (from_tty) printf_filtered ("%d ", found->number);
          b1 = found->next;
          delete_breakpoint (found);
          found = b1;
        }
       if (from_tty) putchar ('\n');
     }
-  free (sals.sals);
+  free ((PTR)sals.sals);
 }
 \f
 /* Delete breakpoint in BS if they are `delete' breakpoints.
@@ -1911,13 +2112,13 @@ breakpoint_auto_delete (bs)
      bpstat bs;
 {
   for (; bs; bs = bs->next)
-    if (bs->breakpoint_at && bs->breakpoint_at->enable == delete)
+    if (bs->breakpoint_at && bs->breakpoint_at->disposition == delete)
       delete_breakpoint (bs->breakpoint_at);
 }
 
 /* Delete a breakpoint and clean up all traces of it in the data structures. */
 
-static void
+void
 delete_breakpoint (bpt)
      struct breakpoint *bpt;
 {
@@ -1941,25 +2142,23 @@ delete_breakpoint (bpt)
 
   free_command_lines (&bpt->commands);
   if (bpt->cond)
-    free (bpt->cond);
+    free ((PTR)bpt->cond);
   if (bpt->cond_string != NULL)
-    free (bpt->cond_string);
+    free ((PTR)bpt->cond_string);
   if (bpt->addr_string != NULL)
-    free (bpt->addr_string);
+    free ((PTR)bpt->addr_string);
 
-  if (xgdb_verbose && bpt->number >=0)
-    printf ("breakpoint #%d deleted\n", bpt->number);
+  if (xgdb_verbose && bpt->type == bp_breakpoint)
+    printf_filtered ("breakpoint #%d deleted\n", bpt->number);
 
   /* Be sure no bpstat's are pointing at it after it's been freed.  */
   /* FIXME, how can we find all bpstat's?  We just check stop_bpstat for now. */
   for (bs = stop_bpstat; bs; bs = bs->next)
     if (bs->breakpoint_at == bpt)
       bs->breakpoint_at = NULL;
-  free (bpt);
+  free ((PTR)bpt);
 }
 
-static void map_breakpoint_numbers ();
-
 static void
 delete_command (arg, from_tty)
      char *arg;
@@ -1992,45 +2191,64 @@ breakpoint_re_set_one (bint)
   struct breakpoint *b = (struct breakpoint *)bint;  /* get past catch_errs */
   int i;
   struct symtabs_and_lines sals;
-  struct symtab_and_line sal;
   char *s;
+  enum enable save_enable;
 
-  if (b->address != NULL && b->addr_string != NULL)
+  switch (b->type)
     {
+    case bp_breakpoint:
+      if (b->addr_string == NULL)
+       {
+         /* Anything without a string can't be re-set. */
+         delete_breakpoint (b);
+         return 0;
+       }
+      /* In case we have a problem, disable this breakpoint.  We'll restore
+        its status if we succeed.  */
+      save_enable = b->enable;
+      b->enable = disabled;
+
       s = b->addr_string;
       sals = decode_line_1 (&s, 1, (struct symtab *)NULL, 0);
       for (i = 0; i < sals.nelts; i++)
        {
-         sal = sals.sals[i];
-         
-         b->symtab = sal.symtab;
-         b->line_number = sal.line;
-         if (sal.pc == 0 && sal.symtab != 0)
+         resolve_sal_pc (&sals.sals[i]);
+         if (b->symtab != sals.sals[i].symtab
+             || b->line_number != sals.sals[i].line
+             || b->address != sals.sals[i].pc)
            {
-             sal.pc = find_line_pc (sal.symtab, sal.line);
-             if (sal.pc == 0)
-               error ("No line %d in file \"%s\".",
-                      sal.line, sal.symtab->filename);
-           }
-         b->address = sal.pc;
+             b->symtab = sals.sals[i].symtab;
+             b->line_number = sals.sals[i].line;
+             b->address = sals.sals[i].pc;
 
-         if (b->cond_string != NULL)
-           {
-             s = b->cond_string;
-             b->cond = parse_exp_1 (&s, block_for_pc (sal.pc), 0);
-           }
+             if (b->cond_string != NULL)
+               {
+                 s = b->cond_string;
+                 b->cond = parse_exp_1 (&s, block_for_pc (sals.sals[i].pc), 0);
+               }
          
-         check_duplicates (b->address);
+             check_duplicates (b->address);
 
-         mention (b);
+             mention (b);
+           }
+         b->enable = save_enable;      /* Restore it, this worked. */
        }
-      free (sals.sals);
-    }
-  else
-    {
-      /* Anything without a string can't be re-set. */
+      free ((PTR)sals.sals);
+      break;
+    case bp_watchpoint:
+      /* FIXME!  This is the wrong thing to do.... */
+      delete_breakpoint (b);
+      break;
+    default:
+      printf_filtered ("Deleting unknown breakpoint type %d\n", b->type);
+    case bp_until:
+    case bp_finish:
+    case bp_longjmp:
+    case bp_longjmp_resume:
       delete_breakpoint (b);
+      break;
     }
+
   return 0;
 }
 
@@ -2038,17 +2256,34 @@ breakpoint_re_set_one (bint)
 void
 breakpoint_re_set ()
 {
-  struct breakpoint *b;
+  struct breakpoint *b, *temp;
+  static char message1[] = "Error in re-setting breakpoint %d:\n";
+  char message[sizeof (message1) + 30 /* slop */];
   
-  ALL_BREAKPOINTS (b)
+  /* If we have no current source symtab, and we have any breakpoints,
+     go through the work of making a source context.  */
+  if (current_source_symtab == NULL && breakpoint_chain != 0)
+    {
+      select_source_symtab (NULL);
+    }
+
+  ALL_BREAKPOINTS_SAFE (b, temp)
     {
-      b->symtab = 0;           /* Be sure we don't point to old dead symtab */
-      (void) catch_errors (breakpoint_re_set_one, (char *) b, 
-                          "Error in re-setting breakpoint:\n");
+      printf_filtered (message, message1, b->number);  /* Format possible error msg */
+      catch_errors (breakpoint_re_set_one, (char *) b, message);
     }
 
+  create_longjmp_breakpoint("longjmp");
+  create_longjmp_breakpoint("_longjmp");
+  create_longjmp_breakpoint("siglongjmp");
+  create_longjmp_breakpoint(NULL);
+
+#if 0
+  /* Took this out (temporaliy at least), since it produces an extra 
+     blank line at startup. This messes up the gdbtests. -PB */
   /* Blank line to finish off all those mention() messages we just printed.  */
   printf_filtered ("\n");
+#endif
 }
 \f
 /* Set ignore-count of breakpoint number BPTNUM to COUNT.
@@ -2071,11 +2306,13 @@ set_ignore_count (bptnum, count, from_tty)
        if (!from_tty)
          return;
        else if (count == 0)
-         printf ("Will stop next time breakpoint %d is reached.", bptnum);
+         printf_filtered ("Will stop next time breakpoint %d is reached.",
+                          bptnum);
        else if (count == 1)
-         printf ("Will ignore next crossing of breakpoint %d.", bptnum);
+         printf_filtered ("Will ignore next crossing of breakpoint %d.",
+                          bptnum);
        else
-         printf ("Will ignore next %d crossings of breakpoint %d.",
+         printf_filtered ("Will ignore next %d crossings of breakpoint %d.",
                  count, bptnum);
        return;
       }
@@ -2114,7 +2351,7 @@ ignore_command (args, from_tty)
   set_ignore_count (num,
                    longest_to_int (value_as_long (parse_and_eval (p))),
                    from_tty);
-  printf ("\n");
+  printf_filtered ("\n");
 }
 \f
 /* Call FUNCTION on each of the breakpoints
@@ -2123,7 +2360,7 @@ ignore_command (args, from_tty)
 static void
 map_breakpoint_numbers (args, function)
      char *args;
-     void (*function) ();
+     void (*function) PARAMS ((struct breakpoint *));
 {
   register char *p = args;
   char *p1;
@@ -2145,7 +2382,7 @@ map_breakpoint_numbers (args, function)
            function (b);
            goto win;
          }
-      printf ("No breakpoint number %d.\n", num);
+      printf_filtered ("No breakpoint number %d.\n", num);
     win:
       p = p1;
     }
@@ -2157,11 +2394,11 @@ enable_breakpoint (bpt)
 {
   bpt->enable = enabled;
 
-  if (xgdb_verbose && bpt->number >= 0)
-    printf ("breakpoint #%d enabled\n", bpt->number);
+  if (xgdb_verbose && bpt->type == bp_breakpoint)
+    printf_filtered ("breakpoint #%d enabled\n", bpt->number);
 
   check_duplicates (bpt->address);
-  if (bpt->val != NULL)
+  if (bpt->type == bp_watchpoint)
     {
       if (bpt->exp_valid_block != NULL
        && !contained_in (get_selected_block (), bpt->exp_valid_block))
@@ -2188,7 +2425,14 @@ enable_command (args, from_tty)
   struct breakpoint *bpt;
   if (args == 0)
     ALL_BREAKPOINTS (bpt)
-      enable_breakpoint (bpt);
+      switch (bpt->type)
+       {
+       case bp_breakpoint:
+       case bp_watchpoint:
+         enable_breakpoint (bpt);
+       default:
+         continue;
+       }
   else
     map_breakpoint_numbers (args, enable_breakpoint);
 }
@@ -2199,8 +2443,8 @@ disable_breakpoint (bpt)
 {
   bpt->enable = disabled;
 
-  if (xgdb_verbose && bpt->number >= 0)
-    printf ("breakpoint #%d disabled\n", bpt->number);
+  if (xgdb_verbose && bpt->type == bp_breakpoint)
+    printf_filtered ("breakpoint #%d disabled\n", bpt->number);
 
   check_duplicates (bpt->address);
 }
@@ -2214,7 +2458,14 @@ disable_command (args, from_tty)
   register struct breakpoint *bpt;
   if (args == 0)
     ALL_BREAKPOINTS (bpt)
-      disable_breakpoint (bpt);
+      switch (bpt->type)
+       {
+       case bp_breakpoint:
+       case bp_watchpoint:
+         disable_breakpoint (bpt);
+       default:
+         continue;
+       }
   else
     map_breakpoint_numbers (args, disable_breakpoint);
 }
@@ -2223,7 +2474,8 @@ static void
 enable_once_breakpoint (bpt)
      struct breakpoint *bpt;
 {
-  bpt->enable = temporary;
+  bpt->enable = enabled;
+  bpt->disposition = disable;
 
   check_duplicates (bpt->address);
 }
@@ -2241,7 +2493,8 @@ static void
 enable_delete_breakpoint (bpt)
      struct breakpoint *bpt;
 {
-  bpt->enable = delete;
+  bpt->enable = enabled;
+  bpt->disposition = delete;
 
   check_duplicates (bpt->address);
 }
@@ -2276,15 +2529,6 @@ decode_line_spec_1 (string, funfirstline)
   return sals;
 }
 \f
-
-/* Chain containing all defined enable commands.  */
-
-extern struct cmd_list_element 
-  *enablelist, *disablelist,
-  *deletelist, *enablebreaklist;
-
-extern struct cmd_list_element *cmdlist;
-
 void
 _initialize_breakpoint ()
 {
@@ -2416,15 +2660,42 @@ Do \"help breakpoints\" for info on other commands dealing with breakpoints.");
   add_com_alias ("brea", "break", class_run, 1);
 
   add_info ("breakpoints", breakpoints_info,
-           "Status of all breakpoints, or breakpoint number NUMBER.\n\
-Second column is \"y\" for enabled breakpoint, \"n\" for disabled,\n\
-\"o\" for enabled once (disable when hit), \"d\" for enable but delete when hit.\n\
-Then come the address and the file/line number.\n\n\
+           "Status of user-settable breakpoints, or breakpoint number NUMBER.\n\
+The \"Type\" column indicates one of:\n\
+\tbreakpoint     - normal breakpoint\n\
+\twatchpoint     - watchpoint\n\
+The \"Disp\" column contains one of \"keep\", \"del\", or \"dis\" to indicate\n\
+the disposition of the breakpoint after it gets hit.  \"dis\" means that the\n\
+breakpoint will be disabled.  The \"Address\" and \"What\" columns indicate the\n\
+address and file/line number respectively.\n\n\
 Convenience variable \"$_\" and default examine address for \"x\"\n\
 are set to the address of the last breakpoint listed.\n\n\
 Convenience variable \"$bpnum\" contains the number of the last\n\
 breakpoint set.");
 
+#if MAINTENANCE_CMDS
+
+  add_cmd ("breakpoints", class_maintenance, maintenance_info_breakpoints,
+           "Status of all breakpoints, or breakpoint number NUMBER.\n\
+The \"Type\" column indicates one of:\n\
+\tbreakpoint     - normal breakpoint\n\
+\twatchpoint     - watchpoint\n\
+\tlongjmp        - internal breakpoint used to step through longjmp()\n\
+\tlongjmp resume - internal breakpoint at the target of longjmp()\n\
+\tuntil          - internal breakpoint used by the \"until\" command\n\
+\tfinish         - internal breakpoint used by the \"finish\" command\n\
+The \"Disp\" column contains one of \"keep\", \"del\", or \"dis\" to indicate\n\
+the disposition of the breakpoint after it gets hit.  \"dis\" means that the\n\
+breakpoint will be disabled.  The \"Address\" and \"What\" columns indicate the\n\
+address and file/line number respectively.\n\n\
+Convenience variable \"$_\" and default examine address for \"x\"\n\
+are set to the address of the last breakpoint listed.\n\n\
+Convenience variable \"$bpnum\" contains the number of the last\n\
+breakpoint set.",
+          &maintenanceinfolist);
+
+#endif /* MAINTENANCE_CMDS */
+
   add_com ("catch", class_breakpoint, catch_command,
          "Set breakpoints to catch exceptions that are raised.\n\
 Argument may be a single exception to catch, multiple exceptions\n\
@@ -2442,7 +2713,37 @@ Do \"help breakpoints\" for info on other commands dealing with breakpoints.");
 A watchpoint stops execution of your program whenever the value of\n\
 an expression changes.");
 
-  add_info ("watchpoints", watchpoints_info,
-           "Status of all watchpoints, or watchpoint number NUMBER.\n\
-Second column is \"y\" for enabled watchpoints, \"n\" for disabled.");
+  add_info ("watchpoints", breakpoints_info,
+           "Synonym for ``info breakpoints''.");
 }
+
+#ifdef IBM6000_TARGET
+/* Where should this function go? It is used by AIX only. FIXME. */
+
+/* Breakpoint address relocation used to be done in breakpoint_re_set(). That
+   approach the following problem:
+
+     before running the program, if a file is list, then a breakpoint is
+     set (just the line number), then if we switch into another file and run
+     the program, just a line number as a breakpoint address was not
+     descriptive enough and breakpoint was ending up in a different file's
+     similar line. 
+
+  I don't think any other platform has this breakpoint relocation problem, so this
+  is not an issue for other platforms. */
+   
+void
+fixup_breakpoints (low, high, delta)
+  CORE_ADDR low;
+  CORE_ADDR high;
+  CORE_ADDR delta;
+{
+  struct breakpoint *b;
+
+  ALL_BREAKPOINTS (b)
+    {
+     if (b->address >= low && b->address <= high)
+       b->address += delta;
+    }
+}
+#endif
This page took 0.043572 seconds and 4 git commands to generate.