将空程序参数向量传递给execve()是否合法?

时间:2017-08-01 06:07:24

标签: c linux gdb exec system-calls

考虑遵循C代码(x86_64)

#include <unistd.h>
int main()
{
    execve("/bin/ls", 0, 0);
}

我编译为gcc a.c并执行;我收到了SIGABRT错误

   
A NULL argv[0] was passed through an exec system call.  
Aborted

接下来在gdb上运行,起初我也得到了SIGABRT,但是我做了第二次运行并且它运行了!

Starting program: /bin/ls 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

为什么?

我测试了/bin/sh并发现它始终与* argv [] = NULL ...
一起使用 我再次写了一些可执行文件(不需要任何参数)来测试并发现它们都能正常工作。

所以我猜只有/bin/sh或其他shell才能将* argv []设置为NULL,其他文件(如/bin/ls)会失败或出现意外行为。

1 个答案:

答案 0 :(得分:3)

execve()系统调用的手册页说

  

argvenvp数组必须每个都包含数组末尾的空指针。

如果你的程序不符合这些要求,那么从那时起事情就不会有多好。如果某些程序“有用”,那就太糟糕了。

手册页也说

  

按照惯例,这些字符串中的第一个(即argv[0])应包含与正在执行的文件关联的文件名。

该约定相当强大(由POSIX强制执行),因此未能执行此操作的程序可被视为错误。如果您要依赖main(),那么您的argv[0]测试它已被正确调用可能是一个好主意,因此您可能会因为错误消息而不是错误而失败,但并非所有程序都会