From fcb887ffcd896af0b53c7ac8808bfeed54b321e8 Mon Sep 17 00:00:00 2001 From: Jim Kingdon Date: Mon, 22 Apr 1991 07:08:07 +0000 Subject: [PATCH] * 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. --- gdb/ChangeLog | 8 ++++++++ gdb/breakpoint.c | 17 +++++++++++++++-- gdb/value.h | 2 ++ gdb/values.c | 25 +++++++++++++++++++++++++ 4 files changed, 50 insertions(+), 2 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 0c209bb0e2d..4054dc36d28 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -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) diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 4617e5d0279..e5d3c69c8d6 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -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 */ } diff --git a/gdb/value.h b/gdb/value.h index e4ac10120d5..4afe8585c7f 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -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 (); diff --git a/gdb/values.c b/gdb/values.c index 196ea23b371..2449da5df4e 100644 --- a/gdb/values.c +++ b/gdb/values.c @@ -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. */ -- 2.30.2