0%

Linux内核栈溢出检测

监测内核栈使用情况,分析 crash 问题

thread_info 位于内核栈底部,一旦溢出会破坏相关信息,有时会报错,但更多的是不直接报错,而是各种奇怪的panic

kernel stack

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