转载时请注明出处和作者联系方式
文章出处:http://www.limodev.cn/blog
作者联系方式:李先静 <xianjimli at hotmail dot com>
这两天在Android eclair版本上增加WML浏览功能,以前在cupcake版本(broncho a1)上实现过,技术上倒是没有什么难题,但编译时总是出现Argument list too long的错误。WebKit里源文件太多,没有WML时还可以编译过去,但加上了WML之后,命令行参数确实很长了,ar后面跟的参数大概都有几百K。奇怪的是,在终端单独运行ar没有问题,但是在Makefile里就是不行。
先尝试去改Android.mk,把它分成几个静态库来编译,但老是编译不过去,试一次要很长时间,真的很烦。后来只好尝试去找出这个长度限制在哪里:
1.这个错误是glibc打出来,所以先到glibc里去找Argument list too long对应错误码。在sysdeps/gnu/errlist.c找到这样一行代码:
[ERR_REMAP (E2BIG)] = N_("Argument list too long"),
很明显,错误码就是E2BIG。
2.错误码应该是exec系统调用返回的,于是到内核里去查找返回E2BIG的代码,在exec.c里找到几处:
static int count(char __user * __user * argv, int max)
{
int i = 0;
if (argv != NULL) {
for (;;) {
char __user * p;
if (get_user(p, argv))
return -EFAULT;
if (!p)
break;
argv++;
if (i++ >= max)
return -E2BIG;
cond_resched();
}
}
return i;
}
bprm->argc = count(argv, MAX_ARG_STRINGS);
if ((retval = bprm->argc) < 0)
goto out;
bprm->envc = count(envp, MAX_ARG_STRINGS);
if ((retval = bprm->envc) < 0)
goto out;
这是对参数个数的限制,MAX_ARG_STRINGS的定义为:
#define MAX_ARG_STRINGS 0x7FFFFFFF
这个值已经大得吓人了,不可能是参数个数超出了。
另外一处是:
static int copy_strings(int argc, char __user * __user * argv,
struct linux_binprm *bprm)
{
struct page *kmapped_page = NULL;
char *kaddr = NULL;
unsigned long kpos = 0;
int ret;
while (argc-- > 0) {
char __user *str;
int len;
unsigned long pos;
if (get_user(str, argv+argc) ||
!(len = strnlen_user(str, MAX_ARG_STRLEN))) {
ret = -EFAULT;
goto out;
}
if (!valid_arg_len(bprm, len)) {
ret = -E2BIG;
goto out;
}
...
}
#ifdef CONFIG_MMU
static bool valid_arg_len(struct linux_binprm *bprm, long len)
{
return len <= MAX_ARG_STRLEN;
}
static bool valid_arg_len(struct linux_binprm *bprm, long len)
{
return len <= bprm->p;
}
#endif /* CONFIG_MMU */
valid_arg_len是用来限制单个参数长度的,PC上肯定是定义了CONFIG_MMU的,所以单个参数的长度应该是MAX_ARG_STRLEN,即:
#define MAX_ARG_STRLEN (PAGE_SIZE * 32)
对于4K的page大小来说,单个参数长度限制是128K, 这也够大了。不过如果前面所说的整个ar命令,在Makefile里被当作一个参数的话,那肯定是超长了。这可以解释在终端单独运行ar没有问题,在 Makefile调用不行的疑问。回头再研究一下Makefile里是怎么调用的吧。
Argument list too long从何而来
解决Android编译Argumentlisttoolong问题
最新推荐文章于 2024-08-11 15:24:38 发布
本文探讨了在Android项目的WebKit模块中加入WML支持时遇到的编译问题——Argumentlisttoolong。通过深入分析glibc和Linux内核源码,作者找到了导致该问题的原因,并提出了解决方案。
829

被折叠的 条评论
为什么被折叠?



