Esta resposta pretende ser uma estrutura geral para resolver problemas com scripts Perl CGI e apareceu originalmente no Perlmonks como Troubleshooting Perl CGI Scripts . Não é um guia completo para todos os problemas que você pode encontrar, nem um tutorial sobre como eliminar bugs. É apenas o culminar da minha experiência depurando scripts CGI por vinte (mais!) Anos. Esta página parece ter muitas casas diferentes e parece que esqueci que ela existe, então estou adicionando-a ao StackOverflow. Você pode enviar qualquer comentário ou sugestão para mim em bdfoy@cpan.org. Também é wiki da comunidade, mas não enlouqueça. :)
Você está usando os recursos integrados do Perl para ajudá-lo a encontrar problemas?
Ative os avisos para permitir que o Perl o avise sobre partes questionáveis do seu código. Você pode fazer isso a partir da linha de comando com a -w
opção para que não precise alterar nenhum código ou adicionar um pragma a cada arquivo:
% perl -w program.pl
No entanto, você deve se forçar a sempre esclarecer o código questionável, adicionando o warnings
pragma a todos os seus arquivos:
use warnings;
Se precisar de mais informações do que a curta mensagem de aviso, use o diagnostics
pragma para obter mais informações ou consulte a documentação do perldiag :
use diagnostics;
Você gerou um cabeçalho CGI válido primeiro?
O servidor espera que a primeira saída de um script CGI seja o cabeçalho CGI. Normalmente, isso pode ser tão simples quanto print "Content-type: text/plain\n\n";
ou com CGI.pm e seus derivados print header()
,. Alguns servidores são sensíveis à saída de erro (ativada STDERR
) exibida antes da saída padrão (ativada STDOUT
).
Tente enviar erros para o navegador
Adicione esta linha
use CGI::Carp 'fatalsToBrowser';
ao seu script. Isso também envia erros de compilação para a janela do navegador. Certifique-se de removê-lo antes de mudar para um ambiente de produção, pois as informações extras podem representar um risco à segurança.
O que o log de erros diz?
Os servidores mantêm logs de erros (ou deveriam, pelo menos). A saída de erro do servidor e do seu script deve aparecer lá. Encontre o log de erros e veja o que ele diz. Não existe um local padrão para arquivos de log. Procure sua localização na configuração do servidor ou pergunte ao administrador do servidor. Você também pode usar ferramentas como CGI :: Carp
para manter seus próprios arquivos de log.
Quais são as permissões do script?
Se você vir erros como "Permissão negada" ou "Método não implementado", provavelmente significa que seu script não pode ser lido e executado pelo usuário do servidor da web. Em sabores de Unix, é recomendado alterar o modo para 755:
chmod 755 filename
. Nunca defina um modo para 777!
Você está usando use strict
?
Lembre-se de que Perl cria variáveis automaticamente quando você as usa pela primeira vez. Este é um recurso, mas às vezes pode causar erros se você digitar incorretamente o nome de uma variável. O pragma
use strict
o ajudará a encontrar esses tipos de erros. É irritante até você se acostumar, mas sua programação irá melhorar significativamente depois de um tempo e você estará livre para cometer diversos erros.
O script compila?
Você pode verificar se há erros de compilação usando a -c
opção. Concentre-se nos primeiros erros relatados. Enxágüe, repita. Se você estiver recebendo erros realmente estranhos, verifique se o seu script tem os finais de linha corretos. Se você FTP em modo binário, check-out do CVS ou qualquer outra coisa que não lide com tradução de fim de linha, o servidor da web pode ver seu script como uma grande linha. Transfira scripts Perl no modo ASCII.
O script está reclamando de dependências inseguras?
Se o seu script reclamar de dependências inseguras, provavelmente você está usando a -T
opção para ativar o modo contaminado, o que é uma coisa boa, pois mantém você passando dados não verificados para o shell. Se estiver reclamando, está fazendo seu trabalho para nos ajudar a escrever scripts mais seguros. Quaisquer dados provenientes de fora do programa (ou seja, o meio ambiente) são considerados contaminados. Variáveis de ambiente como PATH
e
LD_LIBRARY_PATH
são particularmente problemáticas. Você deve defini-los com um valor seguro ou removê-los completamente, como eu recomendo. Você deve usar caminhos absolutos de qualquer maneira. Se a verificação de contaminação reclamar de outra coisa, certifique-se de que os dados não foram corrompidos. Veja a
página de manual do perlsec para detalhes.
O que acontece quando você o executa a partir da linha de comando?
O script produz o que você espera ao ser executado na linha de comando? A saída do cabeçalho é primeiro, seguida por uma linha em branco? Lembre-se de que STDERR
pode ser mesclado com STDOUT
se você estiver em um terminal (por exemplo, uma sessão interativa) e, devido ao buffering, pode aparecer em uma ordem confusa. Ative o recurso autoflush do Perl definindo $|
um valor verdadeiro. Normalmente você pode ver $|++;
em programas CGI. Depois de definidas, todas as impressões e gravações irão imediatamente para a saída em vez de serem armazenadas em buffer. Você tem que definir isso para cada filehandle. Use select
para alterar o manipulador de arquivos padrão, como:
$|++; #sets $| for STDOUT
$old_handle = select( STDERR ); #change to STDERR
$|++; #sets $| for STDERR
select( $old_handle ); #change back to STDOUT
De qualquer forma, a primeira saída deve ser o cabeçalho CGI seguido por uma linha em branco.
O que acontece quando você o executa a partir da linha de comando com um ambiente semelhante a CGI?
O ambiente do servidor da web é geralmente muito mais limitado do que o ambiente da linha de comando e possui informações extras sobre a solicitação. Se o seu script funcionar bem na linha de comando, você pode tentar simular um ambiente de servidor da web. Se o problema aparecer, você tem um problema de ambiente.
Cancele ou remova essas variáveis
PATH
LD_LIBRARY_PATH
- todas as
ORACLE_*
variáveis
Defina essas variáveis
REQUEST_METHOD
(definida como GET
, HEAD
ou POST
como apropriado)
SERVER_PORT
(definido para 80, normalmente)
REMOTE_USER
(se você estiver fazendo coisas de acesso protegido)
Versões recentes de CGI.pm
(> 2.75) requerem o -debug
sinalizador para obter o comportamento antigo (útil), portanto, pode ser necessário adicioná-lo às suas CGI.pm
importações.
use CGI qw(-debug)
Você está usando die()
ou warn
?
Essas funções são impressas, a STDERR
menos que você as tenha redefinido. Eles também não geram um cabeçalho CGI. Você pode obter a mesma funcionalidade com pacotes como CGI :: Carp
O que acontece depois que você limpa o cache do navegador?
Se você acha que seu script está fazendo a coisa certa e, ao executar a solicitação manualmente, obtém a saída correta, o navegador pode ser o culpado. Limpe o cache e defina o tamanho do cache para zero durante o teste. Lembre-se de que alguns navegadores são realmente estúpidos e não recarregam conteúdo novo, mesmo que você diga para fazer isso. Isso é especialmente prevalente nos casos em que o caminho da URL é o mesmo, mas o conteúdo muda (por exemplo, imagens dinâmicas).
O script está onde você pensa que está?
O caminho do sistema de arquivos para um script não está necessariamente relacionado ao caminho da URL para o script. Certifique-se de ter o diretório correto, mesmo se você tiver que escrever um pequeno script de teste para testar isso. Além disso, tem certeza de que está modificando o arquivo correto? Se você não notar nenhum efeito nas alterações, pode estar modificando um arquivo diferente ou enviando um arquivo para o local errado. (Esta é, a propósito, minha causa mais frequente de tais problemas;)
Você está usando CGI.pm
, ou um derivado dele?
Se o seu problema está relacionado a analisar a entrada CGI e você não estiver usando um módulo amplamente testado como CGI.pm
, CGI::Request
,
CGI::Simple
ou CGI::Lite
, utilize o módulo e seguir com a vida.
CGI.pm
tem um cgi-lib.pl
modo de compatibilidade que pode ajudá-lo a resolver problemas de entrada devido a implementações de analisador CGI mais antigas.
Você usou caminhos absolutos?
Se você estiver executando comandos externos com
system
, back ticks ou outros recursos IPC, você deve usar um caminho absoluto para o programa externo. Você não apenas sabe exatamente o que está executando, mas também evita alguns problemas de segurança. Se você estiver abrindo arquivos para leitura ou gravação, use um caminho absoluto. O script CGI pode ter uma ideia diferente sobre o diretório atual da sua. Alternativamente, você pode fazer um explícito chdir()
para colocá-lo no lugar certo.
Você verificou seus valores de retorno?
A maioria das funções Perl dirá se elas funcionaram ou não e serão configuradas $!
em caso de falha. Você verificou o valor de retorno e examinou as $!
mensagens de erro? Você verificou
$@
se estava usando eval
?
Qual versão do Perl você está usando?
A última versão estável do Perl é 5.28 (ou não, dependendo de quando foi editado pela última vez). Você está usando uma versão mais antiga? Versões diferentes do Perl podem ter idéias diferentes de avisos.
Qual servidor web você está usando?
Servidores diferentes podem agir de maneira diferente na mesma situação. O mesmo produto de servidor pode agir de maneira diferente com configurações diferentes. Inclua o máximo dessas informações que puder em qualquer pedido de ajuda.
Você verificou a documentação do servidor?
Os programadores CGI sérios devem saber o máximo possível sobre o servidor - incluindo não apenas os recursos e o comportamento do servidor, mas também a configuração local. A documentação do seu servidor pode não estar disponível se você estiver usando um produto comercial. Caso contrário, a documentação deve estar em seu servidor. Se não for, procure na web.
Este uso é útil, mas todos os bons cartazes morreram ou se perderam.
É provável que alguém já tenha tido o seu problema antes e que alguém (possivelmente eu) o tenha respondido neste newsgroup. Embora este newsgroup tenha passado do seu apogeu, a sabedoria coletada no passado às vezes pode ser útil.
Você pode reproduzir o problema com um pequeno script de teste?
Em sistemas grandes, pode ser difícil rastrear um bug, pois muitas coisas estão acontecendo. Tente reproduzir o comportamento do problema com o script mais curto possível. Saber o problema é a maior parte da correção. Certamente, isso pode ser demorado, mas você ainda não encontrou o problema e está ficando sem opções. :)
Você decidiu ir ver um filme?
Seriamente. Às vezes, podemos ficar tão envolvidos com o problema que desenvolvemos um "estreitamento perceptivo" (visão de túnel). Fazer uma pausa, tomar uma xícara de café ou atacar alguns bandidos em [Duke Nukem, Quake, Doom, Halo, COD] pode lhe dar uma nova perspectiva de que você precisa para abordar novamente o problema.
Você vocalizou o problema?
Sério de novo. Às vezes, explicar o problema em voz alta nos leva às nossas próprias respostas. Fale com o pinguim (brinquedo de pelúcia) porque seus colegas de trabalho não estão ouvindo. Se você estiver interessado nisso como uma ferramenta de depuração séria (e eu a recomendo, se você ainda não encontrou o problema), você também pode ler The Psychology of Computer Programming .