www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Possible runtime bug in preprocessing of command line arguments passed

reply Basile B. <b2.temp gmx.com> writes:
The following code, on linux

```d
module runnable;
​
extern(C) int execv(const char* p, const char** args);
​
immutable src = `
     import std.getopt;
     void main(string[] args)
     {
         bool c;
         getopt(args, "c", &c);
     }
`;
​
void prepareProgram()
{
     import std.process  : execute;
     import std.file     : write;
     write("a.d", src);
     execute(["dmd", "a.d"]);
}
​
void main(string[] args)
{
     prepareProgram();
     execv("a", null);
}
```

results in a std.getopt exception:

 object.Exception /usr/include/dmd/phobos/std/getopt.d(423): 
 Invalid arguments string passed: program name missing
Context is a program not written in D that uses execv to call a D program that uses getopt. What do you think ?
Oct 24 2021
next sibling parent Basile B. <b2.temp gmx.com> writes:
On Sunday, 24 October 2021 at 14:21:52 UTC, Basile B. wrote:
 The following code, on linux
 [...]
 What do you think ?
Forgot to say that this change ```diff - execv("a", null); + execv("a", ["whatever".ptr].ptr); ``` makes the problem goes away, so it would be caused by how `null` args are handled, presumably.
Oct 24 2021
prev sibling parent reply jfondren <julian.fondren gmail.com> writes:
On Sunday, 24 October 2021 at 14:21:52 UTC, Basile B. wrote:
 What do you think ?
I'm very surprised that this is even allowed. Apparently it's Linux userspace that normally complains about it: https://git.savannah.gnu.org/cgit/gnulib.git/tree/lib/progname.c#n54 The manpages just say ``` v - execv(), execvp(), execvpe() The char *const argv[] argument is an array of pointers to null-terminated strings that represent the argument list available to the new program. The first argument, by convention, should point to the filename associated with the file being executed. The array of pointers must be terminated by a null pointer. ``` With nothing to the contrary, I'd take "must be terminated by a null pointer" as "can't itself be a null pointer". On OpenBSD this fails outright: ``` RET execve -1 errno 14 Bad address ``` You can get `execv` from `core.sys.posix.unistd`
Oct 24 2021
next sibling parent Basile B. <b2.temp gmx.com> writes:
On Sunday, 24 October 2021 at 14:38:44 UTC, jfondren wrote:
 [...]

 With nothing to the contrary, I'd take "must be terminated by a 
 null pointer" as "can't itself be a null pointer".
ah yeah, and thanks, of course ... how would the count of arg be known without the sentinel...
Oct 24 2021
prev sibling parent Brian Callahan <bcallah openbsd.org> writes:
On Sunday, 24 October 2021 at 14:38:44 UTC, jfondren wrote:
 With nothing to the contrary, I'd take "must be terminated by a 
 null pointer" as "can't itself be a null pointer".
The execve(2) is more explicit: "The argument argv is a pointer to a null-terminated array of character pointers to NUL-terminated character strings. These strings construct the argument list to be made available to the new process. At least one non-null argument must be present in the array; by custom, the first element should be the name of the executed program (for example, the last component of path)."
Oct 24 2021