@@ -921,6 +921,33 @@ static int __init allocate_overflow_stacks(void)
}
early_initcall(allocate_overflow_stacks);
+static void dump_stack_usage(struct pt_regs *regs)
+{
+ struct stackframe frame;
+ unsigned int depth = 0;
+ unsigned long prev_pc;
+ unsigned long prev_sp;
+ unsigned long stack_high = (unsigned long)current->stack + THREAD_SIZE;
+
+ arm_get_current_stackframe(regs, &frame);
+ pr_emerg("Depth usage size Location\n");
+ while (1) {
+ prev_pc = frame.pc;
+ prev_sp = frame.sp;
+#if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND)
+ //meet the requirement of frame_pointer_check
+ if (frame.sp < (unsigned long)current->stack)
+ frame.sp = (unsigned long)current->stack + 4;
+#endif
+ if (unwind_frame(&frame) < 0)
+ break;
+ pr_emerg("%3d %5ld %5ld %ps\n",
+ depth++, stack_high - prev_sp,
+ frame.sp - prev_sp, (void *)prev_pc);
+ }
+ pr_emerg("----- ----- ----- ------\n");
+}
+
asmlinkage void handle_bad_stack(struct pt_regs *regs)
{
unsigned long tsk_stk = (unsigned long)current->stack;
@@ -940,6 +967,7 @@ asmlinkage void handle_bad_stack(struct pt_regs *regs)
#endif
pr_emerg("Overflow stack: [0x%08lx..0x%08lx]\n",
ovf_stk - OVERFLOW_STACK_SIZE, ovf_stk);
+ dump_stack_usage(regs);
die("kernel stack overflow", regs, 0);
}
With the help of vmap stack,it is able to detect stack overflow. To make it easy to debug stack overflow,dump the stack usage of each frame by walking the stack. After this patch,the log after stack overflows like below: Insufficient stack space to handle exception! Task stack: [0xf4a70000..0xf4a72000] IRQ stack: [0xf0800000..0xf0802000] Overflow stack: [0x818c1000..0x818c2000] Depth usage size Location 0 8232 96 _prb_read_valid 1 8136 24 prb_read_valid 2 8112 200 printk_get_next_message 3 7912 104 console_flush_all 4 7808 64 console_unlock 5 7744 40 vprintk_emit 6 7704 16 vprintk_default 7 7688 32 _printk 8 7656 1048 do_circle_loop 9 6608 1048 do_circle_loop 10 5560 1048 do_circle_loop 11 4512 1048 do_circle_loop 12 3464 1048 do_circle_loop 13 2416 1048 do_circle_loop 14 1368 1048 do_circle_loop 15 320 8 stack_ovf_selftest 16 312 24 param_attr_store 17 288 40 kernfs_fop_write_iter 18 248 112 vfs_write 19 136 48 ksys_write ----- ----- ----- ------ Internal error: kernel stack overflow: 0 [#1] SMP ARM ... Signed-off-by: Haibo Li <haibo.li@mediatek.com> --- arch/arm/kernel/traps.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)