* config/i386/nm-nbsd.h (FLOAT_INFO): Comment out.
[deliverable/binutils-gdb.git] / gdb / breakpoint.c
index aa9ebf678cf12a2c0b362171c42e597f0073ce5e..2a2842a51c9885bdde8b58306e7b58b3cf9b04a3 100644 (file)
@@ -1,5 +1,5 @@
 /* Everything about breakpoints, for GDB.
-   Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994
+   Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
              Free Software Foundation, Inc.
 
 This file is part of GDB.
@@ -16,7 +16,7 @@ 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 <ctype.h>
@@ -28,13 +28,12 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "gdbcore.h"
 #include "gdbcmd.h"
 #include "value.h"
-#include "ctype.h"
 #include "command.h"
 #include "inferior.h"
 #include "thread.h"
 #include "target.h"
 #include "language.h"
-#include <string.h>
+#include "gdb_string.h"
 #include "demangle.h"
 #include "annotate.h"
 
@@ -58,15 +57,9 @@ 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 *)));
 
@@ -158,29 +151,13 @@ static int executing_breakpoint_commands;
             b? (tmp=b->next, 1): 0;    \
             b = tmp)
 
-/* By default no support for hardware watchpoints is assumed.  */
-#ifndef TARGET_CAN_USE_HARDWARE_WATCHPOINT
-#define TARGET_CAN_USE_HARDWARE_WATCHPOINT(TYPE,CNT,OTHERTYPE) 0
-#define target_remove_watchpoint(ADDR,LEN,TYPE) -1
-#define target_insert_watchpoint(ADDR,LEN,TYPE) -1
-#endif
-
-#ifndef target_insert_hw_breakpoint
-#define target_remove_hw_breakpoint(ADDR,SHADOW) -1
-#define target_insert_hw_breakpoint(ADDR,SHADOW) -1
-#endif
-
-#ifndef target_stopped_data_address
-#define target_stopped_data_address() 0
-#endif
-
 /* True if breakpoint hit counts should be displayed in breakpoint info.  */
 
 int show_breakpoint_hit_counts = 1;
 
 /* Chain of all breakpoints defined.  */
 
-static struct breakpoint *breakpoint_chain;
+struct breakpoint *breakpoint_chain;
 
 /* Number of last breakpoint made.  */
 
@@ -675,8 +652,8 @@ remove_breakpoint (b)
        }
       /* Failure to remove any of the hardware watchpoints comes here.  */
       if (b->inserted)
-       error ("Hardware watchpoint %d: Could not remove watchpoint\n",
-              b->number);
+       warning ("Hardware watchpoint %d: Could not remove watchpoint\n",
+                b->number);
       
       /* Free the saved value chain.  We will construct a new one
         the next time the watchpoint is inserted.  */
@@ -935,6 +912,7 @@ bpstat_do_actions (bsp)
 {
   bpstat bs;
   struct cleanup *old_chain;
+  struct command_line *cmd;
 
   executing_breakpoint_commands = 1;
   old_chain = make_cleanup (cleanup_executing_breakpoints, 0);
@@ -945,18 +923,20 @@ top:
   breakpoint_proceeded = 0;
   for (; bs != NULL; bs = bs->next)
     {
-      while (bs->commands)
+      cmd = bs->commands;
+      while (cmd != NULL)
        {
-         char *line = bs->commands->line;
-         bs->commands = bs->commands->next;
-         execute_command (line, 0);
-         /* If the inferior is proceeded by the command, bomb out now.
-            The bpstat chain has been blown away by wait_for_inferior.
-            But since execution has stopped again, there is a new bpstat
-            to look at, so start over.  */
-         if (breakpoint_proceeded)
-           goto top;
+         execute_control_command (cmd);
+         cmd = cmd->next;
        }
+      if (breakpoint_proceeded)
+       /* The inferior is proceeded by the command; bomb out now.
+          The bpstat chain has been blown away by wait_for_inferior.
+          But since execution has stopped again, there is a new bpstat
+          to look at, so start over.  */
+       goto top;
+      else
+       bs->commands = NULL;
     }
 
   executing_breakpoint_commands = 0;
@@ -1094,6 +1074,9 @@ bpstat_alloc (b, cbs)
 /* The value has not changed.  */
 #define WP_VALUE_NOT_CHANGED 3
 
+#define BP_TEMPFLAG 1
+#define BP_HARDWAREFLAG 2
+
 /* Check watchpoint condition.  */
 
 static int
@@ -1102,8 +1085,8 @@ watchpoint_check (p)
 {
   bpstat bs = (bpstat) p;
   struct breakpoint *b;
-  struct frame_info *saved_frame, *fr;
-  int within_current_scope, saved_level;
+  struct frame_info *fr;
+  int within_current_scope;
 
   b = bs->breakpoint_at;
 
@@ -1223,7 +1206,7 @@ bpstat_stop_status (pc, not_a_breakpoint)
   int real_breakpoint = 0;
 #endif
   /* Root of the chain of bpstat's */
-  struct bpstat root_bs[1];
+  struct bpstats root_bs[1];
   /* Pointer to the last thing in the chain currently.  */
   bpstat bs = root_bs;
   static char message1[] =
@@ -1246,9 +1229,6 @@ bpstat_stop_status (pc, not_a_breakpoint)
          && b->address != bp_addr)
        continue;
 
-#ifndef DECR_PC_AFTER_HW_BREAK
-#define DECR_PC_AFTER_HW_BREAK 0
-#endif
       if (b->type == bp_hardware_breakpoint
          && b->address != (bp_addr - DECR_PC_AFTER_HW_BREAK))
        continue;
@@ -1468,6 +1448,9 @@ bpstat_what (bs)
     /* We hit the through_sigtramp breakpoint.  */
     through_sig,
 
+    /* We hit the shared library event breakpoint.  */
+    shlib_event,
+
     /* This is just used to count how many enums there are.  */
     class_last
     };
