GDB não pode executar meu programa de teste

5

Meu computador roda com o Ubuntu 14.04. GDB parece ser anormal em conta diferente. Por exemplo, faço um teste muito simples. Eu escrevo um arquivo em ~/test/test.c assim:

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

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

e construa com o comando "gcc -g test.c -o teste" , então recebo o arquivo de resultado chamado test. Na próxima etapa, execute o gdb para depurar. Observe que a conta atual é de meu próprio usuário.

$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

Mas se eu mudar para a conta root pelo comando "su", o gdb funciona bem. Por quê?

    
por DarkHorse 14.11.2014 / 08:21

1 resposta

3

Parece que sua variável SHELL está definida para um arquivo que não existe. Tente o seguinte:

export SHELL=/bin/sh
gdb test

garantindo que /bin/sh exista e seja executável. Isso funciona por meio de su não por causa das permissões raiz, mas porque su redefine a variável de ambiente SHELL . Por 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.

Discussão adicional

Se você está se perguntando: "Como eu poderia saber isso da seguinte mensagem de erro?":

//error: Cannot exec /home/xxx/test/test -c exec /home/xxx/test/test .
//Error: No such file or directory

Você não está sozinho. Este parece ser um relatório de erros insuficiente de gdb . Quando gdb decide que precisa executar seu comando usando um shell, ele constrói um comando no seguinte formato:

/path/to/shell -c exec /path/to/executable

No entanto, quando ele imprime a mensagem de erro, ele faz isso:

  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);

Aqui exec_file é o caminho expandido do arquivo que você passou na linha de comando. Ele imprime exec_file primeiro, seguido pelos elementos argv , começando no primeiro índice. argv contém os argumentos passados para execvp .

Infelizmente, o shell que ele está tentando usar está no 0º elemento de argv , que nunca é impresso. Assim, você nunca verá o arquivo que execvp não conseguiu encontrar.

Além disso, ele imprime um . à direita que não é, na verdade, um dos argumentos passados para execvp e, presumivelmente, está lá para tornar a mensagem uma sentença completa.

Finalmente, imprime o erro que recebemos de nossa chamada para execvp , que é que o arquivo executável não pôde ser encontrado.

Esse erro provavelmente é causado pelo fato de que esse código de tratamento de erros é o mesmo para o caso em que gdb tenta executar o comando diretamente e para o caso em que ele usa o shell. No primeiro caso, a mensagem de erro construída pareceria correta, pois exec_file e argv[0] seriam os mesmos.

    
por 14.11.2014 / 13:45

Tags