* breakpoint.c (bpstat_print): Try all elements on the bpstat
authorJim Kingdon <jkingdon@engr.sgi.com>
Mon, 22 Apr 1991 07:08:07 +0000 (07:08 +0000)
committerJim Kingdon <jkingdon@engr.sgi.com>
Mon, 22 Apr 1991 07:08:07 +0000 (07:08 +0000)
chain before giving up with an internal error.

Sun Apr 21 21:43:10 1991  Jim Kingdon  (kingdon at cygint.cygnus.com)

* value.h, values.c (value_{,free_to_}mark): New functions.
breakpoint.c (bpstat_stop_status): Use them.

gdb/ChangeLog
gdb/breakpoint.c
gdb/value.h
gdb/values.c

index 0c209bb0e2dc7a673cf04845426306078a85f4fd..4054dc36d2863657cb9861b26765c615f933dbdc 100644 (file)
@@ -1,5 +1,13 @@
+Mon Apr 22 00:02:43 1991  Jim Kingdon  (kingdon at cygint.cygnus.com)
+
+       * breakpoint.c (bpstat_print): Try all elements on the bpstat
+       chain before giving up with an internal error.
+
 Sun Apr 21 21:43:10 1991  Jim Kingdon  (kingdon at cygint.cygnus.com)
 
+       * value.h, values.c (value_{,free_to_}mark): New functions.
+       breakpoint.c (bpstat_stop_status): Use them.
+
        * tm-i386v{,-g}.h: Remove N_SET_MAGIC define.
 
 Sat Apr 20 21:42:47 1991  Jim Kingdon  (kingdon at cygint.cygnus.com)
index 4617e5d02794e8a9e29dd22d9b440042a4de6da9..e5d3c69c8d6a615441ea76d9b18326b5a3a2ee09 100644 (file)
@@ -643,6 +643,13 @@ 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;
 }
@@ -742,10 +749,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 +766,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 */
                }
index e4ac10120d514943644e6831da7c0ba6829f43e4..4afe8585c7f679445069461d17e5d641dbc5156e 100644 (file)
@@ -196,6 +196,8 @@ value read_var_value ();
 value locate_var_value ();
 value allocate_value ();
 value allocate_repeat_value ();
+value value_mark ();
+void value_free_to_mark ();
 value value_string ();
 
 value value_binop ();
index 196ea23b3712c2c5ee0cd766a82f604f290cdf59..2449da5df4ebedd19d67c9c3131ace40a24755fb 100644 (file)
@@ -111,6 +111,31 @@ allocate_repeat_value (type, count)
   return val;
 }
 
+/* Return a mark in the value chain.  All values allocated after the
+   mark is obtained (except for those released) are subject to being freed
+   if a subsequent value_free_to_mark is passed the mark.  */
+value
+value_mark ()
+{
+  return all_values;
+}
+
+/* Free all values allocated since MARK was obtained by value_mark
+   (except for those released).  */
+void
+value_free_to_mark (mark)
+     value mark;
+{
+  value val, next;
+
+  for (val = all_values; val && val != mark; val = next)
+    {
+      next = VALUE_NEXT (val);
+      value_free (val);
+    }
+  all_values = val;
+}
+
 /* Free all the values that have been allocated (except for those released).
    Called after each command, successful or not.  */