Consider following C code (x86_64)
#include <unistd.h>
int main()
{
execve("/bin/ls", 0, 0);
}
I compiled as gcc a.c
and executed; I got a SIGABRT
with error
A NULL argv[0] was passed through an exec system call. Aborted
Next running on gdb, at first I also got a SIGABRT
, however I did second run and it worked!
Starting program: /bin/ls [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Why?
I tested for /bin/sh
and found it always worked with *argv[] = NULL ...
Again I wrote some executable file (without any parameter needed) to test and found all them work.
So I guess only /bin/sh
or other shells would work with *argv[] set to NULL, other files (like /bin/ls
) fail or behave unexpectedly.
The man page for the execve()
system call says
The
argv
andenvp
arrays must each include a null pointer at the end of the array.
If your program doesn't conform to those requirements, there's no certainty of how well things will go from that point on. If it "works" for some programs, that's just bad luck.
The man page also says
By convention, the first of these strings (i.e.,
argv[0]
) should contain the filename associated with the file being executed.
That convention is rather strong (mandated by POSIX), so programs that fail to do so can be considered buggy. It's probably a good idea for your main()
to test it's been called correctly if you're going to rely on argv[0]
so you can fail with a nice error message rather than a fault, but not all programs do.