GDB 无法执行我的测试程序

Dar*_*rse 5 shell gdb exec

我的电脑运行 Ubuntu 14.04。GDB在不同的账户中似乎异常。例如我做了一个非常简单的测试。我在下面写了一个文件~/test/test.c

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    printf("hello,world");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

并使用命令"gcc -g test.c -o test"构建,然后我得到名为 test 的结果文件。下一步,运行 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
Run Code Online (Sandbox Code Playgroud)

但是如果我通过命令“su”更改为 root 帐户,gdb 运行良好。为什么?

Ste*_*n D 5

看来您的 SHELL 变量设置为不存在的文件。请尝试以下操作:

export SHELL=/bin/sh
gdb test
Run Code Online (Sandbox Code Playgroud)

确保/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
Run Code Online (Sandbox Code Playgroud)

你不是一个人。这似乎是来自gdb. 当gdb决定需要使用 shell 执行您的命令时,它会按以下格式构造命令:

/path/to/shell -c exec /path/to/executable
Run Code Online (Sandbox Code Playgroud)

但是,当它打印错误消息时,它会执行以下操作:

  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);
Run Code Online (Sandbox Code Playgroud)

exec_file是您在命令行上传递的文件的扩展路径。它exec_file首先打印,然后是 的元素argv,从第一个索引开始。 argv包含它传递给的参数execvp

不幸的是,它尝试使用的外壳位于 的第 0 个元素中argv,它永远不会被打印出来。因此,您永远不会看到execvp找不到的文件。

此外,它然后打印一个尾随.,它实际上不是它传递给的参数之一,execvp并且可能在那里使消息成为一个完整的句子。

最后,它打印我们从调用 中得到的错误execvp,即找不到可执行文件。

这个错误很可能是由于这个错误处理代码对于gdb尝试直接执行命令的情况和使用 shell的情况是相同的。在前一种情况下,构造的错误消息看起来是正确的,exec_file并且argv[0]是相同的。