Isso depende de qual shell você está usando. Se você estiver usando o bash, o comando ulimit controla várias configurações relacionadas à execução do programa, como se você deve despejar o núcleo. Se você digitar
ulimit -c unlimited
isso informará ao bash que seus programas podem despejar núcleos de qualquer tamanho. Você pode especificar um tamanho como 52M em vez de ilimitado, se desejar, mas na prática isso não deve ser necessário, pois o tamanho dos arquivos principais provavelmente nunca será um problema para você.
@lzprgmr: Para esclarecer: a razão pela qual os dumps do núcleo não são gerados por padrão é que o limite não está definido e / ou definido como 0, o que impede que o núcleo seja descartado. Ao definir um limite ilimitado, garantimos que os dumps principais sempre possam ser gerados.
Eli Courtwright
6
Esse link é mais profundo e oferece mais algumas opções para permitir a geração de core dumps no linux. A única desvantagem é que alguns comandos / configurações são deixados sem explicação.
Salsa
6
No bash 4.1.2 (1), limites de liberação como 52M não podem ser especificados, resultando em uma mensagem de erro de número inválido. A página do manual informa que "Os valores estão em incrementos de 1024 bytes".
a1an
4
Bem, eu tive um projeto "pequeno" do OpenGL, que uma vez fez alguma coisa estranha e causou uma falha no servidor X. Quando efetuei o logon, vi um pequeno arquivo principal de 17 GB (em uma partição de 25 GB). É definitivamente uma boa idéia para manter o tamanho do arquivo núcleo limitado :)
IceCool
1
@PolarisUser: Se você quiser garantir que sua partição não seja consumida, recomendo definir um limite de algo como 1 gig. Isso deve ser grande o suficiente para lidar com qualquer despejo de núcleo razoável, sem ameaçar usar todo o espaço restante no disco rígido.
Eli Courtwright
60
Conforme explicado acima, a verdadeira pergunta que está sendo feita aqui é como habilitar os dumps principais em um sistema em que eles não estão habilitados. Essa pergunta é respondida aqui.
Se você veio aqui esperando aprender como gerar um dump principal para um processo interrompido, a resposta é
gcore <pid>
se o gcore não estiver disponível no seu sistema,
kill -ABRT <pid>
Não use kill -SEGV, pois isso geralmente chama um manipulador de sinais, dificultando o diagnóstico do processo bloqueado
Eu acho que é muito mais provável que -ABRTinvoque um manipulador de sinal do que -SEGV, pois um abort é mais provável que seja recuperável do que um segfault. (Se você manipular um segfault, normalmente ele será acionado novamente assim que o manipulador sair.) Uma melhor opção de sinal para gerar um dump principal é -QUIT.
celticminstrel 25/02
32
Para verificar onde os dumps principais são gerados, execute:
sysctl kernel.core_pattern
ou:
cat /proc/sys/kernel/core_pattern
onde %eé o nome do processo e %ta hora do sistema. Você pode alterá-lo /etc/sysctl.confe recarregá-lo sysctl -p.
Se os arquivos principais não são gerados (testá-lo: sleep 10 &e killall -SIGSEGV sleep), verificar os limites por: ulimit -a.
Se o tamanho do seu arquivo principal for limitado, execute:
ulimit -c unlimited
para torná-lo ilimitado.
Em seguida, teste novamente, se o dumping no núcleo for bem-sucedido, você verá "(core dumped)" após a indicação de falha de segmentação, conforme abaixo:
Para o Ubuntu, para retornar rapidamente ao comportamento normal (despejar um arquivo principal no diretório atual), basta parar o serviço apport com "sudo service apport stop". Observe também que, se você estiver executando na janela de encaixe, essa configuração será controlada no sistema host e não no contêiner.
Digicrat
26
O que fiz no final foi anexar o gdb ao processo antes que ele falhasse e, quando o segfault foi executado, executei o generate-core-filecomando. Essa geração forçada de um core dump.
Para responder ao Ritwik G, para anexar um processo ao gdb, basta iniciar o gdb e digite 'attach <pid>' onde <pid> é o número do pid do processo que você deseja anexar.
O estranho é que eu já defini ulimit -ccomo unlimited, mas o arquivo principal ainda não foi criado, o generate-core-filearquivo na sessão gdb cria o arquivo principal, obrigado.
CodyChan
19
Talvez você possa fazê-lo dessa maneira, este programa é uma demonstração de como capturar uma falha de segmentação e realizar a conversão para um depurador (este é o código original usado abaixo AIX) e imprimir o rastreamento da pilha até o ponto de uma falha de segmentação. Você precisará alterar a sprintfvariável a ser usada gdbno caso do Linux.
#include <stdio.h>#include <signal.h>#include <stdlib.h>#include <stdarg.h>
static void signal_handler(int);
static void dumpstack(void);
static void cleanup(void);
void init_signals(void);
void panic(const char *,...);
struct sigaction sigact;
char *progname;
int main(int argc, char **argv){
char *s;
progname =*(argv);
atexit(cleanup);
init_signals();
printf("About to seg fault by assigning zero to *s\n");*s =0;
sigemptyset(&sigact.sa_mask);return0;}
void init_signals(void){
sigact.sa_handler = signal_handler;
sigemptyset(&sigact.sa_mask);
sigact.sa_flags =0;
sigaction(SIGINT,&sigact,(struct sigaction *)NULL);
sigaddset(&sigact.sa_mask, SIGSEGV);
sigaction(SIGSEGV,&sigact,(struct sigaction *)NULL);
sigaddset(&sigact.sa_mask, SIGBUS);
sigaction(SIGBUS,&sigact,(struct sigaction *)NULL);
sigaddset(&sigact.sa_mask, SIGQUIT);
sigaction(SIGQUIT,&sigact,(struct sigaction *)NULL);
sigaddset(&sigact.sa_mask, SIGHUP);
sigaction(SIGHUP,&sigact,(struct sigaction *)NULL);
sigaddset(&sigact.sa_mask, SIGKILL);
sigaction(SIGKILL,&sigact,(struct sigaction *)NULL);}
static void signal_handler(int sig){if(sig == SIGHUP) panic("FATAL: Program hanged up\n");if(sig == SIGSEGV || sig == SIGBUS){
dumpstack();
panic("FATAL: %s Fault. Logged StackTrace\n",(sig == SIGSEGV)?"Segmentation":((sig == SIGBUS)?"Bus":"Unknown"));}if(sig == SIGQUIT) panic("QUIT signal ended program\n");if(sig == SIGKILL) panic("KILL signal ended program\n");if(sig == SIGINT);}
void panic(const char *fmt,...){
char buf[50];
va_list argptr;
va_start(argptr, fmt);
vsprintf(buf, fmt, argptr);
va_end(argptr);
fprintf(stderr, buf);
exit(-1);}
static void dumpstack(void){/*Got this routine from http://www.whitefang.com/unix/faq_toc.html
**Section6.5.Modified to redirect to file to prevent clutter
*//*This needs to be changed...*/
char dbx[160];
sprintf(dbx,"echo 'where\ndetach' | dbx -a %d > %s.dump", getpid(), progname);/*Change the dbx to gdb */
system(dbx);return;}
void cleanup(void){
sigemptyset(&sigact.sa_mask);/*Do any cleaning up chores here */}
Pode ser necessário adicionar um parâmetro adicional para que o gdb despeje o núcleo, como mostrado aqui neste blog aqui .
Há mais coisas que podem influenciar a geração de um core dump. Eu encontrei estes:
o diretório para o dump deve ser gravável. Por padrão, este é o diretório atual do processo, mas isso pode ser alterado pela configuração /proc/sys/kernel/core_pattern.
em algumas condições, o valor do kernel em /proc/sys/fs/suid_dumpablepode impedir a geração do núcleo.
Há mais situações que podem impedir a geração descrita na página de manual - tente man core.
para verificar se o arquivo principal é gravado, você pode interromper o processo de relacionamento com o cmd kill -s SEGV <PID>(não deve ser necessário, caso não seja gravado nenhum arquivo principal, isso pode ser usado como verificação):
# kill -s SEGV <PID>
Após a gravação do corefile, desative as configurações do coredump novamente nos arquivos relacionados (1./2./3.)!
Na etapa 3, como 'reexecutar' o terminal? Você quer dizer reiniciar?
Naveen
@ Naveen não, basta fechar o terminal e abrir um novo, também parece que você pode simplesmente colocar ulimit -c unlimitedno terminal para uma solução temporária, porque apenas a edição ~/.bashrcrequer reinicialização do terminal para que as alterações tenham efeito.
mrgloom
4
Por padrão, você receberá um arquivo principal. Verifique se o diretório atual do processo é gravável ou se nenhum arquivo principal será criado.
Por "diretório atual do processo", você quer dizer $ cwd no momento em que o processo foi executado? ~ / abc> / usr / bin / cat def se o gato travar, o diretório atual está em questão ~ / abc ou / usr / bin?
18719 Nathan Fellman
5
~ / abc. Hmm, os comentários devem ter 15 caracteres!
Mark Harrison
5
Esse seria o diretório atual no momento do SEGV. Além disso, os processos em execução com um usuário e / ou grupo efetivo diferente do usuário / grupo real não gravam arquivos principais.
Darron
2
Melhor ativar o core dump programaticamente usando a chamada do sistema setrlimit.
arquivo principal gerado após a falha, não é necessário ulimit -c unlimitedno ambiente da linha de comando e execute novamente o aplicativo.
precisa saber é o seguinte
Eu não quero um despejo central toda vez que ele falha, apenas quando um usuário entra em contato comigo como desenvolvedor para analisá-lo. Se ele travar 100 vezes, não preciso de 100 dumps principais para analisar.
Nathan Fellman
Nesse caso, melhor usar ulimit -c unlimited. Além disso, você pode compilar com a definição de marco, o aplicativo não incluirá enable_core_dumpsímbolo, se não definir essa macro quando for lançado, e você receberá um dump principal para substituir a versão de depuração.
precisa saber é o seguinte
mesmo que seja qualificado por uma macro, isso ainda exige que eu recompile se quiser gerar um core dump, em vez de simplesmente executar um comando no shell antes de executar novamente.
18719 Nathan Fellman
1
Vale ressaltar que, se você tem um sistema configurado, as coisas são um pouco diferentes. A configuração normalmente faria com que os arquivos principais fossem canalizados por meio do core_patternvalor sysctl systemd-coredump(8). O tamanho do arquivo principal rlimit normalmente já está configurado como "ilimitado".
É então possível recuperar os dumps do núcleo usando coredumpctl(1).
O armazenamento de core dumps, etc. é configurado por coredump.conf(5). Existem exemplos de como obter os arquivos principais na página do manual coredumpctl, mas, resumindo, ficaria assim:
Encontre o arquivo principal:
[vps@phoenix]~$ coredumpctl list test_me | tail -1Sun2019-01-2011:17:33 CET 161631224122411 present /home/vps/test_me
Algumas respostas sugerem mudanças core_pattern. Esteja ciente de que esse arquivo pode ser substituído pelo serviço apport ao reiniciar.
Simplesmente parar o apport não fez o trabalho
O ulimit -cvalor pode ser alterado automaticamente enquanto você tenta outras respostas da web. Verifique-o regularmente durante a configuração da criação do dump principal.
Respostas:
Isso depende de qual shell você está usando. Se você estiver usando o bash, o comando ulimit controla várias configurações relacionadas à execução do programa, como se você deve despejar o núcleo. Se você digitar
isso informará ao bash que seus programas podem despejar núcleos de qualquer tamanho. Você pode especificar um tamanho como 52M em vez de ilimitado, se desejar, mas na prática isso não deve ser necessário, pois o tamanho dos arquivos principais provavelmente nunca será um problema para você.
No tcsh, você digitaria
fonte
Conforme explicado acima, a verdadeira pergunta que está sendo feita aqui é como habilitar os dumps principais em um sistema em que eles não estão habilitados. Essa pergunta é respondida aqui.
Se você veio aqui esperando aprender como gerar um dump principal para um processo interrompido, a resposta é
se o gcore não estiver disponível no seu sistema,
Não use kill -SEGV, pois isso geralmente chama um manipulador de sinais, dificultando o diagnóstico do processo bloqueado
fonte
-ABRT
invoque um manipulador de sinal do que-SEGV
, pois um abort é mais provável que seja recuperável do que um segfault. (Se você manipular um segfault, normalmente ele será acionado novamente assim que o manipulador sair.) Uma melhor opção de sinal para gerar um dump principal é-QUIT
.Para verificar onde os dumps principais são gerados, execute:
ou:
onde
%e
é o nome do processo e%t
a hora do sistema. Você pode alterá-lo/etc/sysctl.conf
e recarregá-losysctl -p
.Se os arquivos principais não são gerados (testá-lo:
sleep 10 &
ekillall -SIGSEGV sleep
), verificar os limites por:ulimit -a
.Se o tamanho do seu arquivo principal for limitado, execute:
para torná-lo ilimitado.
Em seguida, teste novamente, se o dumping no núcleo for bem-sucedido, você verá "(core dumped)" após a indicação de falha de segmentação, conforme abaixo:
Veja também: core dumped - mas o arquivo core não está no diretório atual?
Ubuntu
No Ubuntu, os core dumps são gerenciados pelo Apport e podem ser localizados em
/var/crash/
. No entanto, é desativado por padrão em versões estáveis.Para mais detalhes, verifique: Onde encontro o dump principal no Ubuntu? .
Mac OS
Para o macOS, consulte: Como gerar dumps principais no Mac OS X?
fonte
O que fiz no final foi anexar o gdb ao processo antes que ele falhasse e, quando o segfault foi executado, executei o
generate-core-file
comando. Essa geração forçada de um core dump.fonte
ge
)ulimit -c
comounlimited
, mas o arquivo principal ainda não foi criado, ogenerate-core-file
arquivo na sessão gdb cria o arquivo principal, obrigado.Talvez você possa fazê-lo dessa maneira, este programa é uma demonstração de como capturar uma falha de segmentação e realizar a conversão para um depurador (este é o código original usado abaixo
AIX
) e imprimir o rastreamento da pilha até o ponto de uma falha de segmentação. Você precisará alterar asprintf
variável a ser usadagdb
no caso do Linux.Pode ser necessário adicionar um parâmetro adicional para que o gdb despeje o núcleo, como mostrado aqui neste blog aqui .
fonte
Há mais coisas que podem influenciar a geração de um core dump. Eu encontrei estes:
/proc/sys/kernel/core_pattern
./proc/sys/fs/suid_dumpable
pode impedir a geração do núcleo.Há mais situações que podem impedir a geração descrita na página de manual - tente
man core
.fonte
Para ativar o dump principal, faça o seguinte:
Em
/etc/profile
comentar a linha:No
/etc/security/limits.conf
comentário da linha:execute o cmd
limit coredumpsize unlimited
e verifique-o com o cmdlimit
:para verificar se o arquivo principal é gravado, você pode interromper o processo de relacionamento com o cmd
kill -s SEGV <PID>
(não deve ser necessário, caso não seja gravado nenhum arquivo principal, isso pode ser usado como verificação):Após a gravação do corefile, desative as configurações do coredump novamente nos arquivos relacionados (1./2./3.)!
fonte
Para o Ubuntu 14.04
Verifique o dump principal ativado:
Uma das linhas deve ser:
Se não :
gedit ~/.bashrc
adicioneulimit -c unlimited
no final do arquivo e salve, execute novamente o terminal.Crie seu aplicativo com informações de depuração:
Em Makefile
-O0 -g
Execute o aplicativo que cria o core dump (o arquivo core dump com o nome 'core' deve ser criado próximo ao arquivo application_name):
Execute sob gdb:
fonte
ulimit -c unlimited
no terminal para uma solução temporária, porque apenas a edição~/.bashrc
requer reinicialização do terminal para que as alterações tenham efeito.Por padrão, você receberá um arquivo principal. Verifique se o diretório atual do processo é gravável ou se nenhum arquivo principal será criado.
fonte
Melhor ativar o core dump programaticamente usando a chamada do sistema
setrlimit
.exemplo:
fonte
ulimit -c unlimited
no ambiente da linha de comando e execute novamente o aplicativo.ulimit -c unlimited
. Além disso, você pode compilar com a definição de marco, o aplicativo não incluiráenable_core_dump
símbolo, se não definir essa macro quando for lançado, e você receberá um dump principal para substituir a versão de depuração.Vale ressaltar que, se você tem um sistema configurado, as coisas são um pouco diferentes. A configuração normalmente faria com que os arquivos principais fossem canalizados por meio do
core_pattern
valor sysctlsystemd-coredump(8)
. O tamanho do arquivo principal rlimit normalmente já está configurado como "ilimitado".É então possível recuperar os dumps do núcleo usando
coredumpctl(1)
.O armazenamento de core dumps, etc. é configurado por
coredump.conf(5)
. Existem exemplos de como obter os arquivos principais na página do manual coredumpctl, mas, resumindo, ficaria assim:Encontre o arquivo principal:
Obtenha o arquivo principal:
fonte
Ubuntu 19.04
Todas as outras respostas em si não me ajudaram. Mas a seguinte soma fez o trabalho
Crie
~/.config/apport/settings
com o seguinte conteúdo:(Isso indica ao apport para também escrever dumps principais para aplicativos personalizados)
verificar:
ulimit -c
. Se der 0, corrija-o comApenas no caso de reiniciar o apport:
Os arquivos de falha agora estão gravados
/var/crash/
. Mas você não pode usá-los com gdb. Para usá-los com gdb, useOutras informações:
core_pattern
. Esteja ciente de que esse arquivo pode ser substituído pelo serviço apport ao reiniciar.ulimit -c
valor pode ser alterado automaticamente enquanto você tenta outras respostas da web. Verifique-o regularmente durante a configuração da criação do dump principal.Referências:
fonte