内核模块中的调试堆栈溢出

格雷格·彼得(Greg Petr)

我正在研究驱动程序代码,这导致堆栈溢出问题和内存损坏。当前正在运行的模块给出了“异常堆栈”,并且堆栈跟踪看起来已损坏。

该模块具有编译警告。警告已通过gcc选项“ -WFrame-larger-than = len”解决。

该问题可能是由于过多的内联,大量的函数参数以及大量的嵌套函数引起的。我需要继续测试并继续重构代码,是否可以进行任何修改内核以增加堆栈大小?另外,您将如何调试此类问题。

Askb

尽管您的模块将使用“ -WFrame-larger-than = len”的警告进行编译,但仍将导致堆栈溢出,并可能破坏内核内数据结构,从而导致系统进入不一致状态。

Linux内核堆栈的大小限制为8KiB(在3.18之前的内核版本中),现在限制为16KiB(对于3.18以后的版本)。有一个最近到很多问题,由于承诺virtioqemu-kvm,内核堆栈一直延伸到16KiB。

现在,如果要将堆栈大小增加到32KiB,则需要在内核源文件中进行以下更改之后重新编译内核:(arch / x86 / include / asm / page_64_types.h)

    // for 32K stack
-    #define THREAD_SIZE_ORDER       2
+    #define THREAD_SIZE_ORDER       3

Linux内核版本3.18上的最近一次提交显示,内核堆栈大小已经增加到16K,在大多数情况下应该足够了。

commit 6538b8ea886e472f4431db8ca1d60478f838d14b
Author: Minchan Kim <[email protected]>
Date:   Wed May 28 15:53:59 2014 +0900

x86_64: expand kernel stack to 16K

请参考LWN:[RFC 2/2] x86_64:将内核堆栈扩展到16K

至于调试此类问题,没有单行回答的方法,但是这里有一些我可以分享的技巧。dump_stack()在模块中使用和获取,其中的堆栈跟踪syslog确实有助于调试与堆栈相关的问题。

使用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

在加载和测试模块时,以上文件将报告最高的堆栈使用率。

保持以下命令运行:

while true; do date; cat /sys/kernel/debug/tracing/stack_max_size;
cat /sys/kernel/debug/tracing/stack_trace; echo ======; sleep 30; done

如果您看到stack_max_size值可能超过〜14000字节(对于内核的16KiB堆栈版本),则值得进一步研究堆栈跟踪。另外,您可能想设置崩溃工具以在出现紧急情况时捕获vmcore核心文件。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章