This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
FYI: fix possible memory leak in dwarf expression evaluation
- From: Tom Tromey <tromey at redhat dot com>
- To: gdb-patches at sourceware dot org
- Date: Tue, 11 Aug 2009 14:36:37 -0600
- Subject: FYI: fix possible memory leak in dwarf expression evaluation
- Reply-to: tromey at redhat dot com
I'm checking this in.
If evaluation of a dwarf expression causes a call to error(), the dwarf
expression context will be leaked. I found this by reading the code.
The fix is to install a cleanup that destroys the context.
Built and regtested on x86-64 (compile farm).
Tom
2009-08-11 Tom Tromey <tromey@redhat.com>
* dwarf2loc.c (dwarf2_evaluate_loc_desc): Make a cleanup.
(dwarf2_loc_desc_needs_frame): Likewise.
* dwarf2expr.h (make_cleanup_free_dwarf_expr_context): Declare.
* dwarf2expr.c (free_dwarf_expr_context_cleanup): New function.
(make_cleanup_free_dwarf_expr_context): Likewise.
* dwarf2-frame.c (execute_stack_op): Make a cleanup.
Index: dwarf2-frame.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2-frame.c,v
retrieving revision 1.95
diff -u -r1.95 dwarf2-frame.c
--- dwarf2-frame.c 6 Aug 2009 23:25:49 -0000 1.95
+++ dwarf2-frame.c 11 Aug 2009 20:35:54 -0000
@@ -352,8 +352,11 @@
{
struct dwarf_expr_context *ctx;
CORE_ADDR result;
+ struct cleanup *old_chain;
ctx = new_dwarf_expr_context ();
+ old_chain = make_cleanup_free_dwarf_expr_context (ctx);
+
ctx->gdbarch = get_frame_arch (this_frame);
ctx->addr_size = addr_size;
ctx->baton = this_frame;
@@ -369,7 +372,7 @@
if (ctx->in_reg)
result = read_reg (this_frame, result);
- free_dwarf_expr_context (ctx);
+ do_cleanups (old_chain);
return result;
}
Index: dwarf2expr.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2expr.c,v
retrieving revision 1.33
diff -u -r1.33 dwarf2expr.c
--- dwarf2expr.c 10 Jul 2009 15:27:02 -0000 1.33
+++ dwarf2expr.c 11 Aug 2009 20:35:54 -0000
@@ -61,6 +61,22 @@
xfree (ctx);
}
+/* Helper for make_cleanup_free_dwarf_expr_context. */
+
+static void
+free_dwarf_expr_context_cleanup (void *arg)
+{
+ free_dwarf_expr_context (arg);
+}
+
+/* Return a cleanup that calls free_dwarf_expr_context. */
+
+struct cleanup *
+make_cleanup_free_dwarf_expr_context (struct dwarf_expr_context *ctx)
+{
+ return make_cleanup (free_dwarf_expr_context_cleanup, ctx);
+}
+
/* Expand the memory allocated to CTX's stack to contain at least
NEED more elements than are currently used. */
Index: dwarf2expr.h
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2expr.h,v
retrieving revision 1.15
diff -u -r1.15 dwarf2expr.h
--- dwarf2expr.h 3 Jan 2009 05:57:51 -0000 1.15
+++ dwarf2expr.h 11 Aug 2009 20:35:54 -0000
@@ -131,6 +131,8 @@
struct dwarf_expr_context *new_dwarf_expr_context (void);
void free_dwarf_expr_context (struct dwarf_expr_context *ctx);
+struct cleanup *
+ make_cleanup_free_dwarf_expr_context (struct dwarf_expr_context *ctx);
void dwarf_expr_push (struct dwarf_expr_context *ctx, CORE_ADDR value);
void dwarf_expr_pop (struct dwarf_expr_context *ctx);
Index: dwarf2loc.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2loc.c,v
retrieving revision 1.62
diff -u -r1.62 dwarf2loc.c
--- dwarf2loc.c 20 Jul 2009 15:06:13 -0000 1.62
+++ dwarf2loc.c 11 Aug 2009 20:35:54 -0000
@@ -215,6 +215,7 @@
struct value *retval;
struct dwarf_expr_baton baton;
struct dwarf_expr_context *ctx;
+ struct cleanup *old_chain;
if (size == 0)
{
@@ -228,6 +229,8 @@
baton.objfile = dwarf2_per_cu_objfile (per_cu);
ctx = new_dwarf_expr_context ();
+ old_chain = make_cleanup_free_dwarf_expr_context (ctx);
+
ctx->gdbarch = get_objfile_arch (baton.objfile);
ctx->addr_size = dwarf2_per_cu_addr_size (per_cu);
ctx->baton = &baton;
@@ -282,7 +285,7 @@
set_value_initialized (retval, ctx->initialized);
- free_dwarf_expr_context (ctx);
+ do_cleanups (old_chain);
return retval;
}
@@ -346,10 +349,13 @@
struct needs_frame_baton baton;
struct dwarf_expr_context *ctx;
int in_reg;
+ struct cleanup *old_chain;
baton.needs_frame = 0;
ctx = new_dwarf_expr_context ();
+ old_chain = make_cleanup_free_dwarf_expr_context (ctx);
+
ctx->gdbarch = get_objfile_arch (dwarf2_per_cu_objfile (per_cu));
ctx->addr_size = dwarf2_per_cu_addr_size (per_cu);
ctx->baton = &baton;
@@ -373,7 +379,7 @@
in_reg = 1;
}
- free_dwarf_expr_context (ctx);
+ do_cleanups (old_chain);
return baton.needs_frame || in_reg;
}