Eu costumo executar um programa como:
./a.out arg1 arg2 <file
Eu gostaria de depurá-lo usando o gdb.
Estou ciente da set argsfuncionalidade, mas isso só funciona a partir do prompt gdb.
Eu costumo executar um programa como:
./a.out arg1 arg2 <file
Eu gostaria de depurá-lo usando o gdb.
Estou ciente da set argsfuncionalidade, mas isso só funciona a partir do prompt gdb.
Respostas:
Passe os argumentos para o runcomando no gdb.
$ gdb ./a.out
(gdb) r < t
Starting program: /dir/a.out < t
$ gdb ./a.out, o (gdb) r < t arg1 arg2que funciona bem para mim. No meu caso a.out = nft arg1 = import arg2 = json et = file containing json rules
Você consegue fazer isso:
gdb --args path/to/executable -every -arg you can=think < of
O ser mágico --args.
Basta digitar runno console de comando gdb para iniciar a depuração.
--args, não há argumentos passados para o executável, por isso não é ambíguo.
argv[0]é o nome do executável
gdbsi para o ofarquivo e resultar em gdb tentando executar comandos a partir dele
Se você deseja ter o runcomando bare gdbpara executar seu programa com redirecionamentos e argumentos, você pode usar set args:
% gdb ./a.out
(gdb) set args arg1 arg2 <file
(gdb) run
Não consegui obter o mesmo comportamento com o --argsparâmetro, gdbescapou ferozmente dos redirecionamentos, ou seja,
% gdb --args echo 1 2 "<file"
(gdb) show args
Argument list to give program being debugged when it is started is "1 2 \<file".
(gdb) run
...
1 2 <file
...
Este realmente redireciona a entrada do próprio gdb, não o que realmente queremos aqui
% gdb --args echo 1 2 <file
zsh: no such file or directory: file
Inicie o GDB em seu projeto.
Vá para o diretório do projeto, onde você já compilou o executável do projeto. Emita o comando gdb e o nome do executável como abaixo:
gdb projectExecutablename
Isso inicia o gdb, imprime o seguinte: GNU gdb (Ubuntu 7.11.1-0ubuntu1 ~ 16.04) 7.11.1 Copyright (C) 2016 Free Software Foundation, Inc. ............... .................................. Digite "palavra apropriada" para procurar comandos relacionados à "palavra". Lendo símbolos do projetoExecutablename ... done. (gdb)
Antes de iniciar a execução do programa, você deseja configurar seus pontos de interrupção. O comando break permite que você faça isso. Para definir um ponto de interrupção no início da função denominada main:
(gdb) b principal
Depois de ter o prompt (gdb), o comando run inicia a execução do executável. Se o programa que você está depurando exigir argumentos da linha de comando, especifique-os para o comando run. Se você deseja executar o meu programa no arquivo "xfiles" (que está em uma pasta "mulder" no diretório do projeto), faça o seguinte:
(gdb) r mulder / xfiles
Espero que isto ajude.
Isenção de responsabilidade: Esta solução não é minha, é adaptada de https://web.stanford.edu/class/cs107/guide_gdb.html Este pequeno guia para gdb foi, provavelmente, desenvolvido na Universidade de Stanford.
Não seria legal digitar debugna frente de qualquer comando para poder depurá-lo gdbno nível do shell?
Abaixo dela esta função. Até funciona com o seguinte:
"$program" "$@" < <(in) 1> >(out) 2> >(two) 3> >(three)
Esta é uma chamada em que você não pode controlar nada, tudo é variável, pode conter espaços, feeds de linha e metacaracteres de shell. Neste exemplo, in, out, two, e threesão outros comandos arbitrários que consomem ou dados de produzir que não devem ser prejudicadas.
A bashfunção a seguir chama gdbquase de forma limpa em um ambiente como esse [ Gist ]:
debug()
{
1000<&0 1001>&1 1002>&2 \
0</dev/tty 1>/dev/tty 2>&0 \
/usr/bin/gdb -q -nx -nw \
-ex 'set exec-wrapper /bin/bash -c "exec 0<&1000 1>&1001 2>&1002 \"\$@\"" exec' \
-ex r \
--args "$@";
}
Exemplo de como aplicar isso: basta digitar debugna frente:
Antes:
p=($'\n' $'I\'am\'evil' " yay ")
"b u g" "${p[@]}" < <(in) 1> >(out) 2> >(two) 3> >(three)
Depois de:
p=($'\n' $'I\'am\'evil' " yay ")
debug "b u g" "${p[@]}" < <(in) 1> >(out) 2> >(two) 3> >(three)
É isso aí. Agora é um acéfalo absoluto para depurar gdb. Exceto por alguns detalhes ou mais:
gdbnão fecha automaticamente e, portanto, mantém o redirecionamento de entrada / saída aberto até você sair gdb. Mas eu chamo isso de recurso.
Você não pode passar facilmente argv0para o programa como com exec -a arg0 command args. A seguir, faça este truque: Depois de exec-wrapperalterar "execpara "exec -a \"\${DEBUG_ARG0:-\$1}\".
Existem DFs acima de 1000 abertos, que normalmente são fechados. Se isso for um problema, altere 0<&1000 1>&1001 2>&1002para ler0<&1000 1>&1001 2>&1002 1000<&- 1001>&- 1002>&-
Você não pode executar dois depuradores em paralelo. Também pode haver problemas, se algum outro comando consumir /dev/tty(ou STDIN). Para corrigir isso, substitua /dev/ttypor "${DEBUGTTY:-/dev/tty}". Em algum outro tipo de TTY tty; sleep infe, em seguida, use o TTY impresso (ie. E. /dev/pts/60) para depuração, como em DEBUGTTY=/dev/pts/60 debug command arg... Esse é o poder da Shell, se acostume!
Função explicada:
1000<&0 1001>&1 1002>&2 afasta os 3 primeiros FDs
0</dev/tty 1>/dev/tty 2>&0restaura os 3 primeiros FDs para apontar para o seu TTY atual. Então você pode controlar gdb./usr/bin/gdb -q -nx -nwexecuta gdbinvoca gdbno shell-ex 'set exec-wrapper /bin/bash -c "exec 0<&1000 1>&1001 2>&1002 \"\$@\"" cria um wrapper de inicialização, que restaura os 3 primeiros FDs salvos em 1000 e acima-ex r inicia o programa usando o exec-wrapper--args "$@" passa os argumentos como dadoIsso não foi fácil?
ré curtorune você pode segui-lo com qualquer argumento. Como nesta questão, seria:r arg1 arg2 <fileou poderia serrun arg1 arg2 <file