
1、ps、top、htop分别干什么先记这个区别ps 看“当前这一刻”的进程快照 top 实时刷新系统进程状态 htop 更友好的交互式 top所以想快速查一个进程有没有启动 → ps 想持续观察 CPU / 内存 → top 想更方便地看线程、排序、搜索 → htopps aux常见列USER PID %CPU %MEM VSZ RSS STAT START COMMAND你不用全背。现阶段重点PID %CPU %MEM RSS STAT COMMANDR running / runnableS sleepingD uninterruptible sleepT stoppedZ zombie如果一个网络接收线程对应的进程大多数时间S很正常。因为它可能正在recv poll epoll_wait condition_variable等待事件。zombie僵尸进程Z不是说进程还在正常执行。而是子进程已经退出但父进程还没有回收它的退出状态。可以理解child 已经死了 ↓ 内核还保留一小份退出信息 ↓ parent 还没 wait()所以 zombie通常不占大量 CPU / 内存但如果大量出现说明父进程的子进程管理有问题运行top通常上面会看到load average Tasks CPU Memory Swap下面是进程列表。你现阶段优先看%CPU %MEM RES PID COMMAND比如PID %CPU %MEM RES COMMAND 4321 98.5 2.1 300M gmr_node 4500 3.0 1.0 120M robot_output那第一反应gmr_node 明显是 CPU 热点然后继续查线程 函数如果只关心一个进程top -p 4321这样界面干净很多。特别适合现场只盯 robot_controltop -H -p 4321意思看这个进程里的线程。例如TID %CPU 4321 5% 4322 95% 4323 1% 4324 3%马上知道线程 4322最忙。然后下一步可以perf gdb strace继续看它在干什么。这就是你之前 perf 那节的链路进程高 ↓ top -H ↓ 线程高 ↓ perf ↓ 函数高某线程 100%往往意味着这个线程几乎一直在执行没有怎么阻塞。如果它本来应该等待 UDP结果却 100%就很可疑。可能是busy loop EAGAIN 重试 轮询错误 while(true)htop的价值htop比top更友好。运行htop一般可以搜索进程 按 CPU 排序 按内存排序 展开线程 树状查看父子关系对初学者很适合。比如你可以更直观看ros2 launch ├── node_a ├── node_b └── node_c这种父子关系。ps 看线程例如ps -T -p 4321或者ps -L -p 4321可以看到线程。如果想更详细ps -L -p 4321 -o pid,tid,psr,pcpu,stat,comm其中tid 线程 IDpsr 当前/最近运行在哪个 CPU 上pcpu CPU 占用这会和后面的CPU affinity直接连接。怎么知道进程什么时候启动可以ps -o pid,lstart,etime,cmd -p 4321其中lstart 启动时间etime 已运行多久这很适合排查程序是不是刚刚自动重启过例如你以为它运行 8 小时结果etime 00:02:15说明2 分钟前刚重启那就要继续查systemd 崩溃 watchdog查看 CPU 核数简单nproc例如8说明有 8 个逻辑 CPU。也可以lscpu看更详细信息。查看进程树常用pstree -p你可能看到systemd(1) └─ros2(3000) ├─mocap_node(3100) ├─gmr_node(3101) └─robot_output(3102)这对 ROS2 launch/systemd 服务排查非常直观。pgrep -a robot_control找到 PID。然后ps -o pid,ppid,etime,stat,%cpu,%mem,rss,args -p PID一次看PID 父进程 运行时间 状态 CPU 内存 完整启动参数这个非常适合机器人现场。只看网络相关系统调用strace -e tracenetwork -p 4321这样重点看socket bind connect accept send recv只看文件系统调用例如配置文件加载失败strace -e tracefile ./robot_control你可能看到openat(..., /etc/robot/config.yaml, ...) -1 ENOENT这说明No such file or directory可能程序其实在错误目录找配置。这类问题非常常见。futex你以后 strace 非常容易看到futex(...)先不要怕。它和mutex condition_variable 线程同步密切相关。可以粗略理解Linux 用户态线程在等待锁或条件变化时底层经常会使用 futex。所以如果程序卡住多个线程都futex(... FUTEX_WAIT ...)你应该开始怀疑是不是在等 mutex / condition_variable甚至可能deadlock-T特别适合看谁卡得久例如recvfrom(...) 0.000012 openat(...) 0.000030 connect(...) 10.001234一看connect花了 10 秒。所以strace 不只是看“调用了什么”还能帮助看“系统调用卡了多久”。保存 strace 日志例如strace -o trace.log -p 4321日志保存到trace.log现场问题特别适合。还可以strace -ff -o trace -p 4321多线程/子进程场景会生成多个 trace 文件。现在知道即可。程序崩了 → gdb / core dump程序卡了 → strace gdbCPU高 → top -H perf内存涨 → RSS ASan/Valgrind系统调用异常 → strace线程竞争 → TSan这就是你现在的完整排障工具链。2、systemdsystemd Linux 上用来管理系统服务和进程生命周期的服务管理器。它能帮你做开机自启 ↓ 启动程序 ↓ 监控是否退出 ↓ 异常时自动重启 ↓ 统一日志 ↓ 正常 stop ↓ 管理依赖关系所以机器人上的robot_driver controller diagnostics network_bridge很适合交给 systemd 管。 shell后台运行而systemd 服务生命周期管理完全不是一个层级。假设文件放在/etc/systemd/system/robot_control.service然后sudo systemctl daemon-reload告诉 systemdunit 文件更新了重新加载。启动sudo systemctl start robot_control查看systemctl status robot_control停止sudo systemctl stop robot_control重启sudo systemctl restart robot_control这几个非常常用。Typesimple先简单理解systemd 认为ExecStart启动的进程就是服务主进程。对于很多普通机器人程序Typesimple已经够用。以后还会看到notify forking oneshot现在不用展开。对于Typesimplesystemd 直接跟踪ExecStart启动的进程。所以systemctl status robot_control能看到Main PID这也是为什么前面说启动脚本里使用 exec会让进程关系更干净。3、LinuxLinux 权限决定“哪个用户/进程可以对哪个资源做什么”。dialout 组sudo usermod -aG dialout $USER意思把当前用户加入dialout组。之后重新登录让组信息生效。再groups确认有dialout这时候你的进程就可以以普通用户身份 ↓ 访问 /dev/ttyUSB0比sudo ./robot_driver更合理。udevudev Linux 用来管理设备节点和设备事件的一套机制。比如你插入 USB 串口USB 设备插入 ↓ Linux 内核识别 ↓ udev 处理 ↓ 创建 /dev/ttyUSB0 ↓ 设置 owner / group / mode ↓ 甚至创建稳定别名所以/dev/ttyUSB0不是你手工创建的。很多时候是udev帮你创建和配置。udev rule 是一组规则当某种设备出现时应该怎么命名、怎么设权限、属于哪个组。规则一般放在/etc/udev/rules.d/例如99-robot.rules为什么 udev 比 chmod 更适合工程部署因为插拔设备 ↓ udev 自动匹配 ↓ 自动应用权限你不需要每次sudo chmod ...所以chmod 临时人工操作而udev rule 可重复、可部署、自动化配置这就是工程上的区别。怎么查 USB 设备的 Vendor/Product ID最常用lsusb例如Bus 001 Device 005: ID 0403:6015 Future Technology Devices...这里0403是 vendor ID。6015是 product ID。这类信息可以用于写 udev rule。udevadm info比如udevadm info -a -n /dev/ttyUSB0它会输出设备属性。你可以找到idVendor idProduct serial manufacturer然后选择稳定属性写规则。udev rule 改完怎么生效常见sudo udevadm control --reload-rules然后sudo udevadm trigger或者直接重新插拔设备。再ls -l /dev/robot_imu确认规则是否生效。如果规则没生效怎么查可以udevadm info -a -n /dev/ttyUSB0确认你匹配的属性到底在哪一层。因为ATTR和ATTRS含义有差别。现阶段不需要钻语法细节。你先建立排障流程设备存在吗 ↓ ls -l 权限是什么 ↓ udevadm info 看属性 ↓ rule 是否匹配 ↓ reload ↓ 重新插拔capabilityLinux 不只有普通用户 root两档。还可以把 root 的能力拆成很多capabilities比如CAP_NET_ADMIN CAP_SYS_NICE CAP_IPC_LOCK这些以后实时控制也会碰到。例如SCHED_FIFO高实时优先级可能需要CAP_SYS_NICEmlockall某些配置下可能涉及MEMLOCK limit网络接口配置可能涉及CAP_NET_ADMIN所以能力可以细分授权而不是所有事都 sudo root。目录权限里的 x 是什么意思这里很容易踩坑。对普通文件x一般是execute但对目录x更接近允许进入/穿过这个目录。例如/home/robot/config/即使robot.yaml本身可读但上级目录没有执行权限程序还是可能打不开所以权限问题不能只看目标文件。udev 还能做什么除了设置权限 创建 symlink它还可以根据设备插拔触发规则 设置属性 设备命名不过机器人项目里你现阶段最重要的是稳定命名 访问权限这两个4、权限ip addr先看网卡和 IP最常用ip addr或者ip a你会看到类似2: enp3s0: inet 192.168.1.10/24这里enp3s0 网卡接口名 192.168.1.10 IP /24 子网前缀机器人现场第一步经常就是目标网卡到底有没有正确 IPip link看网卡是不是 UP执行ip link可能看到enp3s0: BROADCAST,MULTICAST,UP,LOWER_UP重点UP表示接口被启用。LOWER_UP通常说明物理链路也起来了。如果没有LOWER_UP你就要怀疑网线 交换机 网口 设备供电而不是先查应用程序。手工启用网卡例如sudo ip link set enp3s0 up关闭sudo ip link set enp3s0 down这只是接口状态控制。不是配置 IP。临时设置静态 IP例如sudo ip addr add 192.168.1.10/24 dev enp3s0注意这是临时配置重启后通常不会永久保留。生产系统一般用NetworkManager netplan systemd-networkd等做持久配置。ping到底验证了什么例如ping 192.168.1.20如果通说明 IP 层基本可达但注意ping 通 ≠ UDP/TCP 应用一定正常。因为 ping 用的是ICMP不是TCP UDP所以只能说明网络路径大体可达不能证明你的端口打开 程序在监听 防火墙没拦 UDP 应用协议正确为什么 ping 不通也不一定说明完全不通有些设备或防火墙禁止 ICMP但TCP/UDP 业务端口仍然正常所以ping只是网络排查工具之一。不能作为唯一判断。ss查端口最重要你前面已经见过ss -ltnp看 TCP 监听。拆开-l listening -t TCP -n 不解析名字 -p 显示进程例如LISTEN 0 128 0.0.0.0:5555 users:((robot_server,pid4321,fd8))说明robot_server PID 4321 fd 8 正在监听 TCP 5555ss -lunp其中-u UDP比如0.0.0.0:7014说明程序已经 bind 7014。这对你的动捕 UDP 排障特别关键。0.0.0.0是什么意思如果服务绑定0.0.0.0:7014一般表示接受本机多个 IPv4 接口上发到 7014 的流量。如果绑定192.168.1.10:7014那通常只监听这个地址。所以bind 地址也是通信是否正常的重要因素。127.0.0.1是什么意思127.0.0.1是localhost 回环地址如果服务只绑定127.0.0.1:5555那么本机程序可以访问 远端机器通常访问不了这是一个非常常见的配置问题。TCP 怎么简单测端口如果你想确认192.168.1.20:5555能不能建立 TCP 连接可以用nc -vz 192.168.1.20 5555成功可能看到succeeded这说明TCP 路径和服务监听基本正常UDP 为什么不能像 TCP 那么简单验证因为 UDP没有连接建立过程你发一个包不一定有回应所以“我 sendto 成功了”只能说明本地内核接受了这个数据发送请求。不代表对端一定收到了这就是 UDP 排查为什么更依赖抓包和应用层统计。ethtool例如sudo ethtool enp3s0可以看Link detected Speed Duplex Auto-negotiation例如Speed: 1000Mb/s Duplex: Full Link detected: yes对于机器人有线网络很实用。Full Duplex简单理解Full Duplex 可以同时收和发现代以太网通常都是全双工。如果协商异常速度或双工不一致可能导致大量重传 吞吐下降 奇怪网络问题比如服务机器人电脑 192.168.1.10如果你在本机测试nc 127.0.0.1 5555成功。不能证明远端 192.168.1.20也能连接。还需要测试nc 192.168.1.10 5555并从另一台机器实际测试。一个典型 UDP 动捕排障流程假设动捕发送端 → 192.168.10.20:7014你的机器人应该接收第一步ip addr确认机器人网卡是不是192.168.10.x/24第二步ip link确认UP LOWER_UP第三步ss -lunp确认7014真的被你的进程 bind。第四步strace -e tracenetwork -p PID看recvfrom有没有数据返回。这样就能逐层缩小问题。TCPConnection refused例如connect(...) → Connection refused通常意味着目标 IP 可达 但目标端口上没有服务监听或者明确被拒绝。这和Connection timed out不一样。设备网络 → EtherCAT / CAN / UDP 传感器 机器人内部通信 → ROS2 / ZMQ 外部网络 → SSH / Wi-Fi / 调试 / 远程监控