【Linux】【编译相关】execvp: /bin/sh: Argument list too long问题处理小结

简介: 【Linux】【编译相关】execvp: /bin/sh: Argument list too long问题处理小结

问题背景


execvp: /bin/sh: Argument list too long问题出现的两种情况:


  • 1、make的时候,如编译Linux内核、驱动、Android版本等较长-I、-D选项的情况;


  • 2、shell操作,涉及较多文件的情况,如删除大量文件时,直接用rm;


问题原因


1、错误来源于sysdeps/gnu/errlist.c文件中:


[ERR_REMAP (E2BIG)] = N_("Argument list too long"),


可据此找到对应Linux内核中exec.c中返回E2BIG的地方,实际和ARG_MAX有很大关系。


2、参考APUE,ARG_MAX的值在运行时间不变的值,但值可能不确定。


ARG_MAX的值实际上和下面参数有关系:


 - MAX_ARG_STRLEN #单个字符串的最大大小
 - MAX_ARG_STRINGS #参数个数的限制
 - MAX_ARG_PAGES #分配给参数的最大页数
 - stack size #堆栈空间
 - ARG_MAX in limits.h #参数的最大长度


实际上,不同内核的版本也有区别。


几个命令执行情况的例子:


[qxhgd@localhost]getconf ARG_MAX
2897152
[qxhgd@localhost]ulimit -s
8192
[qxhgd@localhost]xargs --show-limits 
Your environment variables take up 4222 bytes
POSIX upper limit on argument length (this system): 2090882
POSIX smallest allowable upper limit on argument length (all systems): 4096
Maximum length of command we could actually use: 2086660
Size of command buffer we are actually using: 131072


问题解决


几种思路


  • 修改主机环境:


  • 调整shell命令或makefile本身;


修改主机环境


据说,Linux内核可通过修改下面参数来规避,具体没做实验。


/*
* MAX_ARG_PAGES defines the number of pages allocated for arguments
* and envelope for the new program. 32 should suffice, this gives
* a maximum env+arg of 128kB w/4KB pages!
*/
#define MAX_ARG_PAGES 32


其他几个参数也可根据需要调整。


shell操作场景


  • 以rm为例,一般配合xargs利用管道来解决:
    find . -name “" | xargs rm -rf "” 就行


  • 也可以通过shell来执行:


#!/bin/bash
# 设定需要删除的文件夹
RM_DIR='/testdir/to-del-all'
cd $RM_DIR
for I in `ls`
do
  rm -f $I


make场景


1、对于-I路径


  • 去除冗余的-I路径


如某模块在增加-I路径的时候,没有确认是否真的需要,只是参考其他模块直接copy的。


  • 将路径包含设法缩短


如有的路径里有类似这种A/xx/yy…/…/的,就可以优化一下;
另外,也可以用软链接来缩短路径;


  • 将需要的头文件整合到一个目录中。


2、对于-D选项


  • 可以将相关-D选项生成.h文件,直接include相关.h文件。


命令汇总


getconf ARG_MAX     #查看系统配置参数ARG_MAX
sys/limits.h #头文件
xargs --show-limits #xargs查看各种参数的长度
MAX_ARG_STRLEN  #include/linux/binfmts.h文件
cat /proc/$$/environ | wc -c #查看环境变量长度;
ulimit -s  #查看或修改线程默认栈空间
echo $(( $(getconf PAGE_SIZE)*32 )) ##查看PAGE_SIZE


参考资料



  • APUE



相关文章
|
Linux 编译器 开发工具
【Linux快速入门(三)】Linux与ROS学习之编译基础(Cmake编译)
【Linux快速入门(三)】Linux与ROS学习之编译基础(Cmake编译)
936 2
|
Ubuntu Linux Go
golang编译成Linux可运行文件
本文介绍了如何在 Linux 上编译和运行 Golang 程序,涵盖了本地编译和交叉编译的步骤。通过这些步骤,您可以轻松地将 Golang 程序编译成适合 Linux 平台的可执行文件,并在目标服务器上运行。掌握这些技巧,可以提高开发和部署 Golang 应用的效率。
3213 14
|
Linux 编译器 C语言
【Linux快速入门(一)】Linux与ROS学习之编译基础(gcc编译)
【Linux快速入门(一)】Linux与ROS学习之编译基础(gcc编译)
568 2
|
Linux API 开发工具
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
ijkplayer是由B站研发的移动端播放器,基于FFmpeg 3.4,支持Android和iOS。其源码托管于GitHub,截至2024年9月15日,获得了3.24万星标和0.81万分支,尽管已停止更新6年。本文档介绍了如何在Linux环境下编译ijkplayer的so库,以便在较新的开发环境中使用。首先需安装编译工具并调整/tmp分区大小,接着下载并安装Android SDK和NDK,最后下载ijkplayer源码并编译。详细步骤包括环境准备、工具安装及库编译等。更多FFmpeg开发知识可参考相关书籍。
948 0
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
|
Linux 编译器 C语言
Linux c/c++之多文档编译
这篇文章介绍了在Linux操作系统下使用gcc编译器进行C/C++多文件编译的方法和步骤。
282 0
Linux c/c++之多文档编译
|
Oracle Java 关系型数据库
Linux下JDK环境的配置及 bash: /usr/local/java/bin/java: cannot execute binary file: exec format error问题的解决
如果遇到"exec format error"问题,文章建议先检查Linux操作系统是32位还是64位,并确保安装了与系统匹配的JDK版本。如果系统是64位的,但出现了错误,可能是因为下载了错误的JDK版本。文章提供了一个链接,指向Oracle官网上的JDK 17 Linux版本下载页面,并附有截图说明。
Linux下JDK环境的配置及 bash: /usr/local/java/bin/java: cannot execute binary file: exec format error问题的解决
用clang编译Linux内核
用clang编译Linux内核
|
Linux C语言
深度探索Linux操作系统 —— 编译过程分析
深度探索Linux操作系统 —— 编译过程分析
229 2
|
Ubuntu Linux Windows
如何在WSL中的ubuntu编译Linux内核并且安装使用ebpf?
请注意,在WSL1中可能会由于内核架构限制而无法成功进行以上过程,WSL2对于Linux内核的完整支持更为合适。此外,部分步骤可能因不同的Linux发行版或内核版本而异。
1224 4
|
Linux
Linux - 如何编译源码安装软件
源码编译安装通常包括三个步骤:1) `./configure` 检测平台特征和依赖项,生成 Makefile;2) `make` 编译源码,生成可执行文件;3) `make install` 将可执行文件安装到指定目录并配置环境变量。
575 0