考虑遵循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
)会失败或出现意外行为。
答案 0 :(得分:3)
execve()
系统调用的手册页说
argv
和envp
数组必须每个都包含数组末尾的空指针。
如果你的程序不符合这些要求,那么从那时起事情就不会有多好。如果某些程序“有用”,那就太糟糕了。
手册页也说
按照惯例,这些字符串中的第一个(即
argv[0]
)应包含与正在执行的文件关联的文件名。
该约定相当强大(由POSIX强制执行),因此未能执行此操作的程序可被视为错误。如果您要依赖main()
,那么您的argv[0]
测试它已被正确调用可能是一个好主意,因此您可能会因为错误消息而不是错误而失败,但并非所有程序都会