关键词:errno、EMFILE、ulimit、lsof等等。

背景是在对程序进行压力测试,运行了一段时间之后出现一个复位操作失败。

这个复位操作通过打开一个设备,进行读写操作,已达到控制GPIO输入输出的目的。

1. 初步分析原因

经过初步分析发觉fopen()返回NULL指针,说明fopen()错误了。

但是要想知道错误原因,还需要借助errno。通过errno为24,即可知道出错的原因为EMFILE。

由errno-base.h可知,EMFILE是打开文件过多的意思。

#define    EMFILE        24    /* Too many open files */

2. 找到是谁打开了哪个文件而没有释放

首先明白系统对资源使用限制的,通过ulimit可以查看限制或者修改限制。

关于文件打开文件数目的限制通过ulimit -n查看,或者ulimit -n <file null>修改限制。

通过ulimit -n命令可以查看linux系统里打开文件描述符的最大值,一般缺省值是1024。

ulimit -a
-f: file size (blocks) unlimited
-t: cpu time (seconds) unlimited
-d: data seg size (kb) unlimited
-s: stack size (kb)
-c: core file size (blocks)
-m: resident set size (kb) unlimited
-l: locked memory (kb)
-p: processes
-n: file descriptors 1024
-v: address space (kb) unlimited
-w: locks unlimited
-e: scheduling priority
-r: real-time priority

lsof显示系统所有打开文件,那么很简单通过lsof即可查看到相关信息。

通过lsof可以看到打开的文件非常多,而且主要集中在uImage这个文件。

...
/heop/package/AiApp/AiApp /heop/package/AiApp/uImage
/heop/package/AiApp/AiApp /heop/package/AiApp/uImage
/heop/package/AiApp/AiApp /heop/package/AiApp/uImage
...

然后看到uImage这个文件被打开了1000多次,问题就很明了了。

通过走查代码,发现uImage文件在被打开后由于某些条件未fclose()。解决也比较简单。

3. EMFILE出现代码走查

open系统调用入口是do_sys_open(),通过get_unused_fd_flags()来获得可用的句柄号。

long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode)
{
...
fd = get_unused_fd_flags(flags);
if (fd >= ) {
...
}
putname(tmp);
return fd;
} SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, umode_t, mode)
{
if (force_o_largefile())
flags |= O_LARGEFILE; return do_sys_open(AT_FDCWD, filename, flags, mode);
}

然后就看看句柄是如何分配的,以及有什么限制。

通过rlimit(RLIMIT_NOFILE)可以获得系统对打开文件数目的限制,等同于ulimit -n。

然后__alloc_fd()应该着这个范围之内。当判断fd>=end的时候,返回-EMFILE

int get_unused_fd_flags(unsigned flags)
{
return __alloc_fd(current->files, , rlimit(RLIMIT_NOFILE), flags);
} int __alloc_fd(struct files_struct *files,
unsigned start, unsigned end, unsigned flags)
{
...
error = -EMFILE;
if (fd >= end)
goto out;
... out:
spin_unlock(&files->file_lock);
return error;
}

