Linux进程/线程是否可以在不通过do_exit()的情况下终止?
为了验证我想使用的第三方二进制分布式软件的行为,我正在实现一个内核模块,其目标是跟踪该软件生成和终止的每个子级 目标二进制文件是Golang生成的,并且是多线程的。 我编写的内核模块在内核函数\u do\u fork()和do\u exit()上安装钩子,以跟踪此二进制文件生成和终止的每个进程/线程 LKM或多或少是有效的 然而,在某些情况下,我有一个无法解释的场景。 进程/线程似乎可以在不经过do\u exit()的情况下终止 我通过放置printk()收集的证据显示了进程的创建,但并不表示进程的终止 我知道printk()可能会很慢,而且我也知道在这种情况下消息可能会丢失 为了防止由于控制台速度慢而导致的消息丢失(对于这个特定的应用程序,使用了串行tty 115200),我尝试实现一个更快的控制台,并使用netconsole收集消息 所述设置似乎确认了一个进程可以在不通过do\u exit()函数的情况下终止 但是因为我不确定我的消息不会在printk()基础设施上丢失,我决定重复相同的测试,但将printk()替换为ftrace_printk(),这应该是printk()的更精简的替代方案 仍然是相同的结果,有时我会看到进程没有通过do_exit(),如果要验证PID当前是否正在运行,我必须面对它没有运行的事实 还要注意,我将钩子放在do_exit()内核函数中作为第一条指令,以确保函数流不会在被调用函数中终止 我的问题是: Linux进程是否可以在其流未通过do_exit()函数的情况下终止 如果是这样的话,有人能给我一个关于这个场景的提示吗 Linux进程是否可以在其流不通过do_exit()函数的情况下终止 可能不会,但您应该研究的源代码以确定。继续问。内核线程和/或相关事物(或者可能是Linux进程/线程是否可以在不通过do_exit()的情况下终止?,linux,multithreading,linux-kernel,exit,printk,Linux,Multithreading,Linux Kernel,Exit,Printk,为了验证我想使用的第三方二进制分布式软件的行为,我正在实现一个内核模块,其目标是跟踪该软件生成和终止的每个子级 目标二进制文件是Golang生成的,并且是多线程的。 我编写的内核模块在内核函数\u do\u fork()和do\u exit()上安装钩子,以跟踪此二进制文件生成和终止的每个进程/线程 LKM或多或少是有效的 然而,在某些情况下,我有一个无法解释的场景。 进程/线程似乎可以在不经过do\u exit()的情况下终止 我通过放置printk()收集的证据显示了进程的创建,但并不表示进
modprobe
或较旧的hotplug
)是可能的例外。当pid 1的/sbin/init
终止时(这不应该发生),奇怪的事情就会发生
LKM或多或少是有效的
这意味着什么?内核模块如何工作
在现实生活中,有时确实会发生Linux内核损坏或崩溃的情况(如果您的LKM没有经过Linux内核社区的同行审查,它可能会发生在LKM上)。在这种情况下,没有更多的概念,因为它们是由一个活的Linux内核提供的抽象 另见 还可以查看libc的源代码,例如 当然,请参见和 以及验证PID当前是否正在运行 这可以通过用户登陆
/proc/
,或使用0信号(也可能是…)来实现
另外,我仍然不明白为什么需要编写内核模块或更改内核代码。我的直觉是尽可能避免这样做。经过长时间的调试,我终于能够回答我自己的问题了 这还不是全部;我也能解释为什么我看到了我在场景中描述的奇怪行为 让我们从头开始:监视大量多线程应用程序。我观察到很少有PID突然停止而没有观察到它通过Linux内核do_exit()函数的流程的情况 因为这是我最初的问题: Linux进程是否可以在不通过do_exit()函数的情况下终止
至于我目前的知识,我现在认为是相当广泛的,一个Linux进程不能结束它的执行而不通过<强> doJeXIT()/<强>函数。< /P> 但这个答案与我的观察结果形成了对比,导致我提出这个问题的问题仍然存在
这里有人说我观察到的奇怪行为是因为我的观察有点错误,暗示我的方法不准确,至于我的结论 我的观察是正确的,我观察的过程没有通过do_exit(),而是终止了 为了解释这一现象,我想提出另一个我认为互联网搜索者可能会觉得有用的问题: 两个进程是否可以共享相同的PID 如果你一个月前问我这个问题,我肯定会回答这个问题:“绝对不会,两个进程不能共享同一个PID。” 不过,Linux更为复杂 在Linux系统中,两个不同的进程可以共享同一个PID 令人惊讶的是,这种行为不会伤害任何人;当这种情况发生时,这两个进程中的一个就是僵尸 如果线程引线在其子线程之前终止,则预期的行为是用引线的PID替换子线程的PID之一。这也意味着孩子的PID突然停止存在。 这就是我所看到的;我正在监视的PID没有通过do_exit(),因为当相应的线程终止时,它不再具有启动时的PID,而是具有其前导的PID 对于那些非常了解Linux内核机制的人来说,这并不奇怪;这种行为是有意的,自2.6.17以来没有改变。 咖喱