Falha na segmentação (núcleo despejado) - para onde? O que é isso? e porque?

16

Quando ocorrer uma falha de segmentação no Linux, a mensagem de erro Segmentation fault (core dumped)será impressa no terminal (se houver) e o programa será encerrado. Como um desenvolvedor de C / C ++, isso acontece muitas vezes, e eu geralmente o ignoro e passo em frente gdb, recriando minha ação anterior para acionar a referência de memória inválida novamente. Em vez disso, pensei que talvez pudesse usar esse "núcleo", pois executar gdbo tempo todo é bastante entediante e nem sempre posso recriar a falha de segmentação.

Minhas perguntas são três:

  • Onde esse "núcleo" ilusório é despejado?
  • O que contém?
  • O que posso fazer com isso?
Joe
fonte
Normalmente você só precisa do comando gdb path-to-your-binary path-to-corefile, info stackseguido de Ctrl-d. A única coisa preocupante é que o core-dumping é uma coisa comum para você.
ott--
Não é muito usual , mais ocasional - na maioria das vezes é devido a erros de digitação ou algo que eu mudei e não impedi o resultado.
Joe

Respostas:

16

Se outras pessoas limparem ...

... você geralmente não encontra nada. Mas, felizmente, o Linux tem um manipulador para isso, que você pode especificar em tempo de execução. Em /usr/src/linux/Documentation/sysctl/kernel.txt, você encontrará:

[/ proc / sys / kernel /] core_pattern é usado para especificar um nome de padrão de arquivo de despejo principal.

  • Se o primeiro caractere do padrão for um '|', o kernel tratará o restante do padrão como um comando a ser executado. O dump principal será gravado na entrada padrão desse programa em vez de em um arquivo.

( obrigado )

De acordo com a fonte, isso é tratado pelo abrtprograma (que é a Ferramenta Automática de Relatório de Erros, e não anulado), mas no meu Arch Linux é tratado pelo systemd. Você pode escrever seu próprio manipulador ou usar o diretório atual.

Mas o que tem lá?

Agora, o que ele contém é específico do sistema, mas de acordo com a enciclopédia onisciente :

[Um core dump] consiste no estado gravado da memória de trabalho de um programa de computador em um horário específico [...]. Na prática, outras partes principais do estado do programa geralmente são despejadas ao mesmo tempo, incluindo os registradores do processador, que podem incluir o contador do programa e o ponteiro da pilha, informações de gerenciamento de memória e outras sinalizações e informações do processador e do sistema operacional.

... então basicamente contém tudo que você gdbsempre quis e muito mais.

Sim, mas gostaria que eu fosse feliz em vez de gdb

Você pode tanto ser feliz, pois gdbvai carregar qualquer dump de memória, desde que você tenha uma cópia exata de seu executável: gdb path/to/binary my/core.dump. Você deve poder continuar os negócios como de costume e ficar aborrecido ao tentar e falhar na correção de bugs, em vez de tentar e não conseguir reproduzir bugs.

Sebb
fonte
4

O arquivo principal normalmente é chamado coree está localizado no diretório de trabalho atual do processo. No entanto, há uma longa lista de razões pelas quais um arquivo principal não seria gerado e pode estar localizado em outro lugar inteiramente, com um nome diferente. Consulte a página do manual core.5 para obter detalhes:

DESCRIÇÃO

A ação padrão de certos sinais é fazer com que um processo seja encerrado e produza um arquivo de despejo principal , um arquivo de disco que contém uma imagem da memória do processo no momento do encerramento. Esta imagem pode ser usada em um depurador (por exemplo, gdb (1)) para inspecionar o estado do programa no momento em que foi finalizado. Uma lista dos sinais que fazem com que um processo despeje o núcleo pode ser encontrada no sinal (7).

...

Há várias circunstâncias em que um arquivo de despejo principal não é produzido:

   *  The process does not have permission to write the core file.  (By
      default, the core file is called core or core.pid, where pid is
      the ID of the process that dumped core, and is created in the
      current working directory.  See below for details on naming.) 
      Writing the core file will fail if the directory in which it is to
      be created is nonwritable, or if a file with the same name exists
      and is not writable or is not a regular file (e.g., it is a
      directory or a symbolic link).
   *  A (writable, regular) file with the same name as would be used for
      the core dump already exists, but there is more than one hard link
      to that file.
   *  The filesystem where the core dump file would be created is full;
      or has run out of inodes; or is mounted read-only; or the user has
      reached their quota for the filesystem.
   *  The directory in which the core dump file is to be created does
      not exist.
   *  The RLIMIT_CORE (core file size) or RLIMIT_FSIZE (file size)
      resource limits for the process are set to zero; see getrlimit(2)
      and the documentation of the shell's ulimit command (limit in
      csh(1)).
   *  The binary being executed by the process does not have read
      permission enabled.
   *  The process is executing a set-user-ID (set-group-ID) program that
      is owned by a user (group) other than the real user (group) ID of
      the process, or the process is executing a program that has file
      capabilities (see capabilities(7)).  (However, see the description
      of the prctl(2) PR_SET_DUMPABLE operation, and the description of
      the /proc/sys/fs/suid_dumpable file in proc(5).)
   *  (Since Linux 3.7) The kernel was configured without the
      CONFIG_COREDUMP option.

Além disso, um dump principal pode excluir parte do espaço de endereço do processo se o sinalizador madvise (2) MADV_DONTDUMP foi empregado.

Nomeação de arquivos de dump principal

Por padrão, um arquivo de dump principal é denominado core, mas o arquivo / proc / sys / kernel / core_pattern (desde o Linux 2.6 e 2.4.21) pode ser definido para definir um modelo usado para nomear arquivos de dump principal. O modelo pode conter% especificadores que são substituídos pelos seguintes valores quando um arquivo principal é criado:

       %%  a single % character
       %c  core file size soft resource limit of crashing process (since
           Linux 2.6.24)
       %d  dump mode—same as value returned by prctl(2) PR_GET_DUMPABLE
           (since Linux 3.7)
       %e  executable filename (without path prefix)
       %E  pathname of executable, with slashes ('/') replaced by
           exclamation marks ('!') (since Linux 3.0).
       %g  (numeric) real GID of dumped process
       %h  hostname (same as nodename returned by uname(2))
       %i  TID of thread that triggered core dump, as seen in the PID
           namespace in which the thread resides (since Linux 3.18)
       %I  TID of thread that triggered core dump, as seen in the
           initial PID namespace (since Linux 3.18)
       %p  PID of dumped process, as seen in the PID namespace in which
           the process resides
       %P  PID of dumped process, as seen in the initial PID namespace
           (since Linux 3.12)
       %s  number of signal causing dump
       %t  time of dump, expressed as seconds since the Epoch,
           1970-01-01 00:00:00 +0000 (UTC)
       %u  (numeric) real UID of dumped process
Andrew Henle
fonte
1

No Ubuntu, qualquer falha que acontece é registrada em / var / crash. O relatório de falha gerado pode ser descompactado usando uma ferramenta apport

apport-unpack /var/crash/_crash_file.crash 'caminho para descompactar'

e, em seguida, o dump principal no relatório descompactado pode ser lido usando

gdb 'cat ExecutablePath' CoreDump

par
fonte