Skip to content

Commit

Permalink
sh: Fix memory leak in dwarf_unwind_stack()
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Matt Fleming committed Oct 11, 2009
1 parent a6a2f2a commit ed4fe7f
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 6 deletions.
1 change: 1 addition & 0 deletions arch/sh/include/asm/dwarf.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 *);

Expand Down
22 changes: 16 additions & 6 deletions arch/sh/kernel/dwarf.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;

Expand All @@ -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 = {
Expand Down

0 comments on commit ed4fe7f

Please sign in to comment.