* xm-sun3os4.h, xm-sun4os4.h: Enable HAVE_MMAP.
[deliverable/binutils-gdb.git] / gdb / breakpoint.c
index 4617e5d02794e8a9e29dd22d9b440042a4de6da9..f6b136fc9a5412f84880f468274f79a5a2662a77 100644 (file)
@@ -3,19 +3,19 @@
 
 This file is part of GDB.
 
-GDB is free software; you can redistribute it and/or modify
+This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 1, or (at your option)
-any later version.
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
 
-GDB is distributed in the hope that it will be useful,
+This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with GDB; see the file COPYING.  If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+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>
@@ -32,6 +32,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "command.h"
 #include "inferior.h"
 #include "target.h"
+#include "language.h"
 #include <string.h>
 
 extern int addressprint;               /* Print machine addresses? */
@@ -130,7 +131,7 @@ set_breakpoint_count (num)
 {
   breakpoint_count = num;
   set_internalvar (lookup_internalvar ("bpnum"),
-                  value_from_long (builtin_type_int, (LONGEST) num));
+                  value_from_longest (builtin_type_int, (LONGEST) num));
 }
 
 /* Default address, symtab and line to put a breakpoint at
@@ -245,7 +246,7 @@ condition_command (arg, from_tty)
            /* I don't know if it matters whether this is the string the user
               typed in or the decompiled expression.  */
            b->cond_string = savestring (arg, strlen (arg));
-           b->cond = parse_c_1 (&arg, block_for_pc (b->address), 0);
+           b->cond = parse_exp_1 (&arg, block_for_pc (b->address), 0);
            if (*arg)
              error ("Junk at end of expression");
          }
@@ -255,6 +256,7 @@ condition_command (arg, from_tty)
   error ("No breakpoint number %d.", bnum);
 }
 
+/* ARGSUSED */
 static void
 commands_command (arg, from_tty)
      char *arg;
@@ -280,7 +282,7 @@ commands_command (arg, from_tty)
   ALL_BREAKPOINTS (b)
     if (b->number == bnum)
       {
-       if (input_from_terminal_p ())
+       if (from_tty && input_from_terminal_p ())
          {
            printf ("Type commands for when breakpoint %d is hit, one per line.\n\
 End with a line saying just \"end\".\n", bnum);
@@ -417,6 +419,10 @@ insert_breakpoints ()
 #endif
              {
                fprintf (stderr, "Cannot insert breakpoint %d:\n", b->number);
+#ifdef ONE_PROCESS_WRITETEXT
+               fprintf (stderr,
+                 "The same program may be running in another process.\n");
+#endif
                memory_error (val, b->address); /* which bombs us out */
              }
          }
@@ -446,8 +452,12 @@ remove_breakpoints ()
          return val;
        b->inserted = 0;
 #ifdef BREAKPOINT_DEBUG
-       printf ("Removed breakpoint at 0x%x, shadow 0x%x, 0x%x.\n",
-               b->address, b->shadow_contents[0], b->shadow_contents[1]);
+       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]));
 #endif /* BREAKPOINT_DEBUG */
       }
 
@@ -566,6 +576,15 @@ bpstat_clear_actions (bs)
     }
 }
 
+/* Stub for cleaning up our state if we error-out of a breakpoint command */
+/* ARGSUSED */
+static void
+cleanup_executing_breakpoints (ignore)
+     int ignore;
+{
+  executing_breakpoint_commands = 0;
+}
+
 /* Execute all the commands associated with all the breakpoints at this
    location.  Any of these commands could cause the process to proceed
    beyond this point, etc.  We look out for such changes by checking
@@ -575,11 +594,14 @@ bpstat_do_actions (bsp)
      bpstat *bsp;
 {
   bpstat bs;
+  struct cleanup *old_chain;
+
+  executing_breakpoint_commands = 1;
+  old_chain = make_cleanup (cleanup_executing_breakpoints, 0);
 
 top:
   bs = *bsp;
 
-  executing_breakpoint_commands = 1;
   breakpoint_proceeded = 0;
   for (; bs != NULL; bs = bs->next)
     {
@@ -599,6 +621,7 @@ top:
   clear_momentary_breakpoints ();
 
   executing_breakpoint_commands = 0;
+  discard_cleanups (old_chain);
 }
 
 int
@@ -643,20 +666,27 @@ bpstat_print (bs)
       return 1;
     }
 
+  /* Maybe another breakpoint in the chain caused us to stop.
+     (Currently all watchpoints go on the bpstat whether hit or
+     not.  That probably could (should) be changed, provided care is taken
+     with respect to bpstat_explains_signal).  */
+  if (bs->next)
+    return bpstat_print (bs->next);
+
   fprintf_filtered (stderr, "gdb internal error: in bpstat_print\n");
   return 0;
 }
 
 /* Evaluate the expression EXP and return 1 if value is zero.
    This is used inside a catch_errors to evaluate the breakpoint condition. 
-   The argument is a "struct expression *" that has been cast to int to 
+   The argument is a "struct expression *" that has been cast to char * to 
    make it pass through catch_errors.  */
 
 static int
 breakpoint_cond_eval (exp)