@@ -1475,15 +1458,16 @@ bpstat_what (bs)
   /* Here is the table which drives this routine.  So that we can
      format it pretty, we define some abbreviations for the
      enum bpstat_what codes.  */
-#define keep_c BPSTAT_WHAT_KEEP_CHECKING
-#define stop_s BPSTAT_WHAT_STOP_SILENT
-#define stop_n BPSTAT_WHAT_STOP_NOISY
-#define single BPSTAT_WHAT_SINGLE
-#define setlr BPSTAT_WHAT_SET_LONGJMP_RESUME
-#define clrlr BPSTAT_WHAT_CLEAR_LONGJMP_RESUME
-#define clrlrs BPSTAT_WHAT_CLEAR_LONGJMP_RESUME_SINGLE
+#define kc BPSTAT_WHAT_KEEP_CHECKING
+#define ss BPSTAT_WHAT_STOP_SILENT
+#define sn BPSTAT_WHAT_STOP_NOISY
+#define sgl BPSTAT_WHAT_SINGLE
+#define slr BPSTAT_WHAT_SET_LONGJMP_RESUME
+#define clr BPSTAT_WHAT_CLEAR_LONGJMP_RESUME
+#define clrs BPSTAT_WHAT_CLEAR_LONGJMP_RESUME_SINGLE
 #define sr BPSTAT_WHAT_STEP_RESUME
 #define ts BPSTAT_WHAT_THROUGH_SIGTRAMP
+#define shl BPSTAT_WHAT_CHECK_SHLIBS
 
 /* "Can't happen."  Might want to print an error message.
    abort() is not out of the question, but chances are GDB is just
@@ -1508,29 +1492,31 @@ bpstat_what (bs)
     table[(int)class_last][(int)BPSTAT_WHAT_LAST] =
       {
        /*                              old action */
-       /*       keep_c stop_s stop_n single  setlr   clrlr   clrlrs  sr  ts
+       /*       kc   ss   sn   sgl   slr  clr   clrs  sr   ts  shl
         */
