]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
sh: Fix memory leak in dwarf_unwind_stack()
authorMatt Fleming <matt@console-pimps.org>
Sat, 10 Oct 2009 15:03:11 +0000 (16:03 +0100)
committerMatt Fleming <matt@console-pimps.org>
Sun, 11 Oct 2009 16:12:28 +0000 (17:12 +0100)
If we broke out of the while (1) loop because the return address of
"frame" was zero, then "frame" needs to be free'd before we return.

Signed-off-by: Matt Fleming <matt@console-pimps.org>
arch/sh/include/asm/dwarf.h
arch/sh/kernel/dwarf.c

index aacdc746d07c5fcc048c3fc647ee5f925a80e90c..eef87539963d09f5cf4d141e318b486794fd469c 100644 (file)
@@ -376,6 +376,7 @@ static inline unsigned int DW_CFA_operand(unsigned long insn)
 
 extern struct dwarf_frame *dwarf_unwind_stack(unsigned long,
                                              struct dwarf_frame *);
+extern void dwarf_free_frame(struct dwarf_frame *);
 extern int dwarf_parse_section(char *, char *, struct module *);
 extern void dwarf_module_unload(struct module *);
 
index 981315c6d656cbaaac50135904f12076d95cdc08..ce8bff45d72c5d6c74ead7f20a66b32b481f3306 100644 (file)
@@ -529,6 +529,16 @@ static int dwarf_cfa_execute_insns(unsigned char *insn_start,
        return 0;
 }
 
+/**
+ *     dwarf_free_frame - free the memory allocated for @frame
+ *     @frame: the frame to free
+ */
+void dwarf_free_frame(struct dwarf_frame *frame)
+{
+       dwarf_frame_free_regs(frame);
+       mempool_free(frame, dwarf_frame_pool);
+}
+
 /**
  *     dwarf_unwind_stack - recursively unwind the stack
  *     @pc: address of the function to unwind
@@ -649,8 +659,7 @@ struct dwarf_frame * dwarf_unwind_stack(unsigned long pc,
        return frame;
 
 bail:
-       dwarf_frame_free_regs(frame);
-       mempool_free(frame, dwarf_frame_pool);
+       dwarf_free_frame(frame);
        return NULL;
 }
 
@@ -837,10 +846,8 @@ static void dwarf_unwinder_dump(struct task_struct *task,
        while (1) {
                frame = dwarf_unwind_stack(return_addr, _frame);
 
-               if (_frame) {
-                       dwarf_frame_free_regs(_frame);
-                       mempool_free(_frame, dwarf_frame_pool);
-               }
+               if (_frame)
+                       dwarf_free_frame(_frame);
 
                _frame = frame;
 
@@ -850,6 +857,9 @@ static void dwarf_unwinder_dump(struct task_struct *task,
                return_addr = frame->return_addr;
                ops->address(data, return_addr, 1);
        }
+
+       if (frame)
+               dwarf_free_frame(frame);
 }
 
 static struct unwinder dwarf_unwinder = {