Avoid NULL dereference.
[deliverable/binutils-gdb.git] / gdb / breakpoint.c
index 18d80106193e1e27aaa76ee342b821e78e66cdb4..0caedec92ff35edb39f41887132f59e2c64e1a58 100644 (file)
@@ -835,8 +835,8 @@ fetch_watchpoint_value (struct expression *exp, struct value **valp,
      in b->loc->cond.
    - Update the list of values that must be watched in B->loc.
 
-   If the watchpoint is disabled, do nothing.  If this is
-   local watchpoint that is out of scope, delete it.  */
+   If the watchpoint disposition is disp_del_at_next_stop, then do nothing.
+   If this is local watchpoint that is out of scope, delete it.  */
 static void
 update_watchpoint (struct breakpoint *b, int reparse)
 {
@@ -1278,7 +1278,7 @@ insert_breakpoint_locations (void)
   int hw_breakpoint_error = 0;
 
   struct ui_file *tmp_error_stream = mem_fileopen ();
-  make_cleanup_ui_file_delete (tmp_error_stream);
+  struct cleanup *cleanups = make_cleanup_ui_file_delete (tmp_error_stream);
   
   /* Explicitly mark the warning -- this will only be printed if
      there was an error.  */
@@ -1351,6 +1351,8 @@ You may have requested too many hardware breakpoints/watchpoints.\n");
       target_terminal_ours_for_output ();
       error_stream (tmp_error_stream);
     }
+
+  do_cleanups (cleanups);
 }
 
 int
@@ -2232,13 +2234,13 @@ watchpoint_value_print (struct value *val, struct ui_file *stream)
 static enum print_stop_action
 print_it_typical (bpstat bs)
 {
-  struct cleanup *old_chain, *ui_out_chain;
+  struct cleanup *old_chain;
   struct breakpoint *b;
   const struct bp_location *bl;
   struct ui_stream *stb;
-  int bp_temp = 0;  
-  stb = ui_out_stream_new (uiout);
-  old_chain = make_cleanup_ui_out_stream_delete (stb);
+  int bp_temp = 0;
+  enum print_stop_action result;
+
   /* bs->breakpoint_at can be NULL if it was a momentary breakpoint
      which has since been deleted.  */
   if (bs->breakpoint_at == NULL)
@@ -2246,6 +2248,9 @@ print_it_typical (bpstat bs)
   bl = bs->breakpoint_at;
   b = bl->owner;
 
+  stb = ui_out_stream_new (uiout);
+  old_chain = make_cleanup_ui_out_stream_delete (stb);
+
   switch (b->type)
     {
     case bp_breakpoint:
@@ -2268,7 +2273,7 @@ print_it_typical (bpstat bs)
        }
       ui_out_field_int (uiout, "bkptno", b->number);
       ui_out_text (uiout, ", ");
-      return PRINT_SRC_AND_LOC;
+      result = PRINT_SRC_AND_LOC;
       break;
 
     case bp_shlib_event:
@@ -2276,20 +2281,20 @@ print_it_typical (bpstat bs)
         variable?  (If so, we report this as a generic, "Stopped due
         to shlib event" message.) */
       printf_filtered (_("Stopped due to shared library event\n"));
-      return PRINT_NOTHING;
+      result = PRINT_NOTHING;
       break;
 
     case bp_thread_event:
       /* Not sure how we will get here. 
         GDB should not stop for these breakpoints.  */
       printf_filtered (_("Thread Event Breakpoint: gdb should not stop!\n"));
-      return PRINT_NOTHING;
+      result = PRINT_NOTHING;
       break;
 
     case bp_overlay_event:
       /* By analogy with the thread event, GDB should not stop for these. */
       printf_filtered (_("Overlay Event Breakpoint: gdb should not stop!\n"));
-      return PRINT_NOTHING;
+      result = PRINT_NOTHING;
       break;
 
     case bp_watchpoint:
@@ -2300,17 +2305,16 @@ print_it_typical (bpstat bs)
          (uiout, "reason",
           async_reason_lookup (EXEC_ASYNC_WATCHPOINT_TRIGGER));
       mention (b);
-      ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "value");
+      make_cleanup_ui_out_tuple_begin_end (uiout, "value");
       ui_out_text (uiout, "\nOld value = ");
       watchpoint_value_print (bs->old_val, stb->stream);
       ui_out_field_stream (uiout, "old", stb);
       ui_out_text (uiout, "\nNew value = ");
       watchpoint_value_print (b->val, stb->stream);
       ui_out_field_stream (uiout, "new", stb);
-      do_cleanups (ui_out_chain);
       ui_out_text (uiout, "\n");
       /* More than one watchpoint may have been triggered.  */
-      return PRINT_UNKNOWN;
+      result = PRINT_UNKNOWN;
       break;
 
     case bp_read_watchpoint:
@@ -2319,13 +2323,12 @@ print_it_typical (bpstat bs)
          (uiout, "reason",
           async_reason_lookup (EXEC_ASYNC_READ_WATCHPOINT_TRIGGER));
       mention (b);
-      ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "value");
+      make_cleanup_ui_out_tuple_begin_end (uiout, "value");
       ui_out_text (uiout, "\nValue = ");
       watchpoint_value_print (b->val, stb->stream);
       ui_out_field_stream (uiout, "value", stb);