-/*no_effect*/  {keep_c,stop_s,stop_n,single, setlr , clrlr , clrlrs, sr, ts},
-/*wp_silent*/  {stop_s,stop_s,stop_n,stop_s, stop_s, stop_s, stop_s, sr, ts},
-/*wp_noisy*/    {stop_n,stop_n,stop_n,stop_n, stop_n, stop_n, stop_n, sr, ts},
-/*bp_nostop*/  {single,stop_s,stop_n,single, setlr , clrlrs, clrlrs, sr, ts},
-/*bp_silent*/  {stop_s,stop_s,stop_n,stop_s, stop_s, stop_s, stop_s, sr, ts},
-/*bp_noisy*/    {stop_n,stop_n,stop_n,stop_n, stop_n, stop_n, stop_n, sr, ts},
-/*long_jump*/  {setlr ,stop_s,stop_n,setlr , err   , err   , err   , sr, ts},
-/*long_resume*/        {clrlr ,stop_s,stop_n,clrlrs, err   , err   , err   , sr, ts},
-/*step_resume*/        {sr    ,sr    ,sr    ,sr    , sr    , sr    , sr    , sr, ts},
-/*through_sig*/ {ts    ,ts    ,ts    ,ts    , ts    , ts    , ts    , ts, ts}
+/*no_effect*/  {kc,  ss,  sn,  sgl,  slr, clr,  clrs, sr,  ts, shl},
+/*wp_silent*/  {ss,  ss,  sn,  ss,   ss,  ss,   ss,   sr,  ts, shl},
+/*wp_noisy*/    {sn,  sn,  sn,  sn,   sn,  sn,   sn,   sr,  ts, shl},
+/*bp_nostop*/  {sgl, ss,  sn,  sgl,  slr, clrs, clrs, sr,  ts, shl},
+/*bp_silent*/  {ss,  ss,  sn,  ss,   ss,  ss,   ss,   sr,  ts, shl},
+/*bp_noisy*/    {sn,  sn,  sn,  sn,   sn,  sn,   sn,   sr,  ts, shl},
+/*long_jump*/  {slr, ss,  sn,  slr,  err, err,  err,  sr,  ts, shl},
+/*long_resume*/        {clr, ss,  sn,  clrs, err, err,  err,  sr,  ts, shl},
+/*step_resume*/        {sr,  sr,  sr,  sr,   sr,  sr,   sr,   sr,  ts, shl},
+/*through_sig*/ {ts,  ts,  ts,  ts,   ts,  ts,   ts,   ts,  ts, shl},
+/*shlib*/       {shl, shl, shl, shl,  shl, shl,  shl,  shl, ts, shl}
              };
-#undef keep_c
-#undef stop_s
-#undef stop_n
-#undef single
-#undef setlr
-#undef clrlr
-#undef clrlrs
+#undef kc
+#undef ss
+#undef sn
+#undef sgl
+#undef slr
+#undef clr
+#undef clrs
 #undef err
 #undef sr
 #undef ts
+#undef shl
   enum bpstat_what_main_action current_action = BPSTAT_WHAT_KEEP_CHECKING;
   struct bpstat_what retval;
 
@@ -1595,7 +1581,9 @@ bpstat_what (bs)
        case bp_watchpoint_scope:
          bs_class = bp_nostop;
          break;
-
+       case bp_shlib_event:
+         bs_class = shlib_event;
+         break;
        case bp_call_dummy:
          /* Make sure the action is stop (silent or noisy), so infrun.c
             pops the dummy frame.  */
@@ -1642,7 +1630,9 @@ breakpoint_1 (bnum, allflag)
                              "hw watchpoint", "read watchpoint",
                              "acc watchpoint", "longjmp",
                              "longjmp resume", "step resume",
-                             "watchpoint scope", "call dummy" };
+                             "sigtramp",
+                             "watchpoint scope", "call dummy",
+                             "shlib events" };
   static char *bpdisps[] = {"del", "dis", "keep"};
   static char bpenables[] = "ny";
   char wrap_indent[80];
@@ -1720,6 +1710,7 @@ breakpoint_1 (bnum, allflag)
          case bp_through_sigtramp:
          case bp_watchpoint_scope:
          case bp_call_dummy:
+         case bp_shlib_event:
            if (addressprint)
              {
                annotate_field (4);
@@ -1793,9 +1784,7 @@ breakpoint_1 (bnum, allflag)
 
            while (l)
              {
-               fputs_filtered ("\t", gdb_stdout);
-               fputs_filtered (l->line, gdb_stdout);
-               fputs_filtered ("\n", gdb_stdout);
+               print_command_line (l, 4);
                l = l->next;
              }
          }
@@ -1973,19 +1962,20 @@ set_raw_breakpoint (sal)
   return b;
 }
 
+static int internal_breakpoint_number = -1;
+
 static void
-create_longjmp_breakpoint(func_name)
+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);
+      m = lookup_minimal_symbol_text (func_name, NULL, (struct objfile *)NULL);
       if (m)
        sal.pc = SYMBOL_VALUE_ADDRESS (m);
       else
@@ -1997,7 +1987,7 @@ create_longjmp_breakpoint(func_name)
   sal.symtab = NULL;
   sal.line = 0;
 
-  b = set_raw_breakpoint(sal);
+  b = set_raw_breakpoint (sal);
   if (!b) return;
 
   b->type = func_name != NULL ? bp_longjmp : bp_longjmp_resume;
