Recupera o comando completo que gerou o core dump

3

Um programa em que estou trabalhando está falhando e gerando despejos principais. Eu acho que o problema está relacionado aos argumentos que estão sendo chamados, alguns dos quais são gerados automaticamente por outro programa (bastante complicado). Então, tentei usar gdb para depurar ou file core.MyApplication.1234 para obter os argumentos.

No entanto, o comando é bastante longo e a saída é parecida com:

core.MyApplication.1234: ELF 64-bit LSB core file x86-64, version 1 (SYSV), SVR4-style, from './MyApplication -view -mwip localhost -mwnp 12345 -mwlp 12346 -mwti 12347 -Debu'

(Eu mudei os nomes para este exemplo, mas você entendeu.)

Eu sei que houve vários outros argumentos depois disso, mas nos arquivos principais o comando é sempre truncado em 80 caracteres. Ambos gdb e file relatam isso. Olhando para a saída de objdump , não tenho certeza se o restante foi gravado no dump principal, porque ele parece ser cortado após "-Debu" também.

Estou executando isso no RHEL6. Eu encontrei este tópico de 2007 descrevendo uma solução para sistemas Solaris usando pargs , mas esse não é um comando válido em meu sistema, e os "equivalentes" da Red Hat que encontrei funcionam apenas em processos em execução, não em um arquivo principal.

Como posso recuperar o comando inteiro usado para executar o programa? Isso é possível?

    
por whrrgarbl 08.02.2016 / 19:39

2 respostas

5

Os dados estão lá (pelo menos até 999 entradas, totalizando pelo menos 6885 bytes de blahs numeradas):

> cat segfault.c 
int main(int argc, char *argv[])
{
    char *s = "hello world";
    *s = 'H';
}
> cc -g -o segfault segfault.c
> limit coredumpsize 9999999
> ./segfault 'perl -le 'print "blah$_" for 1..999''
Segmentation fault (core dumped)
> strings core.12231 | grep -c blah
1000

Depois, com uma rápida mudança de gdb , e assumindo os símbolos de depuração, isso pode ser recuperado por meio de algo como:

> gdb ./segfault core.12231
...
(gdb) p argc
$1 = 1000
(gdb) x/1000s *argv
...

Outra opção seria usar um invólucro de shell simples que registre "$@" em algum lugar, em seguida, exec s o programa adequado com os argumentos fornecidos.

    
por 08.02.2016 / 20:12
1

Eu escrevi uma pargs versão para Linux . Assim, dado o arquivo principal, você pode exibir todos os argumentos com ele no RHEL 6, também:

$ pargs core.MyApplication.1234
argv[0]: /usr/libexec/gvfsd-network
argv[1]: --spawner
argv[2]: :1.16
argv[3]: /org/gtk/gvfs/exec_spaw/2

Como alternativa, se você tiver gdb e o executável ainda disponível, poderá exibir todos os argumentos com o GDB:

$ gdb MyApplication core.MyApplication.1234
(gdb) bt
[..]
#4  0x000055a376101e1b in main (argc=4, argv=0x7ffca4780f08)
                       at daemon-main-generic.c:45
(gdb) frame 4
(gdb) set print address off
(gdb) show print pretty
(gdb) p *argv@argc
$1 = {"/usr/libexec/gvfsd-network", "--spawner", ":1.16",
      "/org/gtk/gvfs/exec_spaw/2"}

Comparando as duas abordagens, pargs requer apenas um arquivo principal e não precisa de mais entradas interativas.

    
por 13.01.2018 / 11:50