From: Tom Tromey Date: Fri, 13 May 2011 15:44:49 +0000 (+0000) Subject: * utils.c (do_value_free): New function. X-Git-Tag: sid-snapshot-20110601~208 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=72fc29ff1236177b2be5f702ed40c7d327897e7e;p=external%2Fbinutils.git * utils.c (do_value_free): New function. (make_cleanup_value_free): Likewise. * dwarf2loc.c (dwarf2_evaluate_loc_desc_full): Handle value freeing correctly. (dwarf2_loc_desc_needs_frame): Call make_cleanup_value_free_to_mark. * dwarf2expr.h (struct dwarf_expr_context) : Remove field. * dwarf2expr.c (free_dwarf_expr_context): Don't call value_free_to_mark. (new_dwarf_expr_context): Don't call value_mark. * dwarf2-frame.c (execute_stack_op): Call make_cleanup_value_free_to_mark. * defs.h (make_cleanup_value_free): Declare. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 06ff560..6c19b73 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,19 @@ +2011-05-13 Tom Tromey + + * utils.c (do_value_free): New function. + (make_cleanup_value_free): Likewise. + * dwarf2loc.c (dwarf2_evaluate_loc_desc_full): Handle value + freeing correctly. + (dwarf2_loc_desc_needs_frame): Call + make_cleanup_value_free_to_mark. + * dwarf2expr.h (struct dwarf_expr_context) : Remove field. + * dwarf2expr.c (free_dwarf_expr_context): Don't call + value_free_to_mark. + (new_dwarf_expr_context): Don't call value_mark. + * dwarf2-frame.c (execute_stack_op): Call + make_cleanup_value_free_to_mark. + * defs.h (make_cleanup_value_free): Declare. + 2011-05-13 Thiago Jung Bauermann * mi/mi-main.c (mi_cmd_execute): Use cleanup from diff --git a/gdb/defs.h b/gdb/defs.h index 771d3ad..38a2fcf 100644 --- a/gdb/defs.h +++ b/gdb/defs.h @@ -362,6 +362,7 @@ extern struct cleanup * make_cleanup_restore_ui_file (struct ui_file **variable); extern struct cleanup *make_cleanup_value_free_to_mark (struct value *); +extern struct cleanup *make_cleanup_value_free (struct value *); extern struct cleanup *make_final_cleanup (make_cleanup_ftype *, void *); diff --git a/gdb/dwarf2-frame.c b/gdb/dwarf2-frame.c index 4e4e6d9..fe48713 100644 --- a/gdb/dwarf2-frame.c +++ b/gdb/dwarf2-frame.c @@ -402,6 +402,7 @@ execute_stack_op (const gdb_byte *exp, ULONGEST len, int addr_size, ctx = new_dwarf_expr_context (); old_chain = make_cleanup_free_dwarf_expr_context (ctx); + make_cleanup_value_free_to_mark (value_mark ()); ctx->gdbarch = get_frame_arch (this_frame); ctx->addr_size = addr_size; diff --git a/gdb/dwarf2expr.c b/gdb/dwarf2expr.c index 0c0760b..b42f289 100644 --- a/gdb/dwarf2expr.c +++ b/gdb/dwarf2expr.c @@ -104,7 +104,6 @@ new_dwarf_expr_context (void) retval->num_pieces = 0; retval->pieces = 0; retval->max_recursion_depth = 0x100; - retval->mark = value_mark (); return retval; } @@ -113,7 +112,6 @@ new_dwarf_expr_context (void) void free_dwarf_expr_context (struct dwarf_expr_context *ctx) { - value_free_to_mark (ctx->mark); xfree (ctx->stack); xfree (ctx->pieces); xfree (ctx); diff --git a/gdb/dwarf2expr.h b/gdb/dwarf2expr.h index 281c65b..676b54b 100644 --- a/gdb/dwarf2expr.h +++ b/gdb/dwarf2expr.h @@ -81,10 +81,6 @@ struct dwarf_expr_context /* Offset used to relocate DW_OP_addr argument. */ CORE_ADDR offset; - /* The evaluator is value-based, and frees values up to this point - when the expression context is destroyed. */ - struct value *mark; - /* An opaque argument provided by the caller, which will be passed to all of the callback functions. */ void *baton; diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c index 04f16e9..64cc5e5 100644 --- a/gdb/dwarf2loc.c +++ b/gdb/dwarf2loc.c @@ -1086,7 +1086,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, struct value *retval; struct dwarf_expr_baton baton; struct dwarf_expr_context *ctx; - struct cleanup *old_chain; + struct cleanup *old_chain, *value_chain; struct objfile *objfile = dwarf2_per_cu_objfile (per_cu); volatile struct gdb_exception ex; @@ -1106,6 +1106,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, ctx = new_dwarf_expr_context (); old_chain = make_cleanup_free_dwarf_expr_context (ctx); + value_chain = make_cleanup_value_free_to_mark (value_mark ()); ctx->gdbarch = get_objfile_arch (objfile); ctx->addr_size = dwarf2_per_cu_addr_size (per_cu); @@ -1128,6 +1129,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, { if (ex.error == NOT_AVAILABLE_ERROR) { + do_cleanups (old_chain); retval = allocate_value (type); mark_value_bytes_unavailable (retval, 0, TYPE_LENGTH (type)); return retval; @@ -1150,6 +1152,9 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, c = allocate_piece_closure (per_cu, ctx->num_pieces, ctx->pieces, ctx->addr_size); + /* We must clean up the value chain after creating the piece + closure but before allocating the result. */ + do_cleanups (value_chain); retval = allocate_computed_value (type, &pieced_value_funcs, c); VALUE_FRAME_ID (retval) = frame_id; set_value_offset (retval, byte_offset); @@ -1166,6 +1171,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, if (byte_offset != 0) error (_("cannot use offset on synthetic pointer to register")); + do_cleanups (value_chain); if (gdb_regnum != -1) retval = value_from_register (type, gdb_regnum, frame); else @@ -1179,6 +1185,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, CORE_ADDR address = dwarf_expr_fetch_address (ctx, 0); int in_stack_memory = dwarf_expr_fetch_in_stack_memory (ctx, 0); + do_cleanups (value_chain); retval = allocate_value_lazy (type); VALUE_LVAL (retval) = lval_memory; if (in_stack_memory) @@ -1201,6 +1208,13 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, val_bytes += byte_offset; n -= byte_offset; + /* Preserve VALUE because we are going to free values back + to the mark, but we still need the value contents + below. */ + value_incref (value); + do_cleanups (value_chain); + make_cleanup_value_free (value); + retval = allocate_value (type); contents = value_contents_raw (retval); if (n > TYPE_LENGTH (type)) @@ -1218,6 +1232,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, if (byte_offset + TYPE_LENGTH (type) > n) invalid_synthetic_pointer (); + do_cleanups (value_chain); retval = allocate_value (type); contents = value_contents_raw (retval); @@ -1231,6 +1246,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, break; case DWARF_VALUE_OPTIMIZED_OUT: + do_cleanups (value_chain); retval = allocate_value (type); VALUE_LVAL (retval) = not_lval; set_value_optimized_out (retval, 1); @@ -1353,6 +1369,7 @@ dwarf2_loc_desc_needs_frame (const gdb_byte *data, unsigned short size, ctx = new_dwarf_expr_context (); old_chain = make_cleanup_free_dwarf_expr_context (ctx); + make_cleanup_value_free_to_mark (value_mark ()); ctx->gdbarch = get_objfile_arch (objfile); ctx->addr_size = dwarf2_per_cu_addr_size (per_cu); diff --git a/gdb/utils.c b/gdb/utils.c index 3e4a54d..6fd220a 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -448,6 +448,22 @@ make_cleanup_value_free_to_mark (struct value *mark) return make_my_cleanup (&cleanup_chain, do_value_free_to_mark, mark); } +/* Helper for make_cleanup_value_free. */ + +static void +do_value_free (void *value) +{ + value_free (value); +} + +/* Free VALUE. */ + +struct cleanup * +make_cleanup_value_free (struct value *value) +{ + return make_my_cleanup (&cleanup_chain, do_value_free, value); +} + struct cleanup * make_my_cleanup2 (struct cleanup **pmy_chain, make_cleanup_ftype *function, void *arg, void (*free_arg) (void *))