@@ -2040,6 +2030,34 @@ disable_longjmp_breakpoint()
       }
 }
 
+#ifdef SOLIB_ADD
+void
+remove_solib_event_breakpoints ()
+{
+  register struct breakpoint *b;
+
+  ALL_BREAKPOINTS (b)
+    if (b->type == bp_shlib_event)
+      delete_breakpoint (b);
+}
+
+void
+create_solib_event_breakpoint (address)
+     CORE_ADDR address;
+{
+  struct breakpoint *b;
+  struct symtab_and_line sal;
+
+  sal.pc = address;
+  sal.symtab = NULL;
+  sal.line = 0;
+  b = set_raw_breakpoint (sal);
+  b->number = internal_breakpoint_number--;
+  b->disposition = donttouch;
+  b->type = bp_shlib_event;
+}
+#endif
+
 int
 hw_breakpoint_used_count()
 {
@@ -2123,6 +2141,13 @@ set_momentary_breakpoint (sal, frame, type)
   b->enable = enabled;
   b->disposition = donttouch;
   b->frame = (frame ? frame->frame : 0);
+
+  /* If we're debugging a multi-threaded program, then we
+     want momentary breakpoints to be active in only a 
+     single thread of control.  */
+  if (in_thread_list (inferior_pid))
+    b->thread = pid_to_thread_id (inferior_pid);
+
   return b;
 }
 
@@ -2272,8 +2297,8 @@ break_command_1 (arg, flag, from_tty)
   int i;
   int thread;
 
-  hardwareflag = flag & 2;
-  tempflag = flag & 1;
+  hardwareflag = flag & BP_HARDWAREFLAG;
+  tempflag = flag & BP_TEMPFLAG;
 
   sals.sals = NULL;
   sals.nelts = 0;
@@ -2424,7 +2449,7 @@ break_command_1 (arg, flag, from_tty)
        b->cond_string = savestring (cond_start, cond_end - cond_start);
                                     
       b->enable = enabled;
-      b->disposition = tempflag ? delete : donttouch;
+      b->disposition = tempflag ? del : donttouch;
 
       mention (b);
     }
@@ -2455,8 +2480,6 @@ resolve_sal_pc (sal)
     }
 }
 
-#define BP_TEMPFLAG 1
-#define BP_HARDWAREFLAG 2
 void
 break_command (arg, from_tty)
      char *arg;
@@ -2617,7 +2640,7 @@ watch_command_1 (arg, accessflag, from_tty)
          scope_breakpoint->enable = enabled;
 
          /* Automatically delete the breakpoint when it hits.  */
-         scope_breakpoint->disposition = delete;
+         scope_breakpoint->disposition = del;
 
          /* Only break in the proper frame (help with recursion).  */
          scope_breakpoint->frame = prev_frame->frame;
@@ -3021,7 +3044,7 @@ catch_command_1 (arg, tempflag, from_tty)
       b->type = bp_breakpoint;
       b->cond = cond;
       b->enable = enabled;
-      b->disposition = tempflag ? delete : donttouch;
+      b->disposition = tempflag ? del : donttouch;
 
       mention (b);
     }
@@ -3034,6 +3057,22 @@ catch_command_1 (arg, tempflag, from_tty)
   free ((PTR)sals.sals);
 }
 
+/* Used by the gui, could be made a worker for other things. */
+
+struct breakpoint *
+set_breakpoint_sal (sal)
+struct symtab_and_line sal;
+{
+  struct breakpoint *b;
+  b = set_raw_breakpoint (sal);
+  set_breakpoint_count (breakpoint_count + 1);
+  b->number = breakpoint_count;
+  b->type = bp_breakpoint;
+  b->cond = 0;
+  b->thread = -1;
+  return b;
+}
+
 #if 0
 /* These aren't used; I don't know what they were for.  */
 /* Disable breakpoints on all catch clauses described in ARGS.  */
