diff options
author | Matt Fleming <matt@console-pimps.org> | 2009-10-10 17:03:11 +0200 |
---|---|---|
committer | Matt Fleming <matt@console-pimps.org> | 2009-10-11 18:12:28 +0200 |
commit | ed4fe7f488008f38d5f423f0bcc736b1779d6ddc (patch) | |
tree | 9d569f812409f9738a99b6a0d398028e85512a28 /arch/sh/kernel/dwarf.c | |
parent | sh: Teach the DWARF unwinder about modules (diff) | |
download | linux-ed4fe7f488008f38d5f423f0bcc736b1779d6ddc.tar.xz linux-ed4fe7f488008f38d5f423f0bcc736b1779d6ddc.zip |
sh: Fix memory leak in dwarf_unwind_stack()
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>
Diffstat (limited to 'arch/sh/kernel/dwarf.c')
-rw-r--r-- | arch/sh/kernel/dwarf.c | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/arch/sh/kernel/dwarf.c b/arch/sh/kernel/dwarf.c index 981315c6d656..ce8bff45d72c 100644 --- a/arch/sh/kernel/dwarf.c +++ b/arch/sh/kernel/dwarf.c @@ -530,6 +530,16 @@ static int dwarf_cfa_execute_insns(unsigned char *insn_start, } /** + * 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 * @prev: struct dwarf_frame of the previous stackframe on the callstack @@ -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 = { |