我有一个在嵌入式 x86 设置上运行的自定义应用程序(使用 buildroot 和 uClibc 构建)。该应用程序一直运行良好,但今天早上当我返回工作时,我发现我的进程已被终止,并且我的终端上出现以下输出
SAK: killed process 1008 (CX_SC3): fd#4 opened to the tty
SAK: killed process 1009 (CX_SC3): fd#4 opened to the tty
SAK: killed process 1011 (CX_SC3): fd#4 opened to the tty
SAK: killed process 1012 (CX_SC3): fd#4 opened to the tty
现在CX_SC3
是我的进程 - 它有多个线程,其中一个线程打开/dev/ttyS0
以通过无线电调制解调器发送消息。串口的fd号是4。我不明白的是
- SAK 的含义
- 上面列出的 PID 必须引用被我的应用程序杀死的进程,因为我的应用程序一次只有一个实例在运行。这些 PID 是否有可能实际上是我的线程 ID(因为我的应用程序始终运行 4 个线程)。
- 如果我的应用程序杀死了其他进程,为什么我的应用程序也被杀死了?
- 该部分是什么
opened to the tty
意思?根据一些研究,这表明这与发送到我用来启动程序的 tty 的中断字符有关。
哪些事件可能导致以下输出?我的嵌入式设置非常小,除了我的自定义应用程序之外,只使用busybox
和运行vsftpd
很少其他东西。我的应用程序的健壮性至关重要。
编辑:针对下面的评论,如果这是由于检测到 SAK 造成的,是否有什么因素会意外触发此问题?是否有可能是串行端口上读取的任何内容触发了此操作?另外,我如何找到我的系统的 SAK 组合 -我的根文件系统中没有rc.sysinit
或文件。rc.local
更新:我已设法将此事件确定为我的主机关闭的时间点。我的主机和目标设备之间有一条串行电缆,用于将串行数据发送到嵌入式目标。当我让目标运行但关闭主机时,我的应用程序将被终止,如上所述。当我在关闭主机之前断开串行电缆时,我的应用程序不会被终止并正常运行。即使在我执行完之后也会发生这种行为
echo 0 > /proc/sys/kernel/sysrq
按照建议。
答案1
SAK 在这种情况下的真正含义是安全注意键。您看到的消息是定义在的内核消息驱动程序/tty/tty_io.c。 SAK 是确保用户在控制台上安全登录的组合键。在 Linux 上,SAK 通过终止附加到调用 SAK 的终端的所有进程来确保这一点。预计init
随后将重新启动受信任的登录过程,例如getty
后跟login
或X服务器和显示管理器。
CX_SC3
列出的 PID 确实是被 SAK 杀死的应用程序线程的 PID 。
fd#n opened to the tty
意味着被杀死的进程/线程具有文件描述符n
打开到调用 SAK 的终端。
在Linux中有两种方法调用SAK:
通过魔法系统请求键 - 通常为 ++ Alt(虚拟终端)或(串行控制台)。您的情况并非如此,因为您已经尝试通过禁用魔法,并且意外发送序列的可能性不大。SysRqKBreakKSysRq
echo 0 > /proc/sys/kernel/sysrq
BreakK通过定义的按键序列(虚拟终端)或中断信号(串行控制台)。串行控制台上的 SAK 可用性由 控制
setserial
。
中断信号在串行线路上连续发送间隔值的时间长于字符发送时间(包括起始位、停止位和奇偶校验位)。在您的情况下,很可能在关闭主机期间出现中断信号的情况。请尝试通过以下方式关闭目标设备上串行端口上的 SAK:setserial
:
setserial /dev/ttyS0 ^sak
您可以通过串口查看SAK功能状态setserial -g /dev/ttyS0
。开启SAK
后会显示Flags:
。要在启动后自动设置该选项,请参阅 BusyBox 系统上的启动脚本,通常是/etc/init.d/rcS
和/etc/rc.d/S*
或检查/etc/inittab
以获得其他可能性。
答案2
我在帕布克的回答的帮助下设法解决了这个问题。我最终发现的基于代码的解决方案允许SAK
在使用用户空间 API 打开时在串行端口上设置/取消设置标志,可以在 stackoverflow 上找到如何使用用户空间 API 在 Linux 上禁用串行端口 SAK 选项?