-     int exp;
+     char *exp;
 {
-  return value_zerop (evaluate_expression ((struct expression *)exp));
+  return !value_true (evaluate_expression ((struct expression *)exp));
 }
 
 /* Allocate a new bpstat and chain it to the current one.  */
@@ -706,8 +736,10 @@ bpstat_stop_status (pc, frame_address)
   int stop = 0;
   int print = 0;
   CORE_ADDR bp_addr;
+#if DECR_PC_AFTER_BREAK != 0 || defined (SHIFT_INST_REGS)
   /* True if we've hit a breakpoint (as opposed to a watchpoint).  */
   int real_breakpoint = 0;
+#endif
   /* Root of the chain of bpstat's */
   struct bpstat__struct root_bs[1];
   /* Pointer to the last thing in the chain currently.  */
@@ -742,10 +774,16 @@ bpstat_stop_status (pc, frame_address)
 
          if (within_current_scope)
            {
+             /* We use value_{,free_to_}mark because it could be a
+                *long* time before we return to the command level and
+                call free_all_values.  */
+
+             value mark = value_mark ();
              value new_val = evaluate_expression (b->exp);
-             release_value (new_val);
              if (!value_equal (b->val, new_val))
                {
+                 release_value (new_val);
+                 value_free_to_mark (mark);
                  bs->old_val = b->val;
                  b->val = new_val;
                  /* We will stop here */
@@ -753,7 +791,7 @@ bpstat_stop_status (pc, frame_address)
              else
                {
                  /* Nothing changed, don't do anything.  */
-                 value_free (new_val);
+                 value_free_to_mark (mark);
                  continue;
                  /* We won't stop here */
                }
@@ -777,26 +815,29 @@ which its expression is valid.\n", b->number);
              continue;
            }
        }
+#if DECR_PC_AFTER_BREAK != 0 || defined (SHIFT_INST_REGS)
       else
        real_breakpoint = 1;
+#endif
 
       if (b->frame && b->frame != frame_address)
        this_bp_stop = 0;
       else
        {
-         int value_zero;
+         int value_is_zero;
 
          if (b->cond)
            {
              /* Need to select the frame, with all that implies
                 so that the conditions will have the right context.  */
              select_frame (get_current_frame (), 0);
-             value_zero
-               = catch_errors (breakpoint_cond_eval, (int)(b->cond),
-                               "Error occurred in testing breakpoint condition.");
+             value_is_zero
+               = catch_errors (breakpoint_cond_eval, (char *)(b->cond),
+                               "Error in testing breakpoint condition:\n");
+                               /* FIXME-someday, should give breakpoint # */
              free_all_values ();
            }
-         if (b->cond && value_zero)
+         if (b->cond && value_is_zero)
            {
              this_bp_stop = 0;
            }
@@ -913,7 +954,7 @@ breakpoint_1 (bnum, watchpoints)
          print_expression (b->exp, stdout);
        } else {
            if (addressprint)
-             printf_filtered (" 0x%08x ", b->address);
+             printf_filtered (" %s ", local_hex_string_custom(b->address, "08"));
 
            last_addr = b->address;
            if (b->symtab)
@@ -929,13 +970,14 @@ breakpoint_1 (bnum, watchpoints)
                printf_filtered (":%d", b->line_number);
              }
            else
-             print_address_symbolic (b->address, stdout, demangle);
+             print_address_symbolic (b->address, stdout, demangle, " ");
          }
 
        printf_filtered ("\n");
 
        if (b->frame)
-         printf_filtered ("\tstop only in stack frame at 0x%x\n", b->frame);
+         printf_filtered ("\tstop only in stack frame at %s\n",
+                          local_hex_string(b->frame));
        if (b->cond)
          {
            printf_filtered ("\tstop only if ");
@@ -969,6 +1011,7 @@ breakpoint_1 (bnum, watchpoints)
     set_next_address (last_addr);
 }
 
+/* ARGSUSED */
 static void
 breakpoints_info (bnum_exp, from_tty)
      char *bnum_exp;
@@ -982,6 +1025,7 @@ breakpoints_info (bnum_exp, from_tty)
   breakpoint_1 (bnum, 0);
 }
 
+/* ARGSUSED */
 static void
 watchpoints_info (bnum_exp, from_tty)
      char *bnum_exp;
