问题描述
我最近刚刚在探索 execve() 系统函数。这段代码可能没有多大意义,但这不是这个问题的主要焦点。 (自从使用 this 线程以来,我设法使其正常工作。
我遇到了一个非常奇怪的行为,想要一个解释或确认这样的事情不应该发生。
“被窃听”的代码是这样的:
#include <unistd.h>
int main(int argc,char **argv,char **env)
{
if (argc != 2)
return (ERROR_CODE);
char *test[] = { argv[1] };
char *a[] = { NULL };
execve(argv[1],test,env);
return (SUCCESS_CODE);
}
使用参数编译和执行它会正确执行该函数,在我的例子中:
$> gcc main.c
$> ./a.out "/bin/ls"
char *a[] = { NULL };
这个变量显然没有使用,完全没用。 再次执行相同的步骤,出于某种原因,它不输出任何内容,这个随机变量对我来说破坏了代码。 (我使用 Gnome 3.36.8 和 gcc 9.3.0 运行 Ubuntu 20.04)。
如果您需要有关我的操作系统或任何其他内容的更多信息,请随时询问。
PS:我想我理解代码试图解决这个问题的方式,但这对我来说没有意义。
$> man execve
main(int argc,char *argv[])
char *newargv[] = { NULL,"hello","world",NULL };
...
execve(argv[1],newargv,newenviron);
手动示例以空终止“newargv”,我的想法是不知何故,编译器决定将我的变量“test”和“a”融合在一起,以空终止“test”?
解决方法
是的,您意外看到了“融合”,因为您没有正确地用 argv
终止 NULL
并且内存布局恰好对您有利.如果你不那么幸运,你会在那里得到垃圾,或者段错误。
参数 argv
是一个指向空终止数组的指针,该数组由指向空终止字符串的字符指针组成。
#include <unistd.h>
int main(int argc,char **argv,char **env)
{
if (argc != 2)
return (ERROR_CODE);
char *test[] = { argv[1],NULL };
execve(argv[1],test,env);
return (SUCCESS_CODE);
}
应该是正确的调用。