It appears that your SHELL variable is set to a file that doesn't exist. Try the following:
/bin/sh exists and is executable. This works via
su not because of root permissions, but because
su resets the
SHELL environment variable. Per the su manual page:
Note that the default behavior for the environment is the following:
The $HOME, $SHELL, $USER, $LOGNAME, $PATH, and $IFS environment variables are reset.
If you are asking yourself, "How was I supposed to know that from the following error message?":
//error: Cannot exec /home/xxx/test/test -c exec /home/xxx/test/test .
//Error: No such file or directory
You are not alone. This appears to be poor error reporting from
gdb decides that it needs to execute your command using a shell, it constructs a command in the following format:
/path/to/shell -c exec /path/to/executable
However, when it prints the error message, it does this:
save_errno = errno;
fprintf_unfiltered (gdb_stderr, "Cannot exec %s", exec_file);
for (i = 1; argv[i] != NULL; i++)
fprintf_unfiltered (gdb_stderr, " %s", argv[i]);
fprintf_unfiltered (gdb_stderr, ".\n");
fprintf_unfiltered (gdb_stderr, "Error: %s\n",
exec_file is the expanded path of the file you passed on the command line. It prints
exec_file first, followed by the elements of
argv, starting at the 1st index.
argv contains the arguments it passed to
Unfortunately, the shell it is trying to use is in the 0th element of
argv, which never gets printed. Thus, you never see the file that
execvp couldn't find.
Further, it then prints a trailing
. which isn't actually one of the arguments that it passed to
execvp and is presumably there to make the message a completely sentence.
Finally, it prints the error we got back from our call to
execvp, which is that the executable file could not be found.
This bug likely is caused by the fact that this error handling code is the same for the case where
gdb attempts to exec the command directly and for the case when it uses the shell. In the former case, the constructed error message would look correct since
argv would be the same.