首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 操作系统 > UNIXLINUX >

依据linux内核源码查找recv返回EBADF(errno 9)的原因

2013-11-02 
根据linux内核源码查找recv返回EBADF(errno 9)的原因linux的内核版本是2.6.18,x86_64.man里的解释是:EBADF

根据linux内核源码查找recv返回EBADF(errno 9)的原因

linux的内核版本是2.6.18,x86_64.

man里的解释是:

EBADF

The argument s is an invalid descriptor

我的模拟测试环境是:

前端loadrunner模拟web点击,通过后端的weblogic压自己的服务的时候发现,有时候recv会收到这个错误,意思就是这个fd已经失效了,但是有点不是很明白,所以查询下内核实现,验证下。

首先recv的实现就是调用的recvfrom:


从代码内可以看到是fget_light这个函数如果返回NULL,则对外报EBADF错误。

那么fget_light这个函数做了什么呢,继续看代码:

再看函数fcheck_files

其实到这里就可以看出来,fget_light总共有两个地方返回NULL,

1、fcheck_files内发现fd > fdt->max_fds 会返回NULL,这种情况一般不会发生,除非你调用recv的时候传入的fd值不是真实使用的fd,而是一个很大的值。

2、当我们要增加引用计数的时候,发现这个引用计数是0,也就是说被你自己进程的其他线程close了。

max_fds可以简单通过/proc/pid/status的FDSize查看值,这个max_fds其实是计算出来的,下面给出算法

初始值是NR_OPEN_DEFAULT就是long的bit数,x64是64,x86是32,

如果超过这个就变成256,如果超过256就4096/8就是512,超过512就是

512*2=1024,再超过就是1024*2=2048,一直这样成倍增加,直到最大值NR_OPEN,是1024*1024=1048576

可能会有人问,不是还有ulimit设置的open files的限制的吗?

恩,是有,这个叫做进程的资源限制,不过这个检查是在分配新的fd,比如accept这时候去检查的,如果新的fd大于那个限制是会直接报错EMFILE这个错误的。




热点排行