You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用FD_ISSET触发未定义行为导致缓冲区溢出的原因排查

崩溃成因分析
  • 核心触发点是glibc的_FORTIFY_SOURCE安全校验机制:你调用的FD_ISSET宏在开启该编译选项时,会先调用__fdelt_chk检查传入的文件描述符是否小于FD_SETSIZE(glibc默认值为1024),如果超过阈值就会直接触发缓冲区溢出检测并终止程序,防止fd_set位图越界访问。
  • 原代码的逻辑漏洞:当some_condition不成立时,代码仍会执行最后一行的FD_ISSET(sock2, &readfds)。此时只要sock2的值≥FD_SETSIZE,无论你是否将sock2加入过readfds集合,都会触发校验失败崩溃。
  • 修复后逻辑正常的原因:新增的using_sock2判断保证了只有sock2被加入集合的场景下,才会执行FD_ISSET(sock2, &readfds)的逻辑,不会触发无效的校验。
  • Heisenbug的成因:gdb/valgrind运行程序时,会为进程注入调试相关逻辑、占用少量低编号文件描述符,导致sock2分配到的值刚好小于1024,不会触发阈值校验;或者调试环境默认降低了_FORTIFY_SOURCE的校验等级,只有原生运行时才会触发严格检查。你通过attach方式调试时程序已经完成启动、sock2已经分配到了超过阈值的数值,因此可以定位到崩溃点。

补充说明:man 2 select的NOTES章节明确标注:fd_set是固定大小的缓冲区,向FD_SET/FD_CLR/FD_ISSET传入值≥FD_SETSIZE的文件描述符会触发未定义行为,这就是你遇到的问题的标准定义。

内容的提问来源于stack exchange,提问作者Daniel Walker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 23:36:02