TOP 发现高CPU占用进程 跟踪定位

方法1: 检查 /proc/PID/cmdline

查看进程的命令行参数:

1
cat /proc/<PID>/cmdline | tr '\0' ' '
  • 结果解释
    • 如果 bash 是直接执行某个命令(如 bash -c "while true; do echo 'loop'; done"),此处会显示完整命令。
    • 如果 bash 是交互式终端或脚本解释器,可能只显示 bash 本身(无具体命令)。

方法 2:查看进程打开的文件(lsof

检查进程打开的文件句柄,尤其是当前工作目录或脚本文件:

1
lsof -p <PID>
  • 重点关注
    • cwd:进程的当前工作目录。
    • txtREG 类型的文件:可能是正在执行的脚本或二进制文件。

方法 3:追踪进程的系统调用(strace

通过 strace 动态追踪进程的系统调用(需要权限):

1
sudo strace -p <PID> -s 9999 -f 2>&1 | grep -E 'execve|open|read'
  • 作用
    • 监控进程的 execve(执行新程序)、open(打开文件)、read(读取文件)等操作。
    • 如果 bash 正在执行脚本或命令,可能会看到具体操作。

方法 4:检查进程的环境变量

查看进程的环境变量(可能包含脚本路径或参数):

1
cat /proc/<PID>/environ | tr '\0' '\n'
  • 关注点
    • _ 变量:通常表示最后执行的命令的路径。
    • BASH_ENVBASH_SOURCE:可能指向加载的脚本。

方法 5:查找父进程或子进程

通过 pstreeps 查看进程关系:

1
2
pstree -p <PID>     # 显示进程树
ps -ef --forest # 显示进程层级关系
  • 场景
    • 如果 bash 是某个脚本的父进程,其子进程可能显示具体命令(如 pythonsleep 等)。
    • 示例:
      1
      bash(1234)───sleep(5678)

方法 6:检查历史记录(仅限交互式会话)

如果 bash 是用户登录的交互式会话,可以检查其历史记录:

1
2
# 查看用户的 bash 历史文件
cat ~/.bash_history | tail -n 20
  • 局限性
    • 如果是后台进程或脚本,历史记录可能未保存。

方法 7:使用 gdb 附加到进程(高级)

通过 gdb 附加到进程并检查调用栈(需要调试符号):

1
2
sudo gdb -p <PID>
(gdb) bt # 查看调用栈
  • 作用
    • 如果 bash 正在执行函数或循环,调用栈可能显示内部状态(需一定经验解读)。

方法 8:检查审计日志(auditd,需提前配置)

如果系统启用了 auditd,可以查询进程执行记录:

1
ausearch -p <PID> -sc execve
  • 前提
    • 需要提前配置审计规则(默认可能未启用)。

总结流程

  1. 快速查看命令行参数
    1
    cat /proc/<PID>/cmdline | tr '\0' ' '
  2. 检查打开的文件和进程树
    1
    lsof -p <PID> && pstree -p <PID>
  3. 动态追踪系统调用
    1
    sudo strace -p <PID> -s 9999 -f

如果上述方法仍无法定位,可能是 bash 在执行一个循环或长时间阻塞操作(如 while true; do ... done),此时需要结合代码审查或日志分析进一步排查。

strace -p 103411 -s 9999 -f 2>&1 | grep -E ‘execve|open|read’