-      do_cleanups (ui_out_chain);
       ui_out_text (uiout, "\n");
-      return PRINT_UNKNOWN;
+      result = PRINT_UNKNOWN;
       break;
 
     case bp_access_watchpoint:
@@ -2337,7 +2340,7 @@ print_it_typical (bpstat bs)
              (uiout, "reason",
               async_reason_lookup (EXEC_ASYNC_ACCESS_WATCHPOINT_TRIGGER));
          mention (b);
-         ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "value");
+         make_cleanup_ui_out_tuple_begin_end (uiout, "value");
          ui_out_text (uiout, "\nOld value = ");
          watchpoint_value_print (bs->old_val, stb->stream);
          ui_out_field_stream (uiout, "old", stb);
@@ -2350,14 +2353,13 @@ print_it_typical (bpstat bs)
            ui_out_field_string
              (uiout, "reason",
               async_reason_lookup (EXEC_ASYNC_ACCESS_WATCHPOINT_TRIGGER));
-         ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "value");
+         make_cleanup_ui_out_tuple_begin_end (uiout, "value");
          ui_out_text (uiout, "\nValue = ");
        }
       watchpoint_value_print (b->val, stb->stream);
       ui_out_field_stream (uiout, "new", stb);
-      do_cleanups (ui_out_chain);
       ui_out_text (uiout, "\n");
