2009-02-11 6 views
3

Environnement: Apache/2.2.11 (Win32) mod_apreq2-20051231/2.6.2-dev mod_perl/2.0.4-dev Perl/v5.10.0Comment déboguer un module mod_perl2 sans redémarrer?

Situation très similaire à ce qui est décrit dans this discussion list post, à l'exception d'être sur win32.

J'ai dans le fichier httpd.conf:

PerlModule Apache2::Reload 
PerlInitHandler Apache2::Reload 
PerlSetVar ReloadAll Off 
PerlSetVar ReloadModules "MyPackage::*" 

... ainsi que seul le traitement des scripts mod-perl.

J'ai un script qui utilise un module MyPackage, et cela fonctionne.

Je casse le module et recharge le script. L'erreur est utile, indiquant la ligne où j'ai cassé le module.

(Si je recharge à nouveau à ce stade, et il me dit seulement "sous-programme non défini & ModPerl :: ROOT :: ModPerl :: Registre ..." parce qu'il n'a pas pu charger le fichier la première fois. Mais de toute façon, le comportement suivant se produit toujours.)

Je rétablis la coupure, et touche le fichier script aussi pour recharger le module et recharger. Maintenant, il dit:

Attempt to reload MyPackage/Foo.pm aborted. 
Compilation failed in require at E:/dev/test.pl line 4. 

Et même si je touche le script et le module, je ne peux pas l'obtenir pour recharger correctement, sauf en redémarrant le serveur Web.

La rupture du script proprement dit (par opposition au module) fonctionne correctement: les erreurs correctes et le changement de retour entraînent à nouveau le redémarrage.

Après chacune de ces choses que je redémarré le serveur Web avant le test:

  1. J'ai essayé de faire une trace, mais la ligne qu'il continue à l'erreur sur sur est ModPerl/RegistryCooker.pm ligne 204, qui est juste la ligne eval {} s le script entier.

  2. J'ai essayé de changer "emploi Mises en garde FATAL => 'all'" juste "utiliser avertissements" dans le script et le module . N'a pas fait la différence.

  3. J'ai essayé de désactiver ma fonction personnalisée $ SIG {__ DIE__}. N'a pas fait faire une différence. (Eh bien, seulement dans où l'erreur est apparue, bien sûr, mais les erreurs générées ont été les même.)

  4. par le lien de la discussion au début, a constaté que MaxRequestsPerChild a été 0 tout ce temps, et je essayé ThreadsPerChild 1, mais aucune différence. J'ai essayé MaxRequestsPerChild à 1, ce qui permet de résoudre les comportements étranges de cette question, mais redémarre le serveur Web après chaque requête:

    Child 7072: Process exiting because it reached MaxRequestsPerChild. Signaling the parent to restart a new child process. 
    Parent: Received restart signal -- Restarting the server. 
    

    Ce n'est pas une bonne solution, puisque j'ai un morceau important de code qui Courons la première fois qu'une page est touchée.Également par la discussion, j'ai exécuté httpd en tant que service, donc j'ai ajouté -X dans la fenêtre des paramètres de service et appuyez sur Démarrer, et il essayait toujours de démarrer trois minutes plus tard (commence généralement dans les 3 secondes.) J'ai même reçu un message d'expiration. Killed processus via le gestionnaire de tâches et vérifié que je ne pouvais pas frapper la page à partir d'un navigateur Web. Démarrez httpd -X à partir de la ligne de commande. Toujours le même comportement qu'au début de cette question. Aussi j'ai trouvé étrange que -X ne soit pas listé quand j'ai couru httpd - ?. Peut-être que ce n'est pas disponible sur le win32 MPM?

  5. Dans ce fil, David fait remarquer:

    Mon expérience résoudre ce genre de question a indiqué que son probable que le paquet qui a été déchargé supprimé une valeur stockée dans l'espace paquet du module rechargé (probablement défini à l'heure de début BEGIN) que la demande ultérieure n'a pas restaurer.

    Mais ce n'est pas le cas de mon code. L'erreur 'casser le script' que j'introduis est juste d'ajouter une ligne supplémentaire 'my $ var' au-dessus de celle qui est déjà là, de sorte que la seconde va se plaindre qu'elle a déjà été déclarée.

est-il pas possible de travailler sur des modules de mod_perl2 sans avoir le redémarrage du serveur Web après chaque reload (que ce soit automatiquement, via MaxRequestsPerChild, ou manuellement, comme avant)?

Répondre

2

Copiez le sous au script vous appelle, et mettre ce code avant la copie:

package MyPackage::Foo; 
no warnings 'redefine'; 

Lorsque vous avez terminé les modifications, déplacer le sous vers le module réel.

+0

Vous devez redémarrer après l'avoir copié (parfois!) Mais c'est utile jusque là, de toute façon. – Kev

Questions connexes