背景

项目在一次升级版本后,发现在DSP发生异常后,没有生成dspcrash文件。该文件通过system函数,直接调用可执行程序。后来增加定位信息,发现system返回-1。而在串口上直接调用可执行程序,执行成功。在控制台调用system函数,返回-1。system函数在该处理器上必现调用失败。

定位

首先需要了解system的执行过程,实际上system执行了三步操作:
1. fork一个子进程;
2. 在子进程中调用exec函数执行command;
3. 在父进程中调用wait等待子进程结束。
对于fork失败,system函数返回-1,;如果exec执行成功,则返回command通过exit或return返回的值;如果exec执行失败,system返回127。
由于返回值是-1,因此比较怀疑fork执行失败。在控制台上输入fork后,果然返回-1。fork返回-1主要由两种原因:系统达到最大进程数上限或者系统内存不足。由于系统当前进程数并不多,因此怀疑内存不足。
0803版本中升级了由于CPUH内存空间不足,导致升级失败的问题。这个问题是通过将CPUL的100M内存挪至CPUH解决的。至此,问题已基本明确,确实是由于挪动内存后,CPUL上的剩余内存不足以fork。
其实这里我有一个疑问,fork会复制父进程的数据空间、堆和栈的副本。因此,如果父进程的内存占用超过系统总可用内存的50%,调用system或fork就会存在风险。而linux提供了另外一个函数:vfork。vfork并不会复制父进程的完整地址空间,这个函数主要应用的场景就是fork后,立即调用exec(exec会使用新程序替换掉当前进程的正文段、数据段、堆和栈)。按照上面提到的fork流程,fork时需要大量的内存来存放父进程的地址空间,而在exec时又会立即用新程序替换掉。对于system调用失败,仅仅是由于内存不足以容纳另一份父进程地址空间,未免有点冤了。而直接使用vfork,则空闲内存并不需要那么大,system为何没有使用更合适的vfork呢?

解决

有两个解决方案,一个是重新调整CPUL以及CPUH的内存分配,另一个是调整内核参数。
其中方案1存在一定的风险,因为内存的使用是动态的,如果分回来的过多,可能导致CPUH再次出现偶尔升级失败,如果分过来的不够,则有可能出现CPUL调用system失败,因此,这里主要考虑使用方案2。
在前面分析的过程中,已经明确,是由于触发了Linux的虚拟内存保护,导致fork失败。可以通过修改/proc/sys/vm/overcommit_memory的值,来修改系统的虚拟内存保护策略。这个文件可以取0、1、2三个值,含义如下:
 0-Heuristic overcommit handling
0是LINUX系统的默认值。允许进程申请的内存超出一个合理(reasonable)值,如果进程申请超出的过多,则内存分配会被拒绝。如果进程超出范围在合理值内,则也有可能触发omm-kill,导致进程被杀死。
 1-Always overcommit
接收进程申请的任何内存大小
 2-Don’t overcommit
不允许超出内存总量。内存总量受另外一个参数overcommit_ratio控制,系统总可用内存计算公式如下:
总可用内存 = (swap space + RAM size * overcommit_ratio)
可以使用该选项为系统预留一定量的内存。overcommit_ratio参数可通过修改/proc/sys/vm/overcommit_ratio设置。
考虑到我们的代码中出了system外,并没有fork的需求,而且system在执行fork后会立即调用exec释放掉申请的空间,因此我们将overcommit_memory设置为1。

