调试堆栈内核模块溢出

时间:2014-12-15 06:55:11

标签: c debugging linux-kernel kernel

我正在处理驱动程序代码,导致堆栈溢出 问题和记忆腐败。目前运行该模块给出, “异常堆栈”和堆栈跟踪看起来已损坏。

模块有编译警告。警告已经解决 使用gcc选项“-WFrame-larger-than = len”。

这个问题可能是因为过多的内衬和很多问题引起的 函数参数和大量嵌套函数。我需要继续 测试并继续重新分解代码,是否可能 进行任何修改内核以增加堆栈大小?另外,您将如何调试此类问题。

1 个答案:

答案 0 :(得分:2)

虽然您的模块将使用“-WFrame-greater-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 <minchan@kernel.org>
Date:   Wed May 28 15:53:59 2014 +0900

x86_64: expand kernel stack to 16K

参考LWN: [RFC 2/2] x86_64: expand kernel stack to 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核心文件。