@@ -3168,7 +3207,7 @@ breakpoint_auto_delete (bs)
      bpstat bs;
 {
   for (; bs; bs = bs->next)
-    if (bs->breakpoint_at && bs->breakpoint_at->disposition == delete
+    if (bs->breakpoint_at && bs->breakpoint_at->disposition == del 
        && bs->stop)
       delete_breakpoint (bs->breakpoint_at);
 }
@@ -3255,7 +3294,7 @@ delete_command (arg, from_tty)
     {
       /* Ask user only if there are some breakpoints to delete.  */
       if (!from_tty
-         || (breakpoint_chain && query ("Delete all breakpoints? ", 0, 0)))
+         || (breakpoint_chain && query ("Delete all breakpoints? ")))
        {
          /* No arg; clear all breakpoints.  */
          while (breakpoint_chain)
@@ -3394,6 +3433,11 @@ breakpoint_re_set_one (bint)
     case bp_call_dummy:
       delete_breakpoint (b);
       break;
+
+    /* This breakpoint is special, it's set up when the inferior
+       starts and we really don't want to touch it.  */
+    case bp_shlib_event:
+      break;
     }
 
   return 0;
@@ -3420,13 +3464,15 @@ breakpoint_re_set ()
   set_language (save_language);
   input_radix = save_input_radix;
 
-  create_longjmp_breakpoint("longjmp");
-  create_longjmp_breakpoint("_longjmp");
-  create_longjmp_breakpoint("siglongjmp");
-  create_longjmp_breakpoint(NULL);
+#ifdef GET_LONGJMP_TARGET
+  create_longjmp_breakpoint ("longjmp");
+  create_longjmp_breakpoint ("_longjmp");
+  create_longjmp_breakpoint ("siglongjmp");
+  create_longjmp_breakpoint (NULL);
+#endif
 
 #if 0
-  /* Took this out (temporaliy at least), since it produces an extra 
+  /* Took this out (temporarily 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");
@@ -3540,7 +3586,7 @@ map_breakpoint_numbers (args, function)
     }
 }
 
-static void
+void
 enable_breakpoint (bpt)
      struct breakpoint *bpt;
 {
@@ -3549,9 +3595,6 @@ enable_breakpoint (bpt)
   int target_resources_ok, other_type_used;
   struct value *mark;
   
-  if (enable_breakpoint_hook)
-    enable_breakpoint_hook (bpt);
-
   if (bpt->type == bp_hardware_breakpoint)
     {
       int i;
@@ -3620,6 +3663,9 @@ have been allocated for other watchpoints.\n", bpt->number);
        select_frame (save_selected_frame, save_selected_frame_level);
       value_free_to_mark (mark);
     }
+
+  if (modify_breakpoint_hook)
+    modify_breakpoint_hook (bpt);
 }
 
 /* ARGSUSED */
@@ -3647,7 +3693,7 @@ enable_command (args, from_tty)
     map_breakpoint_numbers (args, enable_breakpoint);
 }
 
-static void
+void
 disable_breakpoint (bpt)
      struct breakpoint *bpt;
 {
@@ -3657,12 +3703,12 @@ disable_breakpoint (bpt)
   if (bpt->type == bp_watchpoint_scope)
     return;
 
-  if (disable_breakpoint_hook)
-    disable_breakpoint_hook (bpt);
-
   bpt->enable = disabled;
 
   check_duplicates (bpt->address);
+
+  if (modify_breakpoint_hook)
+    modify_breakpoint_hook (bpt);
 }
 
 /* ARGSUSED */
@@ -3784,7 +3830,7 @@ enable_delete_breakpoint (bpt)
      struct breakpoint *bpt;
 {
   bpt->enable = enabled;
-  bpt->disposition = delete;
+  bpt->disposition = del;
 
   check_duplicates (bpt->address);
   breakpoints_changed ();
@@ -4028,39 +4074,3 @@ an expression is either read or written.");
            "Synonym for ``info breakpoints''.");
 
 }
-
-/* OK, when we call objfile_relocate, we need to relocate breakpoints
-   too.  breakpoint_re_set is not a good choice--for example, if
-   addr_string contains just a line number without a file name the
-   breakpoint might get set in a different file.  In general, there is
-   no need to go all the way back to the user's string (though this might
-   work if some effort were made to canonicalize it), since symtabs and
-   everything except addresses are still valid.
-
-   Probably the best way to solve this is to have each breakpoint save
-   the objfile and the section number that was used to set it (if set
-   by "*addr", probably it is best to use find_pc_line to get a symtab
-   and use the objfile and block_line_section for that symtab).  Then
-   objfile_relocate can call fixup_breakpoints with the objfile and
-   the new_offsets, and it can relocate only the appropriate breakpoints.  */
-
-#ifdef IBM6000_TARGET
-/* But for now, just kludge it based on the concept that before an
-   objfile is relocated the breakpoint is below 0x10000000, and afterwards
-   it is higher, so that way we only relocate each breakpoint once.  */
-
-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.031008 seconds and 4 git commands to generate.