-      return PRINT_UNKNOWN;
+      result = PRINT_UNKNOWN;
       break;
 
     /* Fall through, we don't deal with these types of breakpoints
@@ -2368,7 +2370,7 @@ print_it_typical (bpstat bs)
        ui_out_field_string
          (uiout, "reason",
           async_reason_lookup (EXEC_ASYNC_FUNCTION_FINISHED));
-      return PRINT_UNKNOWN;
+      result = PRINT_UNKNOWN;
       break;
 
     case bp_until:
@@ -2376,7 +2378,7 @@ print_it_typical (bpstat bs)
        ui_out_field_string
          (uiout, "reason",
           async_reason_lookup (EXEC_ASYNC_LOCATION_REACHED));
-      return PRINT_UNKNOWN;
+      result = PRINT_UNKNOWN;
       break;
 
     case bp_none:
@@ -2386,8 +2388,12 @@ print_it_typical (bpstat bs)
     case bp_watchpoint_scope:
     case bp_call_dummy:
     default:
-      return PRINT_UNKNOWN;
+      result = PRINT_UNKNOWN;
+      break;
     }
+
+  do_cleanups (old_chain);
+  return result;
 }
 
 /* Generic routine for printing messages indicating why we
@@ -3485,8 +3491,7 @@ print_one_breakpoint_location (struct breakpoint *b,
        if (opts.addressprint)
          ui_out_field_skip (uiout, "addr");
        annotate_field (5);
-       print_expression (b->exp, stb->stream);
-       ui_out_field_stream (uiout, "what", stb);
+       ui_out_field_string (uiout, "what", b->exp_string);
        break;
 
       case bp_breakpoint:
@@ -4884,15 +4889,11 @@ static void
 mention (struct breakpoint *b)
 {
   int say_where = 0;
-  struct cleanup *old_chain, *ui_out_chain;
-  struct ui_stream *stb;
+  struct cleanup *ui_out_chain;
   struct value_print_options opts;
 
   get_user_print_options (&opts);
 
-  stb = ui_out_stream_new (uiout);
-  old_chain = make_cleanup_ui_out_stream_delete (stb);
-
   /* FIXME: This is misplaced; mention() is called by things (like
      hitting a watchpoint) other than breakpoint creation.  It should
      be possible to clean this up and at the same time replace the
@@ -4912,8 +4913,7 @@ mention (struct breakpoint *b)
        ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "wpt");
        ui_out_field_int (uiout, "number", b->number);
        ui_out_text (uiout, ": ");
-       print_expression (b->exp, stb->stream);
-       ui_out_field_stream (uiout, "exp", stb);
+       ui_out_field_string (uiout, "exp", b->exp_string);
        do_cleanups (ui_out_chain);
        break;
       case bp_hardware_watchpoint:
@@ -4921,8 +4921,7 @@ mention (struct breakpoint *b)
        ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "wpt");
        ui_out_field_int (uiout, "number", b->number);
        ui_out_text (uiout, ": ");
-       print_expression (b->exp, stb->stream);
-       ui_out_field_stream (uiout, "exp", stb);
+       ui_out_field_string (uiout, "exp", b->exp_string);
        do_cleanups (ui_out_chain);
        break;
       case bp_read_watchpoint:
@@ -4930,8 +4929,7 @@ mention (struct breakpoint *b)
        ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "hw-rwpt");
        ui_out_field_int (uiout, "number", b->number);
        ui_out_text (uiout, ": ");
-       print_expression (b->exp, stb->stream);
-       ui_out_field_stream (uiout, "exp", stb);
+       ui_out_field_string (uiout, "exp", b->exp_string);
        do_cleanups (ui_out_chain);
        break;
       case bp_access_watchpoint:
@@ -4939,8 +4937,7 @@ mention (struct breakpoint *b)
        ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "hw-awpt");
        ui_out_field_int (uiout, "number", b->number);
        ui_out_text (uiout, ": ");
-       print_expression (b->exp, stb->stream);
-       ui_out_field_stream (uiout, "exp", stb);
+       ui_out_field_string (uiout, "exp", b->exp_string);
        do_cleanups (ui_out_chain);
        break;
       case bp_breakpoint:
@@ -5009,7 +5006,6 @@ mention (struct breakpoint *b)
 
        }
     }
-  do_cleanups (old_chain);
   if (ui_out_is_mi_like_p (uiout))
     return;
   printf_filtered ("\n");
@@ -5084,7 +5080,7 @@ create_breakpoint (struct symtabs_and_lines sals, char *addr_string,
                   char *cond_string,
                   enum bptype type, enum bpdisp disposition,
                   int thread, int ignore_count, 
-                  struct breakpoint_ops *ops, int from_tty)
+                  struct breakpoint_ops *ops, int from_tty, int enabled)
 {
   struct breakpoint *b = NULL;
   int i;
@@ -5118,7 +5114,7 @@ create_breakpoint (struct symtabs_and_lines sals, char *addr_string,
   
          b->cond_string = cond_string;
          b->ignore_count = ignore_count;
-         b->enable_state = bp_enabled;
+         b->enable_state = enabled ? bp_enabled : bp_disabled;
          b->disposition = disposition;
 
          loc = b->loc;
@@ -5293,7 +5289,8 @@ create_breakpoints (struct symtabs_and_lines sals, char **addr_string,
                    char *cond_string,
                    enum bptype type, enum bpdisp disposition,
                    int thread, int ignore_count, 
-                   struct breakpoint_ops *ops, int from_tty)
+                   struct breakpoint_ops *ops, int from_tty,
+                   int enabled)
 {
   int i;
   for (i = 0; i < sals.nelts; ++i)
@@ -5303,7 +5300,7 @@ create_breakpoints (struct symtabs_and_lines sals, char **addr_string,
 
       create_breakpoint (expanded, addr_string[i],
                         cond_string, type, disposition,
-                        thread, ignore_count, ops, from_tty);
+                        thread, ignore_count, ops, from_tty, enabled);
     }
 
   update_global_location_list (1);
@@ -5432,8 +5429,11 @@ find_condition_and_thread (char *tok, CORE_ADDR pc,
       
       if (toklen >= 1 && strncmp (tok, "if", toklen) == 0)
        {
+         struct expression *expr;
+
          tok = cond_start = end_tok + 1;
-         parse_exp_1 (&tok, block_for_pc (pc), 0);
+         expr = parse_exp_1 (&tok, block_for_pc (pc), 0);
+         xfree (expr);
          cond_end = tok;
          *cond_string = savestring (cond_start, 
                                     cond_end - cond_start);
@@ -5472,7 +5472,8 @@ break_command_really (char *arg, char *cond_string, int thread,
                      int ignore_count,
                      enum auto_boolean pending_break_support,
                      struct breakpoint_ops *ops,
-                     int from_tty)
+                     int from_tty,
+                     int enabled)
 {
   struct gdb_exception e;
   struct symtabs_and_lines sals;
@@ -5605,7 +5606,7 @@ break_command_really (char *arg, char *cond_string, int thread,
                          hardwareflag ? bp_hardware_breakpoint 
                          : bp_breakpoint,
                          tempflag ? disp_del : disp_donttouch,
-                         thread, ignore_count, ops, from_tty);
+                         thread, ignore_count, ops, from_tty, enabled);
     }
   else
     {
@@ -5626,6 +5627,7 @@ break_command_really (char *arg, char *cond_string, int thread,
       b->disposition = tempflag ? disp_del : disp_donttouch;
       b->condition_not_parsed = 1;
       b->ops = ops;
+      b->enable_state = enabled ? bp_enabled : bp_disabled;
 
       update_global_location_list (1);
       mention (b);
@@ -5660,7 +5662,8 @@ break_command_1 (char *arg, int flag, int from_tty)
                        0 /* Ignore count */,
                        pending_break_support, 
                        NULL /* breakpoint_ops */,
