forked from luck/tmp_suning_uos_patched
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>
This commit is contained in:
parent
a6a2f2ad67
commit
ed4fe7f488
@ -376,6 +376,7 @@ static inline unsigned int DW_CFA_operand(unsigned long insn)
|
|||||||
|
|
||||||
extern struct dwarf_frame *dwarf_unwind_stack(unsigned long,
|
extern struct dwarf_frame *dwarf_unwind_stack(unsigned long,
|
||||||
struct dwarf_frame *);
|
struct dwarf_frame *);
|
||||||
|
extern void dwarf_free_frame(struct dwarf_frame *);
|
||||||
extern int dwarf_parse_section(char *, char *, struct module *);
|
extern int dwarf_parse_section(char *, char *, struct module *);
|
||||||
extern void dwarf_module_unload(struct module *);
|
extern void dwarf_module_unload(struct module *);
|
||||||
|
|
||||||
|
@ -529,6 +529,16 @@ static int dwarf_cfa_execute_insns(unsigned char *insn_start,
|
|||||||
return 0;
|
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
|
* dwarf_unwind_stack - recursively unwind the stack
|
||||||
* @pc: address of the function to unwind
|
* @pc: address of the function to unwind
|
||||||
@ -649,8 +659,7 @@ struct dwarf_frame * dwarf_unwind_stack(unsigned long pc,
|
|||||||
return frame;
|
return frame;
|
||||||
|
|
||||||
bail:
|
bail:
|
||||||
dwarf_frame_free_regs(frame);
|
dwarf_free_frame(frame);
|
||||||
mempool_free(frame, dwarf_frame_pool);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -837,10 +846,8 @@ static void dwarf_unwinder_dump(struct task_struct *task,
|
|||||||
while (1) {
|
while (1) {
|
||||||
frame = dwarf_unwind_stack(return_addr, _frame);
|
frame = dwarf_unwind_stack(return_addr, _frame);
|
||||||
|
|
||||||
if (_frame) {
|
if (_frame)
|
||||||
dwarf_frame_free_regs(_frame);
|
dwarf_free_frame(_frame);
|
||||||
mempool_free(_frame, dwarf_frame_pool);
|
|
||||||
}
|
|
||||||
|
|
||||||
_frame = frame;
|
_frame = frame;
|
||||||
|
|
||||||
@ -850,6 +857,9 @@ static void dwarf_unwinder_dump(struct task_struct *task,
|
|||||||
return_addr = frame->return_addr;
|
return_addr = frame->return_addr;
|
||||||
ops->address(data, return_addr, 1);
|
ops->address(data, return_addr, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (frame)
|
||||||
|
dwarf_free_frame(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct unwinder dwarf_unwinder = {
|
static struct unwinder dwarf_unwinder = {
|
||||||
|
Loading…
Reference in New Issue
Block a user