system函数调用失败相关推荐

  1. linux调用一个函数失败 打印错误,linux下settimeofday函数调用失败,何故?解决办法...

    当前位置:我的异常网» C语言 » linux下settimeofday函数调用失败,何故?解决办法 linux下settimeofday函数调用失败,何故?解决办法 www.myexceptions ...

  2. 关于对话框DoModal()函数调用失败的原因分析

    对话框DoModal()函数调用失败一般而言有两种表现形式:一是对话框弹不出来,但是没有错误提示:二是对话框弹不出来,同时伴随内存访问错误的提示框出现. 第一种表现主要是因为没有对资源句柄进行切换造成 ...

  3. 云函数调用失败的原因

    云函数调用失败的原因 关于第一个云函数在网上都可以查到 不过也会出现很多问题 本文主要讲解的是出现的问题如何解决 首先在云函数段一定要写上这三段 // 云函数入口文件 const cloud = re ...

  4. Maven执行mvn help:system命令失败的特殊原因解决思路

    maven安装成功,但是执行mvn help:system命令却总是出现问题,在网上查找了各种资料,花费了大量时间,始终都没有成功,最后通过百度网盘下载资料到自己定义的maven本地仓库时发现,出现了 ...

  5. ualarm()函数调用失败以及浅析

    ualarm()函数浅析 函数原型 //come from /usr/include/unistd.h extern __useconds_t ualarm(__useconds_t __value, ...

  6. 项目实训(十)引入mudule后System.loadLibrary失败天坑

    我使用Android Studio的include C++生成了一个项目,然后Import一个module,这个module也是一个含有C++代码和CmakeLists的项目.然后编译也全部通过了,我 ...

  7. php system 执行失败,PHP 执行 system、exec 等函数发生错误

    2012-12-06 20:45 1932人阅读 评论(0) 往往在调用system.exec 等函数时,要么没有反应,要么出错: 原因很多,以下是抄别人的: ==================== ...

  8. php system 执行失败,php执行system()函数没有任何反应

    浏览量: 361 引言 最近需要用php调用本地Linux命令,来实现一些功能. 在网上搜了一下发现,PHP提供4个专门的执行外部命令的函数:exec(), system(), passthru(), ...

  9. c语言调用system返回值,在C语言中获取用system函数调用shell的返回值

    一般我们调用shell脚本都用system()来实现,然后发现sytem返回值不好控制而且转换麻烦(还要右移4位即/256),于是我用popen来获取shell的返回值.果然在Unix世界里面,通道就 ...

最新文章

  1. CList 点击表头排序 (1)SortItems函数
  2. ubuntu 设置开机执行脚本_Ubuntu 16.04设置rc.local开机启动命令/脚本的方法
  3. @autowired失败_@Autowired的使用:推荐对构造函数进行注释
  4. 【bzoj5452】[Hnoi2016]大数(莫队)
  5. accumulate
  6. 【一天一个C++小知识】002.C++中const和volatile关键字
  7. 市民卡怎么登录显示服务器繁忙,2分钟办理一笔业务 杭州网记者体验最具人气的“市民卡”窗口服务...
  8. 《HiWind企业快速开发框架实战》(2)使用HiWind创建自己的项目
  9. 36.windbg-!peb(手工分析PEB结构)
  10. iOS手势缩放字体大小
  11. 【洛谷试炼场】洛谷新手村——洛谷的第一个任务
  12. mp4播放器带后台开源源码
  13. 动态拨号主机多IP随机分配拨号自动分配
  14. java解析8583报文55域
  15. MFC界面布局、效果
  16. kali虚拟机配置成桥接模式
  17. springboot学校快递站点管理系统的设计与实现毕业设计源码111544
  18. FPGA学习之数模转换(TLC5620)(通过4个按键输入,输出数模转换需要的数据和数码管显示需要的数据)
  19. android 代码规范检测工具,Android 代码规范之Inspection 定制
  20. 你会想谈一场诗书传情,相知相敬的爱情吗?

热门文章

  1. 学生台灯用暖光好还是白光好?光线柔和的暖光护眼灯推荐
  2. 【Matlab程序设计知识点合集】新手入门第十五天
  3. RobWork框架编程(2):使用雅可比数值迭代算法对机器人进行逆运动学求解
  4. Nuvoton,新唐官网,OpenNuvoton,新唐gitee仓库
  5. 英语口语理论技巧汇总(持续更新)
  6. 安卓机更新系统会卡吗_安卓手机真的越用越卡?看完你就明白了
  7. Ubuntu20.04 设置开机自启
  8. CMake教程(二)- 添加静态库文件和动态库文件
  9. docker study --- shim
  10. 对话智领云CTO宋文欣:读懂云原生时代的数据中台