Eu tenho um script perl que deve ser executado indefinidamente. Está sendo morto ... como eu determino quem ou o que mata?

4

Eu executo o script perl na tela (consigo fazer o login e verificar a saída de depuração). Nada na lógica do script deve ser capaz de matá-lo completamente.

Eu sou uma das duas únicas pessoas com acesso ao servidor, e o outro cara jura que não é ele (e nós dois temos muito dinheiro para continuar sem correr). Não tenho motivos para acreditar que algum hacker tenha conseguido um shell ou algo assim. Eu tenho muito pouca razão para suspeitar dos administradores da operação do host (bandwidth / cpu-wise, este script é bem leve).

A tela continua a ser executada, mas no final da saída do script perl eu vejo "Killed" e ele caiu de volta para um prompt. Como faço para testar o que está acontecendo?

Eu verifiquei crontab, nada lá que mataria processos aleatórios / não aleatórios. Nada em qualquer dos arquivos de log dá qualquer dica. Ele vai correr de 2 a 8 horas, parece (e no meu mac em casa, ele vai correr bem mais de 24 horas sem nenhum problema). O servidor está rodando alguma coisa do Ubuntu, eu posso procurar isso se for importante.

    
por John O 08.02.2011 / 19:11

7 respostas

2

Sem muito conhecimento prático, eu começaria a procurar na saída do dmesg ou em diversos syslogs se o killer da OOM estiver rodando. Se assim for, provavelmente é isso.

    
por 08.02.2011 / 19:25
5

Coloque os manipuladores de sinais para todos os sinais (TERM, SEGV, INT, HUP, etc) e faça com que eles efetuem logout sempre que forem atingidos. Ele não lhe dirá o que está enviando o sinal, mas permitirá que você veja qual é o sinal e talvez o ignore.

$SIG{'TERM'} = $SIG{'INT'} = sub { print(STDERR "Caught SIG$_[0]. Ignoring\n"); };

Isso imprimiria quando pegasse um sigterm ou sigint e retornaria o controle de volta ao programa. Claro que com todos esses sinais sendo ignorados, a única maneira de matá-lo seria fazer o próprio programa sair, ou enviar um SIGKILL que não pode ser capturado.

    
por 08.02.2011 / 19:18
3

Sei que isso não é exatamente uma resposta para a pergunta que você fez, por isso peço desculpas se estiver fora do tópico, mas: seu aplicativo precisa ser executado continuamente, para sempre? O Perl não é o ambiente mais econômico do mundo, e embora a sobrecarga da inicialização do intérprete não seja desprovida de seus inconvenientes, os scripts de execução extremamente longa podem ter problemas próprios - vazamentos de memória, geralmente em um nível abaixo do seu controle são a maldição da existência do desenvolvedor vanilla-perl, e é por isso que as pessoas geralmente mitigam esses problemas executando um subambiente mais formalmente conservacionista de recursos, como o Perl :: POE, ou entregando parte do ouvinte de longa data. o trabalho para um serviço front-end como o xinetd e apenas executando o componente perl quando o trabalho precisa ser feito.

Eu rodei vários scripts perl que rodam continuamente lendo e processando a saída do nosso fluxo de syslog central (consideravelmente grande); eles sofrem de problemas terríveis, inexplicáveis "não liberaram memória apesar da remoção de hash keys" em todos os momentos, e estão no bloco a ser fronteado por algo mais adequado para entradas contínuas de alto volume (uma fila de eventos como Gearman, por exemplo), para que possamos deixar o perl para as tarefas de coleta de dados que ele faz melhor.

Isso foi um pouco; Eu peço desculpas. Espero que seja pelo menos um pouco útil!

    
por 08.02.2011 / 22:56
2

O syslog é a primeira coisa a consultar. Se não for suficiente ...

Você não pode determinar quem envia um sinal para um processo. Poderia ser outro processo, poderia ser o kernel, etc. Além de envolver o framework perf muito recente, algumas suposições estão envolvidas.

No entanto, você pode configurar um monitoramento melhor. O pacote atop , em debian / ubuntu, configura um serviço que registra a carga do sistema e a atividade por processo (disco, memória , CPU). Você pode consultar esses registros e ter uma ideia do que estava acontecendo no momento em que o processo falhou.

Curso intensivo: sudo atop -r , navegue com t e T , digite h para obter ajuda sobre as várias visualizações.

Considere também adicionar um manipulador de sinal que despeja pstree em um arquivo temporário.

    
por 08.02.2011 / 19:33
2

Provavelmente você está correndo para limites de recursos. Por exemplo, tempo de CPU. Tente ulimit -a para verificar. Se for apenas um limite mínimo, defina um script de login e, em seguida, você poderá corrigi-lo com, por exemplo, ulimit -t unlimited . Se for um limite rígido, como é definido, por exemplo, para usuários regulares no OpenBSD e em outros SOs, então você terá que sobrescrever.

    
por 09.02.2011 / 04:10
1

Até encontrar o problema, execute o script com

nohup scriptname

pode ajudar. Se ainda falhar, examine o arquivo nohup.out.

E se nada mencionado aqui ajudar, eu tentaria usar strace / ltrace para ver o que o script de chamadas do sistema ou da biblioteca estava fazendo antes da falha, mas eles geram MUITOS resultados.

    
por 09.02.2011 / 00:14
1

Em uma vida anterior, encontrei uma caixa DEC Ultrix que tinha uma tarefa cron muito inteligente, que procurava todos os processos com mais de 1 hora de CPU e os matava. Foi por isso que o trabalho noturno de reportagem em lote morreu todas as noites.

Quaisquer tarefas / scripts agendados inteligentes que possam estar a matar? Ou pode ser outro parâmetro de ajuste de desempenho ou algo assim como a resposta ulimit já fornecida.

    
por 09.02.2011 / 04:22