lsof can't identify protocol 句柄泄漏分析

本文详细记录了服务器上程序CPU标高问题的排查过程,通过使用lsof和strace工具,深入分析了360开源的evpp调用libevent的http接口引发的文件句柄泄露问题,最终定位并解决了Toomanyopenfiles问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前几天服务器上出现程序cpu标高,通过gdb看堆栈信息,发现Too many open files问题

 

通过lsof -p pid |wc -l看到文件非常高

分析如下:

程序主要是通过360开源的evpp 调用libevent 的http接口实现简单http服务器功能。所以一开始就就直接怀疑是evpp开源代码出现的问题,然后就看源代码分析。看句柄释放位置,但是不得而终。

后面开始用strace工具分析代码调用堆栈。

1、直接前端运行代码:

strace -f -F -o dcop-strace.txt dcopserver

这里 -f -F选项告诉strace同时跟踪fork和vfork出来的进程,-o选项把所有strace输出写到dcop-strace.txt里 面,dcopserver是要启动和调试的程序。

2、运行测试用例

3、关闭程序看dcop-strace.txt文件

   

显然开源代码已经在http返回时候执行了关闭操作。

4、重新1-2步操作,看进程id 在看/proc/pid/fd/里面的文件句柄,

5、执行测试用例,看多出的fd是哪些

 

 

6、再看dcop-strace.txt文件发现问题,通过文件内容里面显示的上下文调用顺序就可以很容易定位到问题

 

<think>好的,我现在需要解释用户的问题,关于“lsof -i -t”命令的解释。用户之前已经询问过如何提取进程ID,现在他们可能想深入了解这个特定命令的用途和参数。 首先,我得确认用户对lsof的基本了解。lsof是列出打开文件的工具,但在Linux中,文件包括网络连接等。用户之前接触过lsof -i来查看网络连接,现在加上-t选项,可能想知道其作用。 接下来,我需要分解每个选项的含义。-i参数用于显示网络连接,而-t选项让lsof仅输出进程ID,不显示其他信息。用户可能希望快速获取PID,以便后续操作,比如终止进程。不过,我需要检查是否正确记忆选项,避免错误解释。 然后,考虑用户的使用场景。用户可能在写脚本或者自动化任务,需要简洁的输出。-t选项适合这种情况,因为它去除了表头和其他冗余信息,直接输出PID,方便用变量存储或管道传递。但要注意,如果同时有多个进程使用同一端口,-t会返回多个PID,用kill命令处理时需要谨慎。 另外,用户可能对参数组合的用例感兴趣,比如结合特定端口(如80)使用。例如,lsof -i:80 -t,这会列出所有使用80端口的进程ID。需要给出具体例子,并提醒sudo权限的问题,因为普通用户可能无法查看所有进程。 还要注意潜在的问题,比如没有输出时如何处理,或者多个PID的情况。用户可能需要知道这些情况下的应对措施,比如检查服务是否运行,或确认是否有多个进程需要处理。 最后,总结命令的优点和注意事项,确保用户明白何时使用以及可能的风险,比如误杀进程。需要以清晰的结构分点说明,让用户容易理解。</think>在 Linux 中,`lsof -i -t` 是一个组合命令,用于**快速获取与网络连接相关的进程 ID(PID)**。它的核心特点是**简洁输出**,适合在脚本或自动化操作中直接提取 PID。以下是详细解释: --- ### **命令分解** 1. **`lsof`** 全称 `List Open Files`,用于列出系统中被打开的文件(包括网络连接、设备、目录等)。 2. **`-i`** 筛选**网络连接**相关的进程(如 TCP/UDP 端口、IPv4/IPv6 连接)。 3. **`-t`** 启用 "terse mode"(简洁模式),**仅输出 PID**,不显示表头和其他详细信息。 --- ### **典型用法** #### **1. 获取占用某端口的进程 PID** ```bash sudo lsof -i :80 -t ``` - **输出示例** ```bash 1234 5678 ``` 表示端口 `80` 被 PID 为 `1234` 和 `5678` 的进程占用。 #### **2. 终止占用某端口的所有进程** ```bash sudo kill -9 $(sudo lsof -i :80 -t) ``` - 直接通过管道将 PID 传递给 `kill -9` 强制终止进程。 #### **3. 结合正则过滤特定 IP 的连接** ```bash sudo lsof -i @192.168.1.100 -t ``` 列出与 IP `192.168.1.100` 建立连接的所有进程 PID。 --- ### **注意事项** 1. **必须使用 `sudo`** 普通用户可能无法查看其他用户的进程,需通过 `sudo` 提权。 2. **无输出表示无相关进程** 若命令无返回结果,说明指定条件(如端口、IP)下无活跃进程。 3. **多个 PID 的处理** 如果返回多个 PID,表示多个进程共享同一资源(如端口复用),终止前需确认用途。 --- ### **对比常规 `lsof` 输出** #### **未使用 `-t` 的情况** ```bash sudo lsof -i :22 ``` 输出包含表头和详细信息: ``` COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME sshd 1234 root 3u IPv4 12345 0t0 TCP *:ssh (LISTEN) ``` #### **使用 `-t` 后** ```bash sudo lsof -i :22 -t ``` 直接输出 PID: ``` 1234 ``` --- ### **总结** - **用途**:快速提取网络连接相关的 PID,适用于脚本或批量操作。 - **优势**:输出简洁,无需二次处理(如 `awk`/`cut`)。 - **风险**:直接操作 PID 可能误杀关键进程,建议先手动验证。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值