diff options
author | Matt Fleming <matt@console-pimps.org> | 2009-10-10 11:03:11 -0400 |
---|---|---|
committer | Matt Fleming <matt@console-pimps.org> | 2009-10-11 12:12:28 -0400 |
commit | ed4fe7f488008f38d5f423f0bcc736b1779d6ddc (patch) | |
tree | 9d569f812409f9738a99b6a0d398028e85512a28 /arch/sh/kernel/dwarf.c | |
parent | a6a2f2ad67506090e332f440457553c0ec011d68 (diff) |
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, | |||
530 | } | 530 | } |
531 | 531 | ||
532 | /** | 532 | /** |
533 | * dwarf_free_frame - free the memory allocated for @frame | ||
534 | * @frame: the frame to free | ||
535 | */ | ||
536 | void dwarf_free_frame(struct dwarf_frame *frame) | ||
537 | { | ||
538 | dwarf_frame_free_regs(frame); | ||
539 | mempool_free(frame, dwarf_frame_pool); | ||
540 | } | ||
541 | |||
542 | /** | ||
533 | * dwarf_unwind_stack - recursively unwind the stack | 543 | * dwarf_unwind_stack - recursively unwind the stack |
534 | * @pc: address of the function to unwind | 544 | * @pc: address of the function to unwind |
535 | * @prev: struct dwarf_frame of the previous stackframe on the callstack | 545 | * @prev: struct dwarf_frame of the previous stackframe on the callstack |
@@ -649,8 +659,7 @@ struct dwarf_frame * dwarf_unwind_stack(unsigned long pc, | |||
649 | return frame; | 659 | return frame; |
650 | 660 | ||
651 | bail: | 661 | bail: |
652 | dwarf_frame_free_regs(frame); | 662 | dwarf_free_frame(frame); |
653 | mempool_free(frame, dwarf_frame_pool); | ||
654 | return NULL; | 663 | return NULL; |
655 | } | 664 | } |
656 | 665 | ||
@@ -837,10 +846,8 @@ static void dwarf_unwinder_dump(struct task_struct *task, | |||
837 | while (1) { | 846 | while (1) { |
838 | frame = dwarf_unwind_stack(return_addr, _frame); | 847 | frame = dwarf_unwind_stack(return_addr, _frame); |
839 | 848 | ||
840 | if (_frame) { | 849 | if (_frame) |
841 | dwarf_frame_free_regs(_frame); | 850 | dwarf_free_frame(_frame); |
842 | mempool_free(_frame, dwarf_frame_pool); | ||
843 | } | ||
844 | 851 | ||
845 | _frame = frame; | 852 | _frame = frame; |
846 | 853 | ||
@@ -850,6 +857,9 @@ static void dwarf_unwinder_dump(struct task_struct *task, | |||
850 | return_addr = frame->return_addr; | 857 | return_addr = frame->return_addr; |
851 | ops->address(data, return_addr, 1); | 858 | ops->address(data, return_addr, 1); |
852 | } | 859 | } |
860 | |||
861 | if (frame) | ||
862 | dwarf_free_frame(frame); | ||
853 | } | 863 | } |
854 | 864 | ||
855 | static struct unwinder dwarf_unwinder = { | 865 | static struct unwinder dwarf_unwinder = { |