summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog16
-rw-r--r--gdb/defs.h1
-rw-r--r--gdb/dwarf2-frame.c1
-rw-r--r--gdb/dwarf2expr.c2
-rw-r--r--gdb/dwarf2expr.h4
-rw-r--r--gdb/dwarf2loc.c19
-rw-r--r--gdb/utils.c16
7 files changed, 52 insertions, 7 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 06ff560b775..6c19b73371e 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,19 @@
+2011-05-13 Tom Tromey <tromey@redhat.com>
+
+ * 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) <mark>: 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 <bauerman@br.ibm.com>
* mi/mi-main.c (mi_cmd_execute): Use cleanup from
diff --git a/gdb/defs.h b/gdb/defs.h
index 771d3ade8fe..38a2fcf98c0 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 4e4e6d97e5f..fe48713d245 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 0c0760b038c..b42f28914bb 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 281c65b472c..676b54bfff2 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 04f16e9780e..64cc5e553c8 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 3e4a54dfcfe..6fd220a6059 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 *))