打开文件失败返回EMFILE的问题分析

打开文件失败返回EMFILE的问题分析

查找官网错误代码

在官网中查找到返回值为24对应的错误信息为EMFILE,对应的描述信息为EMFILE Too many open files 24,对应的中文翻译就是打开的文件太多.具体参考网址为:https://msdn.microsoft.com/en-us/library/t3ayayh1.aspx,对应的中文参考网址为:https://msdn.microsoft.com/zh-cn/magazine/t3ayayh1.aspx.由于是第一次碰到这种问题,且每次调用后我在析构函数中都调用了close,难道是fclose没有将FILE*关闭.windows系统存在这么明显的bug?显然是不可能的.
使用其它打开文件命令无法查看到返回错误信息的情况下可以通过上面的_wfopen_s来看看具体的错误值.
##调试fclose##
通过debug单步跟踪发现如下的调用关系:

  1. fclose
  2. _fclose_nolock
  3. _close(_fileno(stream))
    其中可以看到_fileno中获取的是stream中的_file,也就是文件no.具体FILE*的结构体如下:
struct _iobuf {
        char *_ptr;
        int   _cnt;
        char *_base;
        int   _flag;
        int   _file;//文件句柄
        int   _charbuf;
        int   _bufsiz;
        char *_tmpfname;
        };

通过调试这里发现此处文件很明显是关闭了的.

伟大的_fcloseall()

通过查找发现有个NB的函数可以关掉所有的句柄,直接在释放位置调用该方法_fcloseall(),再进行测试,此时长时间运行都未出现问题.可惜由于应用的需要不能使用该方法,故可以肯定是在某个位置出现了句柄的内存泄漏.

输出发现大玄机

通过在fclose前面输出FILE* fp的fp->_file信息,通过测试发现该值不断增大当增大到512左右的时候,程序就出现了文件再也无法打开的情况.按道理windows系统中除了标准输入、标准输出和错误输出后_file不应该出现无限增加的情况,初步推断windows一个进程最多可以支持打开512个文件(未验证,据说linux的是1024,按道理这应该是可以配置的系统参数).

后续

通过追踪肯定是句柄问题后,通过逐步排查最终找到了文件未关闭的位置.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值