【发布时间】:2014-05-21 09:30:18
【问题描述】:
我为 armv6l 构建了一个最小的 Busybox initramfs 系统。内核版本为 3.12.20。如果我在没有CONFIG_ARM_UNWIND | Enable stack unwinding support (EXPERIMENTAL) 的情况下编译内核,然后通过 SSH 连接到系统并运行此脚本:
#!/bin/sh
while :
do
dmesg
done
短时间后屏幕上会显示“已杀”消息,系统将无法使用。如果我查看控制台,我看到 OOM 杀手已经杀死了 /bin/sh。我不必运行脚本来触发此行为,有时 SSH 连接会在登录后几乎立即断开。
之后我可以登录系统,但是 shell 不可用,所以我无法运行任何命令。但是,运行脚本总是会触发问题。我做了一些测试,发现在 OOM 杀手杀死 shell 之前,几乎所有 512 MB RAM 都是空闲的,所以 OOM 杀手没有理由杀死任何东西。
在做了一些研究之后,我仍然不明白堆栈展开支持是什么,但该功能是实验性的,所以我不认为我的系统需要它才能使用。
谁能解释为什么功能系统需要此功能?
【问题讨论】:
-
有多种功能依赖于
UNWIND支持。事实上,如果你不选择UNWIND,then another mechanism is used(即,RMK 将不得不杀死你;意思是 ARM Linux 维护者)。如果你没有编译,并且 bug 没有触发,那么UNWIND可能是 real bug 的无辜受害者;例如堆栈溢出。信息真的太少了;除非您只想要带有“?”的部分回答?事实上,你使用的编译器会发挥作用。 -
很可能,重复的
dmesg导致了某种竞争。一个真正的问题正在发生;内核任务 SEGV 然后展开将尝试打印诊断信息。此时,您一直在访问想要打印此信息的日志。串行控制台将是更好的机制。您的 SSH 依赖于很多功能;网络堆栈、驱动程序、用户空间 sshd 等。串行控制台将打印出错误而不运行常量dmesg。 -
即使您有很多可用内存,也可以调用OOM。大尺寸的
kmalloc()可能需要连续的内存。在这种情况下,分配器可能会运行 OOM 杀手。例如,如果不同的池已用尽或驱动程序使用 >4k 分配。