2000-05-10 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
[deliverable/binutils-gdb.git] / gdb / breakpoint.c
index 2ad3a78a983a5f6e9eba4e261e6cdcd140dc549f..89b15909a71777579acefd89e09d28a5356f7c55 100644 (file)
@@ -918,6 +918,7 @@ insert_breakpoints ()
              b->type == bp_read_watchpoint ||
              b->type == bp_access_watchpoint)
             && b->enable == enabled
+            && b->disposition != del_at_next_stop
             && !b->inserted
             && !b->duplicate)
       {
@@ -973,24 +974,39 @@ insert_breakpoints ()
                if (VALUE_LVAL (v) == lval_memory
                    && ! VALUE_LAZY (v))
                  {
-                   CORE_ADDR addr;
-                   int len, type;
-
-                   addr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
-                   len = TYPE_LENGTH (VALUE_TYPE (v));
-                   type   = hw_write;
-                   if (b->type == bp_read_watchpoint)
-                     type = hw_read;
-                   else if (b->type == bp_access_watchpoint)
-                     type = hw_access;
-
-                   val = target_insert_watchpoint (addr, len, type);
-                   if (val == -1)
+                   struct type *vtype = check_typedef (VALUE_TYPE (v));
+
+                   /* We only watch structs and arrays if user asked
+                      for it explicitly, never if they just happen to
+                      appear in the middle of some value chain.  */
+                   if (v == b->val_chain
+                       || (TYPE_CODE (vtype) != TYPE_CODE_STRUCT
+                           && TYPE_CODE (vtype) != TYPE_CODE_ARRAY))
                      {
-                       b->inserted = 0;
-                       break;
+                       CORE_ADDR addr;
+                       int len, type;
+
+                       addr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
+                       len = TYPE_LENGTH (VALUE_TYPE (v));
+                       type   = hw_write;
+                       if (b->type == bp_read_watchpoint)
+                         type = hw_read;
+                       else if (b->type == bp_access_watchpoint)
+                         type = hw_access;
+
+                       val = target_insert_watchpoint (addr, len, type);
+                       if (val == -1)
+                         {
+                           /* Don't exit the loop, try to insert
+                              every value on the value chain.  That's
+                              because we will be removing all the
+                              watches below, and removing a
+                              watchpoint we didn't insert could have
+                              adverse effects.  */
+                           b->inserted = 0;
+                         }
+                       val = 0;
                      }
-                   val = 0;
                  }
              }
            /* Failure to insert a watchpoint on any memory value in the
@@ -1005,7 +1021,7 @@ insert_breakpoints ()
          }
        else
          {
-           printf_filtered ("Hardware watchpoint %d deleted", b->number);
+           printf_filtered ("Hardware watchpoint %d deleted ", b->number);
            printf_filtered ("because the program has left the block \n");
            printf_filtered ("in which its expression is valid.\n");
            if (b->related_breakpoint)
@@ -1016,7 +1032,7 @@ insert_breakpoints ()
        /* Restore the frame and level.  */
        if ((saved_frame != selected_frame) ||
            (saved_level != selected_frame_level))
-         select_and_print_frame (saved_frame, saved_level);
+         select_frame (saved_frame, saved_level);
 
        if (val)
          return_val = val;     /* remember failure */
@@ -1079,6 +1095,27 @@ remove_breakpoints ()
   return 0;
 }
 
+int
+remove_hw_watchpoints (void)
+{
+  register struct breakpoint *b;
+  int val;
+
+  ALL_BREAKPOINTS (b)
+  {
+    if (b->inserted
+       && (b->type == bp_hardware_watchpoint
+           || b->type == bp_read_watchpoint
+           || b->type == bp_access_watchpoint))
+      {
+       val = remove_breakpoint (b, mark_uninserted);
+       if (val != 0)
+         return val;
+      }
+  }
+  return 0;
+}
+
 int
 reattach_breakpoints (pid)
      int pid;
@@ -1326,21 +1363,28 @@ remove_breakpoint (b, is)
          if (VALUE_LVAL (v) == lval_memory
              && ! VALUE_LAZY (v))
            {
-             CORE_ADDR addr;
-             int len, type;
-
-             addr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
-             len = TYPE_LENGTH (VALUE_TYPE (v));
-             type   = hw_write;
-             if (b->type == bp_read_watchpoint)
-               type = hw_read;
-             else if (b->type == bp_access_watchpoint)
-               type = hw_access;
+             struct type *vtype = check_typedef (VALUE_TYPE (v));
 
-             val = target_remove_watchpoint (addr, len, type);
-             if (val == -1)
-               b->inserted = 1;
-             val = 0;
+             if (v == b->val_chain
+                 || (TYPE_CODE (vtype) != TYPE_CODE_STRUCT
+                     && TYPE_CODE (vtype) != TYPE_CODE_ARRAY))
+               {
+                 CORE_ADDR addr;
+                 int len, type;
+
+                 addr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
+                 len = TYPE_LENGTH (VALUE_TYPE (v));
+                 type   = hw_write;
+                 if (b->type == bp_read_watchpoint)
+                   type = hw_read;
+                 else if (b->type == bp_access_watchpoint)
+                   type = hw_access;
+
+                 val = target_remove_watchpoint (addr, len, type);
+                 if (val == -1)
+                   b->inserted = 1;
+                 val = 0;
+               }
            }
        }
       /* Failure to remove any of the hardware watchpoints comes here.  */