-                       from_tty);
+                       from_tty,
+                       1 /* enabled */);
 }
 
 
@@ -5668,7 +5671,7 @@ void
 set_breakpoint (char *address, char *condition,
                int hardwareflag, int tempflag,
                int thread, int ignore_count,
-               int pending)
+               int pending, int enabled)
 {
   break_command_really (address, condition, thread,
                        0 /* condition and thread are valid.  */,
@@ -5676,7 +5679,7 @@ set_breakpoint (char *address, char *condition,
                        ignore_count,
                        pending 
                        ? AUTO_BOOLEAN_TRUE : AUTO_BOOLEAN_FALSE,
-                       NULL, 0);
+                       NULL, 0, enabled);
 }
 
 /* Adjust SAL to the first instruction past the function prologue.
@@ -5941,6 +5944,12 @@ watch_command_1 (char *arg, int accessflag, int from_tty)
   exp_start = arg;
   exp = parse_exp_1 (&arg, 0, 0);
   exp_end = arg;
+  /* Remove trailing whitespace from the expression before saving it.
+     This makes the eventual display of the expression string a bit
+     prettier.  */
+  while (exp_end > exp_start && (exp_end[-1] == ' ' || exp_end[-1] == '\t'))
+    --exp_end;
+
   exp_valid_block = innermost_block;
   mark = value_mark ();
   fetch_watchpoint_value (exp, &val, NULL, NULL);
@@ -6527,7 +6536,8 @@ handle_gnu_v3_exceptions (int tempflag, char *cond_string,
                        tempflag, 0,
                        0,
                        AUTO_BOOLEAN_TRUE /* pending */,
-                       &gnu_v3_exception_catchpoint_ops, from_tty);
+                       &gnu_v3_exception_catchpoint_ops, from_tty,
+                       1 /* enabled */);
 
   return 1;
 }
@@ -6846,6 +6856,16 @@ breakpoint_auto_delete (bpstat bs)
   }
 }
 