一个EMFILE问题定位:lsof、ulimit的应用,以及简单分析的更多相关文章

  1. Selenium自动化中DOM,XPATH,CSS定位Web页面对象的优劣性分析

    加速IE浏览器自动化执行效率:Selenium自动化中DOM,XPATH,CSS定位Web页面对象的优劣性分析 1.技术背景       在Web应用中,用户通过键盘在输入框中输入值和鼠标点击按钮,链 ...

  2. [转] 一个U盘病毒简单分析

    (转自:一个U盘病毒简单分析 - 瑞星网   原文日期:2014.03.25) U盘这个移动存储设备由于体积小.容量大.便于携带等优点,给人们的存储数据带来了很大的便利.但正是由于这种便利,也给病毒有 ...

  3. 想做一个整合开源安全代码扫描工具的代码安全分析平台 - Android方向调研

    想做一个整合开源安全代码扫描工具的代码安全分析平台 - Android方向调研 http://blog.csdn.net/testing_is_believing/article/details/22 ...

  4. 一个使用C#的TPL Dataflow Library的例子:分析文本文件中词频

    博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:一个使用C#的TPL Dataflow Library的例子:分析文本文件中词频.

  5. 每天一个linux命令(38)--lsof 之FD文件描述符

    一般lsof 会输出以下这些信息: COMMAND: 进程的名称 PID:进程标识符 PPID:父进程标识符(需要指定-R参数) USER:进程所有者 PGID:进程所属组 FD:文件描述符,应用程序 ...

  6. 每天一个linux命令(38)--lsof命令

    lsof (list open files )是一个列出当前系统打开文件的工具,在Linux 环境下,任何事情都以文件的形式存在,通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件.所以如传输控 ...

  7. 多个ul中第一个li获取定位

    如果我们只是获取一个ul中的第一个li的话,那么我们可以这样写: $("ul li:first"); $("ul li").eq(0); $("ul ...

  8. 一个ActionResult中定位到两个视图—<团委项目>

         在使用MVC做项目的时候一般的情况就是一个ActionResult一个视图,这样对应的Return View();就可以找到下面对应的视图,这是根据一个原则,"约定大于配置&quo ...

  9. 谁记录了mysql error log中的超长信息(记pt-stalk一个bug的定位过程)

    [问题] 最近查看MySQL的error log文件时,发现有很多服务器的文件中有大量的如下日志,内容很长(大小在200K左右),从记录的内容看,并没有明显的异常信息. 有一台测试服务器也有类似的问题 ...

随机推荐

  1. ASP.NET Aries 高级开发教程:行内编辑事件怎么新增数据到后台(番外篇)

    前提: 今天又网友又提出了一个问题,说行内编辑保存之前,怎么新增一些数据提交到后台? 对方说看了源码,也没找到怎么处理,这里就写文给解答一下. 解答: 于是我看了一眼源码,只能说你没找到地方: 第12 ...

  2. VS2019 开发Django(六)------Admin中图片上传

    导航:VS2019开发Django系列 该篇继续完善在Django的管理界面上传图片,因为LazyOrders小程序中菜单需要展示图片,而不是一个文本路径,所以我们还需要继续改造一下. 1)安装pil ...

  3. 安装指定版本的tensorflow(我报错了)

    安装命令如下: pip install tensorflow-gpu==1.10.0 -i https://pypi.tuna.tsinghua.edu.cn/simple 慎用,反正我报错了,而且还 ...

  4. JavaScript 日期格式

    有四种 JavaScript 日期输入格式: 类型 实例 ISO 日期 "2018-02-19" (国际标准) 短日期 "02/19/2018" 或者 &quo ...

  5. [转]UiPath Deployment Architecture

    本文转自:https://dotnetbasic.com/2019/08/uipath-deployment-architecture.html We will learn step by step ...

  6. Saltstack_使用指南09_远程执行-编写执行模块

    1. 主机规划 salt 版本 [root@salt100 ~]# salt --version salt (Oxygen) [root@salt100 ~]# salt-minion --versi ...

  7. Nginx基础知识点总结和优化项

    1.什么是Nginx? Nginx是一个高性能的HTTP和反向代理服务器,常用于做负载均衡服务器 2.为什么要用Nginx?跨平台.配置简单非阻塞.高并发连接:处理2-3万并发连接数,官方监测能支持5 ...

  8. Redis分布式缓存实现

    基于redis分布式缓存实现 第一:Redis是什么? Redis是基于内存.可持久化的日志型.Key-Value数据库高性能存储系统,并提供多种语言的API. 第二:出现背景 数据结构(Data S ...

  9. Linux 部署 java1.8

    1.安装 查看java安装包 yum list | grep java 使用yum安装 yum install java-1.8.0-openjdk.x86_64 修改环境变量 vi /etc/pro ...

  10. Git终端命令行的常用操作

    一.git源代码管理的优点 方便多人协同开发.工作 降低代码的管理成本 良好的分支管理机制 二.结构分析 服务端和客户端都有版本控制能力,都能进行代码的提交.合并 结构一: 结构二: 三.工作区的创建 ...