Ubuntu20.04下Visual Code绕过文件描述符限制的原理问询
核心原理
Ubuntu 20.04 针对单进程的文件描述符资源(RLIMIT_NOFILE)设置了两级限制:
- 软限制:默认值1024,是进程实际触发资源超限的阈值,当进程打开的fd数超过该值时,
open、socket、accept等系统调用会返回EMFILE错误。大部分业务程序没有针对该错误做兼容处理,拿到返回的-1作为合法fd操作时就会触发无提示崩溃。 - 硬限制:默认值远高于软限制(普通桌面版通常为4096~1048576不等,取决于系统配置),是普通进程可以自主调整软限制的天花板,进程无需root权限即可在硬限制范围内任意修改自身软限制,不存在突破系统规则的特殊机制。
VS Code的具体实现逻辑
VS Code 没有使用任何特殊的系统hook或后门,只是做了常规的资源限制调整:
- 主进程启动阶段,会直接调用
prlimit/setrlimit系统调用,将自身进程的RLIMIT_NOFILE软限制拉高到硬限制允许的较高值(多数版本默认设为65536,或直接对齐硬限制上限)。 - Linux的进程资源限制遵循继承规则:父进程fork出的所有子进程,会默认完整继承父进程当前的资源限制配置。
- VS Code直接拉起的调试进程、插件进程是其子进程,直接继承拉高后的fd限制
- VS Code内置终端启动的shell进程同样是子进程,会继承该限制,后续从该shell中启动的所有程序都会沿用这个高阈值,自然不会触发1024的默认上限。
- 可直接验证:在系统原生终端执行
ulimit -n会返回默认值1024,在VS Code内置终端执行相同命令,返回值会远高于1024,就是该继承逻辑的直接体现。
自有应用复刻方案
只需要在程序入口的最早期(启动子进程、打开大量文件/socket连接之前),加入调整自身RLIMIT_NOFILE软限制的逻辑即可,无需root权限:
- C/C++ 实现代码:
#include <sys/resource.h> // 放入main函数最开头执行 void adjust_nofile_rlimit() { struct rlimit rl; if (getrlimit(RLIMIT_NOFILE, &rl) != 0) return; // 软限制对齐硬限制,也可按需设置为不超过硬限制的自定义值 rl.rlim_cur = rl.rlim_max; setrlimit(RLIMIT_NOFILE, &rl); }
- Shell启动脚本实现:
# 脚本头部加入,将当前shell进程的软限制对齐硬限制 ulimit -n $(ulimit -Hn) # 后续执行业务程序启动命令即可
- Python实现代码:
import resource def adjust_nofile_rlimit(): soft_limit, hard_limit = resource.getrlimit(resource.RLIMIT_NOFILE) resource.setrlimit(resource.RLIMIT_NOFILE, (hard_limit, hard_limit))
注意:如果业务需要的fd数量超过系统配置的默认硬限制,需要先修改系统全局配置(如
/etc/security/limits.conf、systemd服务的LimitNOFILE配置)将硬限制调到目标值,这一步需要root权限,VS Code本身也无法突破硬限制的约束。
内容的提问来源于stack exchange,提问作者JDGross
相关产品推荐
相关产品推荐