+/* A cleanup function which destroys a vector.  */
+
+static void
+do_vec_free (void *p)
+{
+  VEC(bp_location_p) **vec = p;
+  if (*vec)
+    VEC_free (bp_location_p, *vec);
+}
+
 /* If SHOULD_INSERT is false, do not insert any breakpoint locations
    into the inferior, only remove already-inserted locations that no
    longer should be inserted.  Functions that delete a breakpoint or
@@ -6868,11 +6888,12 @@ update_global_location_list (int should_insert)
   struct bp_location **next = &bp_location_chain;
   struct bp_location *loc;
   struct bp_location *loc2;
-  struct gdb_exception e;
   VEC(bp_location_p) *old_locations = NULL;
   int ret;
   int ix;
-  
+  struct cleanup *cleanups;
+
+  cleanups = make_cleanup (do_vec_free, &old_locations);
   /* Store old locations for future reference.  */
   for (loc = bp_location_chain; loc; loc = loc->global_next)
     VEC_safe_push (bp_location_p, old_locations, loc);
@@ -7001,6 +7022,8 @@ update_global_location_list (int should_insert)
          || (gdbarch_has_global_solist (target_gdbarch)
              && target_supports_multi_process ())))
     insert_breakpoint_locations ();
+
+  do_cleanups (cleanups);
 }
 
 void
@@ -7360,7 +7383,7 @@ breakpoint_re_set_one (void *bint)
   char *s;
   enum enable_state save_enable;
   struct gdb_exception e;
-
+  struct cleanup *cleanups;
 
   switch (b->type)
     {
@@ -7430,9 +7453,9 @@ breakpoint_re_set_one (void *bint)
          b->condition_not_parsed = 0;
        }
       expanded = expand_line_sal_maybe (sals.sals[0]);
+      cleanups = make_cleanup (xfree, sals.sals);
       update_breakpoint_locations (b, expanded);
-
-      xfree (sals.sals);
+      do_cleanups (cleanups);
       break;
 
     case bp_watchpoint:
@@ -7780,56 +7803,18 @@ do_enable_breakpoint (struct breakpoint *bpt, enum bpdisp disposition)
       bpt->type == bp_read_watchpoint || 
       bpt->type == bp_access_watchpoint)
     {
-      struct frame_id saved_frame_id;
-      
-      saved_frame_id = get_frame_id (get_selected_frame (NULL));
-      if (bpt->exp_valid_block != NULL)
+      struct gdb_exception e;
+
+      TRY_CATCH (e, RETURN_MASK_ALL)
        {
-         struct frame_info *fr =
-           fr = frame_find_by_id (bpt->watchpoint_frame);
-         if (fr == NULL)
-           {
-             printf_filtered (_("\
-Cannot enable watchpoint %d because the block in which its expression\n\
-is valid is not currently in scope.\n"), bpt->number);
-             return;
-           }
-         select_frame (fr);
+         update_watchpoint (bpt, 1 /* reparse */);
        }
-      
-      if (bpt->val)
-       value_free (bpt->val);
-      mark = value_mark ();
-      fetch_watchpoint_value (bpt->exp, &bpt->val, NULL, NULL);
-      if (bpt->val)
-       release_value (bpt->val);
-      bpt->val_valid = 1;
-
-      if (bpt->type == bp_hardware_watchpoint ||
-         bpt->type == bp_read_watchpoint ||
-         bpt->type == bp_access_watchpoint)
+      if (e.reason < 0)
        {
-         int i = hw_watchpoint_used_count (bpt->type, &other_type_used);
-         int mem_cnt = can_use_hardware_watchpoint (bpt->val);
-         
-         /* Hack around 'unused var' error for some targets here */
-         (void) mem_cnt, (void) i;
-         target_resources_ok = TARGET_CAN_USE_HARDWARE_WATCHPOINT (
-                                                                   bpt->type, i + mem_cnt, other_type_used);
-         /* we can consider of type is bp_hardware_watchpoint, convert to 
-            bp_watchpoint in the following condition */
-         if (target_resources_ok < 0)
-           {
-             printf_filtered (_("\
-Cannot enable watchpoint %d because target watch resources\n\
-have been allocated for other watchpoints.\n"), bpt->number);
-             value_free_to_mark (mark);
-             return;
-           }
+         exception_fprintf (gdb_stderr, e, _("Cannot enable watchpoint %d: "),
+                            bpt->number);
+         return;
        }
-      
-      select_frame (frame_find_by_id (saved_frame_id));
-      value_free_to_mark (mark);
     }
 
   if (bpt->enable_state != bp_permanent)
This page took 0.030587 seconds and 4 git commands to generate.