监测内核栈使用情况,分析 crash 问题
thread_info
位于内核栈底部,一旦溢出会破坏相关信息,有时会报错,但更多的是不直接报错,而是各种奇怪的panic
debugfs
开启 debugfs
使用如下方法监控内核栈的大小和深度
# mount -t debugfs nodev /sys/kernel/debug
# echo 1 > /proc/sys/kernel/stack_tracer_enabled
# cat /sys/kernel/debug/tracing/stack_max_size
# cat /sys/kernel/debug/tracing/stack_trace
内核配置
CONFIG_DEBUG_STACK_USAGE
Symbol: DEBUG_STACK_USAGE [=y]
Type : boolean
Prompt: Stack utilization instrumentation
Location:
-> Kernel hacking
(1) -> Memory Debugging
Defined at lib/Kconfig.debug:562
Depends on: DEBUG_KERNEL [=y] && !IA64
用于跟踪内核栈的溢出错误,一个内核栈溢出错误的明显的现象是产生 oops 错误却没有列出系统的调用栈信息。该选项将使内核进行栈溢出检查,并使内核进行栈使用的统计
DEBUG_STACK_OVERFLOW
内核未提供 arm 配置选项,可以参照 patch 检测内核的堆栈溢出
CONFIG_STACK_TRACER
Symbol: STACK_TRACER [=n]
Type : boolean
Prompt: Trace max stack
Location:
-> Kernel hacking
-> Tracers (FTRACE [=y])
Defined at kernel/trace/Kconfig:381
Depends on: TRACING_SUPPORT [=y] && FTRACE [=y] && HAVE_FUNCTION_TRACER [=y]
Selects: FUNCTION_TRACER [=n] && STACKTRACE [=y] && KALLSYMS [=y]
参照文档 Documentation/trace/ftrace.txt
使用如下
# echo 1 > /proc/sys/kernel/stack_tracer_enabled
# cat stack_max_size
2928
# cat stack_trace
Depth Size Location (18 entries)
----- ---- --------
0) 2928 224 update_sd_lb_stats+0xbc/0x4ac
1) 2704 160 find_busiest_group+0x31/0x1f1
2) 2544 256 load_balance+0xd9/0x662
3) 2288 80 idle_balance+0xbb/0x130
4) 2208 128 __schedule+0x26e/0x5b9
5) 2080 16 schedule+0x64/0x66
6) 2064 128 schedule_timeout+0x34/0xe0
7) 1936 112 wait_for_common+0x97/0xf1
8) 1824 16 wait_for_completion+0x1d/0x1f
9) 1808 128 flush_work+0xfe/0x119
10) 1680 16 tty_flush_to_ldisc+0x1e/0x20
11) 1664 48 input_available_p+0x1d/0x5c
12) 1616 48 n_tty_poll+0x6d/0x134
13) 1568 64 tty_poll+0x64/0x7f
14) 1504 880 do_select+0x31e/0x511
15) 624 400 core_sys_select+0x177/0x216
16) 224 96 sys_select+0x91/0xb9
17) 128 128 system_call_fastpath+0x16/0x1b