假设在 Linux 系统上有一个非常短暂的进程被重复执行,它的效果是可见的(计算机发出哔哔声或其他声音),但进程本身退出得太快,无法被捕获ps
或pstree
以其他方式检查 - 而且它不在 crontab 或类似的东西中。如何找出进程实际上是什么,以及是什么执行了它?
(也可以应用于 PPID 为 1 的奇怪/恶意守护进程,这些守护进程在被杀死时会由未知的父进程神秘地重新启动。)
答案1
使用叉状态通过“netlink 连接器”子系统监控所有进程创建。
# forkstat
Time Event PID Info Duration Process
18:56:12 fork 1715703 parent -bash
18:56:12 fork 1722638 child -bash
18:56:12 exec 1722638 ls -N -F -h --color=auto
18:56:13 exit 1722638 0 0.535s ls -N -F -h --color=auto
forkstat 适用于任何 Linux 内核,但它仍然依赖于从/proc/<PID>
实际事件中获取命令行,因此仍有可能错过读取完整的命令行(尽管它将要无论如何仍报告事件和 PID)。
你也可以尝试bpftrace使用 eBPF 跟踪点:
# cat > forkstat.bt <<EOF
#include <linux/sched.h> /* for curtask */
BEGIN {
printf("%-8s %-16s => %-8s %s\n", "PPID", "COMM", "PID", "ARGS");
}
tracepoint:syscalls:sys_enter_exec* {
printf("%-8d %-16s => %-8d ", curtask->parent->pid, comm, pid);
join(args->argv);
}
EOF
# bpftrace forkstat.bt
Attaching 3 probes...
PPID COMM => PID ARGS
1714659 bash => 1723793 ls -N -F -h --color=auto
(请注意,此 bpftrace 示例需要内核头文件为当前运行的内核安装,例如linux-headers
包 – 类似于编译模块时所需要的。)
这脂肪痕迹工具跟踪文件访问,而不是进程,而是文件访问做包括执行一个程序:
# fatrace -fO
bash(295866): RO /usr/bin/git
bash(295866): RO /usr/lib/ld-linux-x86-64.so.2
再次,fatrace 依赖 /proc 来获取进程名称,因此它可能会显示unknown
快速退出的进程,但这不应该导致问题,因为父母通常是长期运行并且可以被检查。