@@ -2570,14 +2614,21 @@ bpstat_stop_status (pc, not_a_breakpoint)
            if (VALUE_LVAL (v) == lval_memory
                && ! VALUE_LAZY (v))
              {
-               CORE_ADDR vaddr;
-
-               vaddr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
-               /* Exact match not required.  Within range is sufficient.  
-                */
-               if (addr >= vaddr &&
-                   addr < vaddr + TYPE_LENGTH (VALUE_TYPE (v)))
-                 found = 1;
+               struct type *vtype = check_typedef (VALUE_TYPE (v));
+
+               if (v == b->val_chain
+                   || (TYPE_CODE (vtype) != TYPE_CODE_STRUCT
+                       && TYPE_CODE (vtype) != TYPE_CODE_ARRAY))
+                 {
+                   CORE_ADDR vaddr;
+
+                   vaddr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
+                   /* Exact match not required.  Within range is
+                       sufficient.  */
+                   if (addr >= vaddr &&
+                       addr < vaddr + TYPE_LENGTH (VALUE_TYPE (v)))
+                     found = 1;
+                 }
              }
          }
        if (found)
@@ -2590,6 +2641,17 @@ bpstat_stop_status (pc, not_a_breakpoint)
              /* Stop.  */
              break;
            case WP_VALUE_CHANGED:
+             if (b->type == bp_read_watchpoint)
+               {
+                 /* Don't stop: read watchpoints shouldn't fire if
+                    the value has changed.  This is for targets which
+                    cannot set read-only watchpoints.  */
+                 bs->print_it = print_it_noop;
+                 bs->stop = 0;
+                 continue;
+               }
+             ++(b->hit_count);
+             break;
            case WP_VALUE_NOT_CHANGED:
              /* Stop.  */
              ++(b->hit_count);
@@ -5514,6 +5576,7 @@ can_use_hardware_watchpoint (v)
      struct value *v;
 {
   int found_memory_cnt = 0;
+  struct value *head = v;
 
   /* Did the user specifically forbid us to use hardware watchpoints? */
   if (!can_use_hw_watchpoints)
@@ -5551,13 +5614,23 @@ can_use_hardware_watchpoint (v)
            {
              /* Ahh, memory we actually used!  Check if we can cover
                  it with hardware watchpoints.  */
-             CORE_ADDR vaddr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
-             int       len   = TYPE_LENGTH (VALUE_TYPE (v));
+             struct type *vtype = check_typedef (VALUE_TYPE (v));
+
+             /* We only watch structs and arrays if user asked for it
+                explicitly, never if they just happen to appear in a
+                middle of some value chain.  */
+             if (v == head
+                 || (TYPE_CODE (vtype) != TYPE_CODE_STRUCT
+                     && TYPE_CODE (vtype) != TYPE_CODE_ARRAY))
+               {
+                 CORE_ADDR vaddr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
+                 int       len   = TYPE_LENGTH (VALUE_TYPE (v));
 
-             if (!TARGET_REGION_OK_FOR_HW_WATCHPOINT (vaddr, len))
-               return 0;
-             else
-               found_memory_cnt++;
+                 if (!TARGET_REGION_OK_FOR_HW_WATCHPOINT (vaddr, len))
+                   return 0;
+                 else
+                   found_memory_cnt++;
+               }
            }
        }
       else if (v->lval != not_lval && v->modifiable == 0)
@@ -5635,7 +5708,7 @@ until_break_command_continuation (struct continuation_arg *arg)
 {
   struct cleanup *cleanups;
 
-  cleanups = (struct cleanup *) arg->data;
+  cleanups = (struct cleanup *) arg->data.pointer;
   do_exec_cleanups (cleanups);
 }
 
@@ -5699,8 +5772,8 @@ until_break_command (arg, from_tty)
          the exec_cleanup_chain. */
       arg1 =
        (struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
-      arg1->next = NULL;
-      arg1->data = (PTR) old_chain;
+      arg1->next         = NULL;
+      arg1->data.pointer = old_chain;
 
       add_continuation (until_break_command_continuation, arg1);
     }
@@ -7536,8 +7609,7 @@ have been allocated for other watchpoints.\n", bpt->number);
        }
 
       if (save_selected_frame_level >= 0)
-       select_and_print_frame (save_selected_frame,
-                               save_selected_frame_level);
+       select_frame (save_selected_frame, save_selected_frame_level);
       value_free_to_mark (mark);
     }
   if (modify_breakpoint_hook)
This page took 0.027285 seconds and 4 git commands to generate.