@@ -1019,7 +1063,7 @@ describe_other_breakpoints (pc)
                    (b->enable == disabled) ? " (disabled)" : "",
                    (others > 1) ? "," : ((others == 1) ? " and" : ""));
          }
-      printf ("also set at pc 0x%x.\n", pc);
+      printf ("also set at pc %s.\n", local_hex_string(pc));
     }
 }
 \f
@@ -1148,7 +1192,8 @@ mention (b)
     }
   else
     {
-      printf_filtered ("Breakpoint %d at 0x%x", b->number, b->address);
+      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);
@@ -1287,7 +1332,7 @@ break_command_1 (arg, tempflag, from_tty)
            {
              arg += 2;
              cond_start = arg;
-             cond = parse_c_1 (&arg, block_for_pc (pc), 0);
+             cond = parse_exp_1 (&arg, block_for_pc (pc), 0);
              cond_end = arg;
            }
          else
@@ -1343,6 +1388,7 @@ tbreak_command (arg, from_tty)
   break_command_1 (arg, 1, from_tty);
 }
 
+/* ARGSUSED */
 static void
 watch_command (arg, from_tty)
      char *arg;
@@ -1360,7 +1406,7 @@ watch_command (arg, from_tty)
   
   /* Parse arguments.  */
   innermost_block = NULL;
-  exp = parse_c_expression (arg);
+  exp = parse_expression (arg);
   exp_valid_block = innermost_block;
   val = evaluate_expression (exp);
   release_value (val);
@@ -1381,6 +1427,7 @@ watch_command (arg, from_tty)
  * Helper routine for the until_command routine in infcmd.c.  Here
  * because it uses the mechanisms of breakpoints.
  */
+/* ARGSUSED */
 void
 until_break_command (arg, from_tty)
      char *arg;
@@ -1433,6 +1480,8 @@ until_break_command (arg, from_tty)
   proceed (-1, -1, 0);
 }
 \f
+#if 0
+/* These aren't used; I don't konw what they were for.  */
 /* Set a breakpoint at the catch clause for NAME.  */
 static int
 catch_breakpoint (name)
@@ -1454,6 +1503,7 @@ static int
 enable_catch_breakpoint ()
 {
 }
+#endif /* 0 */
 
 struct sal_chain
 {
@@ -1461,6 +1511,8 @@ struct sal_chain
   struct symtab_and_line sal;
 };
 
+#if 0
+/* This isn't used; I don't know what it was for.  */
 /* For each catch clause identified in ARGS, run FUNCTION
    with that clause as an argument.  */
 static struct symtabs_and_lines
@@ -1471,7 +1523,9 @@ map_catch_names (args, function)
   register char *p = args;
   register char *p1;
   struct symtabs_and_lines sals;
+#if 0
   struct sal_chain *sal_chain = 0;
+#endif
 
   if (p == 0)
     error_no_arg ("one or more catch names");
@@ -1510,11 +1564,14 @@ map_catch_names (args, function)
        }
 #endif
       printf ("No catch clause for exception %s.\n", p);
+#if 0
     win:
+#endif
       p = p1;
       while (*p == ' ' || *p == '\t') p++;
     }
 }
+#endif /* 0 */
 
 /* This shares a lot of code with `print_frame_label_vars' from stack.c.  */
 
