检测 3.0 之前版本内核上的内核线程

检测 3.0 之前版本内核上的内核线程

查看 proc 手册页(http://man7.org/linux/man-pages/man5/proc.5.html) 可以/proc/<pid>/stat通过查看flags值 ( PF_KTHREAD)来检测哪些进程是内核线程

flags %u (%lu before Linux 2.6.22)
     (9) The kernel flags word of the process.  For bit
     meanings, see the PF_* defines in the Linux kernel
     source file include/linux/sched.h.  Details depend
     on the kernel version.

这个进程标志 ( PF_KTHREAD) 在内核版本 2.6.18(在 RHEL5 中使用)中似乎不存在,该值被另一个标志使用。

有没有其他方法来确定pid是否是内核线程?

答案1

启发式地,请参阅https://stackoverflow.com/questions/12213445/identifying-kernel-threads

pstop(来自procps-3.28)使用“无命令行”作为检查,并且不了解PF_KTHREAD.这就是触发他们添加[``]到进程名称的原因,它是不是实际进程名称的一部分。由于命令行受进程本身的控制,因此它可能已被修改。

这取决于您需要回溯多远(2.4?2.2?)。对一些系统的快速搜索表明没有明显的共同标志(字段 9 /proc/PID/stat

在 2.6.x 后期,您可以通过父 PID 为 0 来猜测[kthreadd],通常 PID 为 2,并且所有线程都将是其子线程(init也可能具有 PPID=0)。或者可能(早期的 2.6.x?) a[kthread]代替,但不是 PID 2,但它可能只是大多数而不是所有线程的父级。

另一种方法是检查/proc/PID/maps(用户空间内存映射),对于内核线程来说,这将是空的——因此只要进程标志(in /proc/PID/stat)不是&(PF_EXITING)/proc/PID/maps空就是一个很好的指示器。请注意,您必须实际读取maps,而不仅仅是stat()它,因为大小被错误报告为 0;并且您还必须获得许可,如果没有,它可能会显示为空而不会导致错误。

for pp in /proc/[0-9]*; do 
  if [ -z "$(< $pp/maps)" ]; then echo ${pp##/proc/}; fi; 
done 

您可以添加类似的表达式来检查它cmdline是否也是空的。

答案2

查看/proc3.8 系列内核上的内核线程条目,显然链接exe是空的,其中statm充满了零,status缺少所有Vm*条目并且也是maps空的。

也许其中一些适用于有问题的旧内核。

相关内容