我的电脑运行 Ubuntu 14.04。 GDB在不同的账户下好像不正常。例如我做了一个非常简单的测试。我在下面写了一个文件,~/test/test.c
如下所示:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
printf("hello,world");
return 0;
}
并使用命令构建“gcc -g 测试.c -o 测试”,然后我得到名为 test.txt 的结果文件。下一步,运行gdb进行调试。请注意,当前帐户是我自己的用户。
$gdb test
(gdb)l //work well
(gdb) b 6 //work well
(gdb) r //error: Cannot exec /home/xxx/test/test -c exec /home/xxx/test/test .
//Error: No such file or directory
但如果我通过命令“su”更改为root帐户,gdb就可以正常工作。为什么?
答案1
您的 SHELL 变量似乎被设置为一个不存在的文件。请尝试以下操作:
export SHELL=/bin/sh
gdb test
确保/bin/sh
存在并且可执行。这su
不是因为 root 权限起作用,而是因为su
重置了SHELL
环境变量。根据su 手册页:
请注意,环境的默认行为如下:
$HOME、$SHELL、$USER、$LOGNAME、$PATH 和 $IFS 环境变量将被重置。
进一步讨论
如果您问自己,“我如何从以下错误消息中知道这一点?”:
//error: Cannot exec /home/xxx/test/test -c exec /home/xxx/test/test .
//Error: No such file or directory
你并不孤单。这似乎是来自 的错误报告gdb
。当gdb
决定需要使用 shell 执行您的命令时,它会按以下格式构造一个命令:
/path/to/shell -c exec /path/to/executable
但是,当它打印错误消息时,它会执行以下操作:
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",
safe_strerror (save_errno));
gdb_flush (gdb_stderr);
这exec_file
是您在命令行上传递的文件的扩展路径。它exec_file
首先打印,然后是 的元素argv
,从第一个索引开始。 argv
包含它传递给 的参数execvp
。
不幸的是,它尝试使用的 shell 位于 的第 0 个元素中argv
,它永远不会被打印。因此,您永远不会看到execvp
找不到的文件。
此外,它然后打印一个尾随.
,该尾随实际上不是它传递给的参数之一execvp
,并且可能是为了使消息成为一个完整的句子。
最后,它打印我们从调用返回的错误execvp
,即找不到可执行文件。
此错误可能是由于以下事实引起的:对于尝试直接执行命令的情况gdb
和使用 shell 的情况,此错误处理代码是相同的。在前一种情况下,构造的错误消息看起来是正确的,因为exec_file
和argv[0]
是相同的。