@@ -1524,14 +1581,22 @@ get_catch_sals (this_level_only)
 {
   extern struct blockvector *blockvector_for_pc ();
   register struct blockvector *bl;
-  register struct block *block = get_frame_block (selected_frame);
+  register struct block *block;
   int index, have_default = 0;
-  struct frame_info *fi = get_frame_info (selected_frame);
-  CORE_ADDR pc = fi->pc;
+  struct frame_info *fi;
+  CORE_ADDR pc;
   struct symtabs_and_lines sals;
   struct sal_chain *sal_chain = 0;
   char *blocks_searched;
 
+  /* Not sure whether an error message is always the correct response,
+     but it's better than a core dump.  */
+  if (selected_frame == NULL)
+    error ("No selected frame.");
+  block = get_frame_block (selected_frame);
+  fi = get_frame_info (selected_frame);
+  pc = fi->pc;
+
   sals.nelts = 0;
   sals.sals = NULL;
 
@@ -1660,7 +1725,10 @@ catch_command_1 (arg, tempflag, from_tty)
     {
       /* Grab selected catch clauses.  */
       error ("catch NAME not implemeneted");
+#if 0
+      /* This isn't used; I don't know what it was for.  */
       sals = map_catch_names (arg, catch_breakpoint);
+#endif
     }
 
   if (! sals.nelts) 
@@ -1684,7 +1752,7 @@ catch_command_1 (arg, tempflag, from_tty)
        {
          if (arg[0] == 'i' && arg[1] == 'f'
              && (arg[2] == ' ' || arg[2] == '\t'))
-           cond = (struct expression *) parse_c_1 ((arg += 2, &arg),
+           cond = (struct expression *) parse_exp_1 ((arg += 2, &arg),
                                                    block_for_pc (pc), 0);
          else
            error ("Junk at end of arguments.");
@@ -1706,7 +1774,7 @@ catch_command_1 (arg, tempflag, from_tty)
       if (tempflag)
        b->enable = temporary;
 
-      printf ("Breakpoint %d at 0x%x", b->number, b->address);
+      printf ("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");
@@ -1720,6 +1788,8 @@ catch_command_1 (arg, tempflag, from_tty)
   free (sals.sals);
 }
 
+#if 0
+/* These aren't used; I don't know what they were for.  */
 /* Disable breakpoints on all catch clauses described in ARGS.  */
 static void
 disable_catch (args)
@@ -1743,6 +1813,7 @@ delete_catch (args)
 {
   /* Map the delete command to catch clauses described in ARGS.  */
 }
+#endif /* 0 */
 
 static void
 catch_command (arg, from_tty)
@@ -1910,9 +1981,13 @@ delete_command (arg, from_tty)
     map_breakpoint_numbers (arg, delete_breakpoint);
 }
 
-static void
+/* Reset a breakpoint given it's struct breakpoint * BINT.
+   The value we return ends up being the return value from catch_errors.
+   Unused in this case.  */
+
+static int
 breakpoint_re_set_one (bint)
-     int bint;
+     char *bint;
 {
   struct breakpoint *b = (struct breakpoint *)bint;  /* get past catch_errs */
   int i;
@@ -1942,7 +2017,7 @@ breakpoint_re_set_one (bint)
          if (b->cond_string != NULL)
            {
              s = b->cond_string;
-             b->cond = parse_c_1 (&s, block_for_pc (sal.pc), 0);
+             b->cond = parse_exp_1 (&s, block_for_pc (sal.pc), 0);
            }
          
          check_duplicates (b->address);
@@ -1956,6 +2031,7 @@ breakpoint_re_set_one (bint)
       /* Anything without a string can't be re-set. */
       delete_breakpoint (b);
     }
+  return 0;
 }
 
 /* Re-set all breakpoints after symbols have been re-loaded.  */
@@ -1967,8 +2043,8 @@ breakpoint_re_set ()
   ALL_BREAKPOINTS (b)
     {
       b->symtab = 0;           /* Be sure we don't point to old dead symtab */
-      (void) catch_errors (breakpoint_re_set_one, (int) b, 
-                          "Error in re-setting breakpoint");
+      (void) catch_errors (breakpoint_re_set_one, (char *) b, 
+                          "Error in re-setting breakpoint:\n");
     }
 
   /* Blank line to finish off all those mention() messages we just printed.  */
@@ -2035,7 +2111,9 @@ ignore_command (args, from_tty)
   if (*p == 0)
     error ("Second argument (specified ignore-count) is missing.");
 
-  set_ignore_count (num, parse_and_eval_address (p), from_tty);
+  set_ignore_count (num,
+                   longest_to_int (value_as_long (parse_and_eval (p))),
+                   from_tty);
   printf ("\n");
 }
 \f
@@ -2101,6 +2179,7 @@ is valid is not currently in scope.\n", bpt->number);
     }
 }
 
+/* ARGSUSED */
 static void
 enable_command (args, from_tty)
      char *args;
@@ -2126,6 +2205,7 @@ disable_breakpoint (bpt)
   check_duplicates (bpt->address);
 }
 
+/* ARGSUSED */
 static void
 disable_command (args, from_tty)
      char *args;
@@ -2148,6 +2228,7 @@ enable_once_breakpoint (bpt)
   check_duplicates (bpt->address);
 }
 
+/* ARGSUSED */
 static void
 enable_once_command (args, from_tty)
      char *args;
@@ -2165,6 +2246,7 @@ enable_delete_breakpoint (bpt)
   check_duplicates (bpt->address);
 }
 
+/* ARGSUSED */
 static void
 enable_delete_command (args, from_tty)
      char *args;
@@ -2225,8 +2307,8 @@ then no output is printed when it is hit, except what the commands print.");
 
   add_com ("condition", class_breakpoint, condition_command,
           "Specify breakpoint number N to break only if COND is true.\n\
-N is an integer; COND is a C expression to be evaluated whenever\n\
-breakpoint N is reached.  Actually break only when COND is nonzero.");
+N is an integer; COND is an expression to be evaluated whenever\n\
+breakpoint N is reached.  ");
 
   add_com ("tbreak", class_breakpoint, tbreak_command,
           "Set a temporary breakpoint.  Args like \"break\" command.\n\
This page took 0.052314 seconds and 4 git commands to generate.