Esta respuesta está pensada como un marco general para resolver problemas con los scripts CGI de Perl y apareció originalmente en Perlmonks como Troubleshooting Perl CGI Scripts . No es una guía completa de todos los problemas que pueda encontrar, ni un tutorial sobre la eliminación de errores. Es solo la culminación de mi experiencia depurando scripts CGI durante veinte (¡más!) Años. Esta página parece haber tenido muchos hogares diferentes, y parece que me olvido de que existe, así que la estoy agregando a StackOverflow. Puede enviarme cualquier comentario o sugerencia a bdfoy@cpan.org. También es un wiki de la comunidad, pero no te vuelvas loco. :)
¿Está utilizando las funciones integradas de Perl para ayudarlo a encontrar problemas?
Active las advertencias para que Perl le advierta sobre partes cuestionables de su código. Puede hacer esto desde la línea de comando con el -w
interruptor para que no tenga que cambiar ningún código o agregar un pragma a cada archivo:
% perl -w program.pl
Sin embargo, debe obligarse a aclarar siempre el código cuestionable agregando el warnings
pragma a todos sus archivos:
use warnings;
Si necesita más información que el breve mensaje de advertencia, use diagnostics
pragma para obtener más información o busque en la documentación de perldiag :
use diagnostics;
¿Produjo primero un encabezado CGI válido?
El servidor espera que la primera salida de un script CGI sea el encabezado CGI. Típicamente que podría ser tan simple como print "Content-type: text/plain\n\n";
o con CGI.pm y sus derivados, print header()
. Algunos servidores son sensibles a la salida de error (activada STDERR
) que aparece antes que la salida estándar (activada STDOUT
).
Intente enviar errores al navegador
Agregar esta línea
use CGI::Carp 'fatalsToBrowser';
a tu guión. Esto también envía errores de compilación a la ventana del navegador. Asegúrese de eliminar esto antes de pasar a un entorno de producción, ya que la información adicional puede representar un riesgo para la seguridad.
¿Qué decía el registro de errores?
Los servidores mantienen registros de errores (o deberían, al menos). La salida de error del servidor y de su script debería aparecer allí. Busque el registro de errores y vea lo que dice. No existe un lugar estándar para los archivos de registro. Busque en la configuración del servidor su ubicación o pregunte al administrador del servidor. También puede utilizar herramientas como CGI :: Carp
para mantener sus propios archivos de registro.
¿Cuáles son los permisos del script?
Si ve errores como "Permiso denegado" o "Método no implementado", probablemente significa que el usuario del servidor web no puede leer ni ejecutar su script. En las variantes de Unix, se recomienda cambiar el modo a 755:
chmod 755 filename
. ¡Nunca establezca un modo en 777!
¿Usted está utilizando use strict
?
Recuerde que Perl crea automáticamente variables cuando las usa por primera vez. Esta es una característica, pero a veces puede causar errores si escribe mal el nombre de una variable. El pragma
use strict
le ayudará a encontrar ese tipo de errores. Es molesto hasta que te acostumbras, pero tu programación mejorará significativamente después de un tiempo y podrás cometer diferentes errores.
¿Se compila el script?
Puede comprobar si hay errores de compilación utilizando el -c
conmutador. Concéntrese en los primeros errores notificados. Enjuague, repita. Si está recibiendo errores realmente extraños, verifique que su script tenga los finales de línea correctos. Si utiliza FTP en modo binario, realiza el pago desde CVS o cualquier otra cosa que no maneja la traducción del final de línea, el servidor web puede ver su script como una línea grande. Transfiera scripts de Perl en modo ASCII.
¿El script se queja de dependencias inseguras?
Si su secuencia de comandos se queja de dependencias inseguras, probablemente esté usando el -T
interruptor para activar el modo de corrupción, lo cual es bueno ya que le mantiene pasando datos no verificados al shell. Si se queja, está haciendo su trabajo para ayudarnos a escribir scripts más seguros. Cualquier dato que se origine fuera del programa (es decir, el medio ambiente) se considera contaminado. Las variables de entorno como PATH
y
LD_LIBRARY_PATH
son particularmente problemáticas. Debe configurarlos en un valor seguro o desarmarlos por completo, como recomiendo. De todos modos, deberías usar rutas absolutas. Si la comprobación de manchas se queja de otra cosa, asegúrese de haber limpiado los datos. Consulte la
página del manual de perlsec para obtener más detalles.
¿Qué sucede cuando lo ejecuta desde la línea de comandos?
¿El script genera lo que espera cuando se ejecuta desde la línea de comando? ¿La salida del encabezado es primero, seguida de una línea en blanco? Recuerde que STDERR
puede fusionarse con STDOUT
si está en una terminal (por ejemplo, una sesión interactiva) y, debido al almacenamiento en búfer, puede aparecer en un orden desordenado. Active la función de descarga automática de Perl estableciendo $|
un valor real. Por lo general, es posible que vea $|++;
en programas CGI. Una vez configuradas, cada impresión y escritura irá inmediatamente a la salida en lugar de almacenarse en búfer. Debe configurar esto para cada identificador de archivo. Úselo select
para cambiar el identificador de archivo predeterminado, así:
$|++; #sets $| for STDOUT
$old_handle = select( STDERR ); #change to STDERR
$|++; #sets $| for STDERR
select( $old_handle ); #change back to STDOUT
De cualquier manera, la primera salida debería ser el encabezado CGI seguido de una línea en blanco.
¿Qué sucede cuando lo ejecuta desde la línea de comandos con un entorno similar a CGI?
El entorno del servidor web suele ser mucho más limitado que el entorno de la línea de comandos y tiene información adicional sobre la solicitud. Si su secuencia de comandos se ejecuta bien desde la línea de comandos, puede intentar simular un entorno de servidor web. Si aparece el problema, tiene un problema medioambiental.
Desarmar o eliminar estas variables
PATH
LD_LIBRARY_PATH
- todas las
ORACLE_*
variables
Establecer estas variables
REQUEST_METHOD
(establecido en GET
, HEAD
o POST
según el caso)
SERVER_PORT
(establecido en 80, generalmente)
REMOTE_USER
(si está haciendo cosas de acceso protegido)
Las versiones recientes de CGI.pm
(> 2.75) requieren que el -debug
indicador obtenga el comportamiento anterior (útil), por lo que es posible que deba agregarlo a sus CGI.pm
importaciones.
use CGI qw(-debug)
¿Estás usando die()
o warn
?
Esas funciones se imprimen en a STDERR
menos que las haya redefinido. Tampoco generan un encabezado CGI. Puede obtener la misma funcionalidad con paquetes como CGI :: Carp
¿Qué sucede después de borrar la memoria caché del navegador?
Si cree que su script está haciendo lo correcto y cuando realiza la solicitud manualmente obtiene el resultado correcto, el navegador podría ser el culpable. Borre el caché y establezca el tamaño del caché en cero durante la prueba. Recuerde que algunos navegadores son realmente estúpidos y no volverán a cargar contenido nuevo aunque usted le diga que lo haga. Esto es especialmente frecuente en los casos en que la ruta URL es la misma, pero el contenido cambia (por ejemplo, imágenes dinámicas).
¿Está el guión donde crees que está?
La ruta del sistema de archivos a un script no está necesariamente relacionada directamente con la ruta URL del script. Asegúrese de tener el directorio correcto, incluso si tiene que escribir un breve script de prueba para probarlo. Además, ¿está seguro de que está modificando el archivo correcto? Si no ve ningún efecto con sus cambios, es posible que esté modificando un archivo diferente o cargando un archivo en el lugar equivocado. (Esta es, por cierto, mi causa más frecuente de tal problema;)
¿Está usando CGI.pm
, o un derivado de él?
Si su problema está relacionado con el análisis de la entrada de CGI y no está usando un módulo ampliamente probado como CGI.pm
, CGI::Request
,
CGI::Simple
o CGI::Lite
, utilice el módulo y continuar con su vida.
CGI.pm
tiene un cgi-lib.pl
modo de compatibilidad que puede ayudarlo a resolver problemas de entrada debido a implementaciones de analizador CGI más antiguas.
¿Usaste caminos absolutos?
Si está ejecutando comandos externos con system
retrocesos u otras funciones de
IPC, debe usar una ruta absoluta al programa externo. No solo sabe exactamente lo que está ejecutando, sino que también evita algunos problemas de seguridad. Si abre archivos para leer o escribir, utilice una ruta absoluta. El script CGI puede tener una idea diferente a la tuya sobre el directorio actual. Alternativamente, puede hacer un explícito chdir()
para ponerlo en el lugar correcto.
¿Verificó sus valores devueltos?
La mayoría de las funciones de Perl le dirán si funcionaron o no y se establecerán $!
en falla. ¿Verificó el valor de retorno y examinó $!
los mensajes de error? ¿Verificó
$@
si estaba usando eval
?
¿Qué versión de Perl estás usando?
La última versión estable de Perl es 5.28 (o no, dependiendo de cuándo se editó por última vez). ¿Estás usando una versión anterior? Las diferentes versiones de Perl pueden tener diferentes ideas de advertencias.
¿Qué servidor web estás usando?
Diferentes servidores pueden actuar de manera diferente en la misma situación. El mismo producto de servidor puede actuar de manera diferente con diferentes configuraciones. Incluya tanta información como pueda en cualquier solicitud de ayuda.
¿Verificó la documentación del servidor?
Los programadores serios de CGI deben saber todo lo posible sobre el servidor, incluidas no solo las características y el comportamiento del servidor, sino también la configuración local. Es posible que la documentación de su servidor no esté disponible si está utilizando un producto comercial. De lo contrario, la documentación debería estar en su servidor. Si no es así, búsquelo en la web.
Esto solía ser útil, pero todos los buenos carteles han muerto o se han perdido.
Es probable que alguien haya tenido su problema antes y que alguien (posiblemente yo) lo haya respondido en este grupo de noticias. Aunque este grupo de noticias ha pasado su apogeo, la sabiduría recopilada del pasado a veces puede ser útil.
¿Puede reproducir el problema con un breve script de prueba?
En sistemas grandes, puede ser difícil rastrear un error debido a que están sucediendo muchas cosas. Intente reproducir el comportamiento problemático con el script más corto posible. Conocer el problema es la mayor parte de la solución. Sin duda, esto puede llevar mucho tiempo, pero aún no ha encontrado el problema y se están quedando sin opciones. :)
¿Decidiste ir a ver una película?
Seriamente. A veces podemos estar tan envueltos en el problema que desarrollamos un "estrechamiento perceptivo" (visión de túnel). Tomarte un descanso, tomar una taza de café o criticar a los malos en [Duke Nukem, Quake, Doom, Halo, COD] puede darte la nueva perspectiva de que necesitas para volver a abordar el problema.
¿Ha vocalizado el problema?
En serio otra vez. A veces, explicar el problema en voz alta nos lleva a nuestras propias respuestas. Habla con el pingüino (peluche) porque tus compañeros de trabajo no te escuchan. Si está interesado en esto como una herramienta de depuración seria (y la recomiendo si aún no ha encontrado el problema), también puede leer La psicología de la programación informática .