Je me demande comment personne n'a mentionné l' PERLDB_OPTS
option appelée" RemotePort
; bien que, certes, il n'y a pas beaucoup d'exemples sur le web (RemotePort
n'est même pas mentionné dans perldebug) - et c'était un peu problématique pour moi de venir avec ce point, mais ici, il va (étant un Linux par exemple).
Pour faire un bon exemple, j'ai d'abord besoin de quelque chose qui peut faire un très simple simulation d'un serveur web CGI, de préférence au moyen d'une seule ligne de commande. Après constatation Simple ligne de commande du serveur web pour l'exécution de scripts cgi. (perlmonks.org), j'ai trouvé le IO::Tous - Un petit Serveur Web pour être applicable pour ce test.
Ici, je vais travailler dans l' /tmp
répertoire; le script CGI sera /tmp/test.pl
(inclus ci-dessous). Notez que l' IO::All
serveur servira uniquement les fichiers exécutables dans le même répertoire que le CGI, de sorte chmod +x test.pl
est requis ici. Donc, faire l'habitude CGI essai, je change le répertoire /tmp
dans le terminal et exécutez la ligne de commande du serveur web:
$ cd /tmp
$ perl -MIO::All -e 'io(":8080")->fork->accept->(sub { $_[0] < io(-x $1 ? "./$1 |" : $1) if /^GET \/(.*) / })'
Le serveur de commande va bloquer dans le terminal, et sinon, démarrez le serveur web en local (127.0.0.1 ou localhost
) - par la suite, je peux aller à un navigateur web, et demande à cette adresse:
http://127.0.0.1:8080/test.pl
... et je dois observer l' print
s par test.pl
chargé et affiché dans le navigateur web.
Maintenant, pour déboguer ce script avec RemotePort
, nous avons d'abord besoin d'un port d'écoute sur le réseau, qui nous permettra d'interagir avec le débogueur Perl; on peut utiliser l'outil de ligne de commande netcat
(nc
, vu que ici: Perl如何remote debug?). Donc, tout d'abord exécuter l' netcat
auditeur dans un terminal où il permet de bloquer et d'attente pour les connexions sur le port 7234 (qui sera notre port de débogage):
$ nc -l 7234
Ensuite, nous souhaitons perl
pour démarrer en mode debug avec RemotePort
, lorsque l' test.pl
a été appelé (même en mode CGI, par le biais du serveur). Ce, dans Linux, qui peut être fait à l'aide de la suite de "shebang wrapper" script - qui, ici, doit aussi être prise en /tmp
, et doit être rendu exécutable:
cd /tmp
cat > perldbgcall.sh <<'EOF'
#!/bin/bash
PERLDB_OPTS="RemotePort=localhost:7234" perl -d -e "do '$@'"
EOF
chmod +x perldbgcall.sh
C'est le genre de chose la plus délicate - voir le script shell - Comment puis-je utiliser des variables d'environnement dans mon arborescence? - Unix & Linux Stack Exchange. Mais, le truc, ici, semble être pas la fourche à l' perl
interprète qui gère test.pl
- donc, une fois que nous avons atteint, nous n'avons pas l' exec
, mais au lieu de cela, nous appelons perl
"clairement", et en gros, "source" notre test.pl
script à l'aide de do
(voir Comment puis-je exécuter un script Perl à partir de l'intérieur d'un script Perl?).
Maintenant que nous avons perldbgcall.sh
en /tmp
- on peut changer l' test.pl
le fichier, de sorte qu'il se réfère à ce fichier exécutable sur sa ligne shebang (au lieu de l'habituel interpréteur Perl) - /tmp/test.pl
modifié ainsi:
#!./perldbgcall.sh
# this is test.pl
use 5.10.1;
use warnings;
use strict;
my $b = '1';
my $a = sub { "hello $b there" };
$b = '2';
print "YEAH " . $a->() . " CMON\n";
$b = '3';
print "CMON " . &$a . " YEAH\n";
$DB::single=1; # BREAKPOINT
$b = '4';
print "STEP " . &$a . " NOW\n";
$b = '5';
print "STEP " . &$a . " AGAIN\n";
Maintenant, les deux test.pl
et sa nouvelle arborescence du gestionnaire, perldbgcall.sh
, sont en /tmp
; et nous avons nc
écoute pour déboguer les connexions sur le port 7234 - alors, nous pouvons enfin ouvrir une autre fenêtre de terminal, modifiez le répertoire /tmp
, et d'exécuter la ligne de commande du serveur web (qui sera à l'écoute pour les connexions web sur le port 8080) il y a:
cd /tmp
perl -MIO::All -e 'io(":8080")->fork->accept->(sub { $_[0] < io(-x $1 ? "./$1 |" : $1) if /^GET \/(.*) / })'
Après ceci est fait, nous pouvons aller à notre navigateur web, et demande à la même adresse, http://127.0.0.1:8080/test.pl
. Cependant, maintenant, quand le serveur tente d'exécuter le script, il le fera par le biais perldbgcall.sh
inclus - qui débutera perl
dans le débogueur distant mode. Ainsi, l'exécution du script en pause - et donc le navigateur web de verrouillage, l'attente de données. Nous pouvons maintenant passer à l' netcat
terminal, et nous devrions voir les familiers débogueur Perl texte - cependant, la sortie par le biais nc
:
$ nc -l 7234
Loading DB routines from perl5db.pl version 1.32
Editor support available.
Enter h or `h h' for help, or `man perldebug' for more help.
main::(-e:1): do './test.pl'
DB<1> r
main::(./test.pl:29): $b = '4';
DB<1>
Comme le montre l'extrait de code, nous allons maintenant utiliser nc
comme un "terminal" - afin que nous puissions type r
(et Enter) pour "exécuter" - et le script sera exécuté jusqu'faire le point d'arrêt de déclaration (voir aussi En perl, quelle est la différence entre $DB::simple = 1 et 2?), avant de s'arrêter à nouveau (note à ce point, le navigateur sera toujours verrouiller).
Donc, maintenant, nous pouvons, dire, étape à travers le reste de l' test.pl
, grâce à l' nc
terminal:
....
main::(./test.pl:29): $b = '4';
DB<1> n
main::(./test.pl:30): print "STEP " . &$a . " NOW\n";
DB<1> n
main::(./test.pl:31): $b = '5';
DB<1> n
main::(./test.pl:32): print "STEP " . &$a . " AGAIN\n";
DB<1> n
Debugged program terminated. Use q to quit or R to restart,
use o inhibit_exit to avoid stopping after program termination,
h q, h R or h o to get additional info.
DB<1>
... cependant, à ce niveau, le navigateur de serrures et attend les données. C'est seulement après la sortie du débogueur avec q
:
DB<1> q
$
... le navigateur arrêt verrouillage - et enfin affiche l' (complète) de sortie de l' test.pl
:
YEAH hello 2 there CMON
CMON hello 3 there YEAH
STEP hello 4 there NOW
STEP hello 5 there AGAIN
Bien sûr, ce genre de débogage peut être fait même sans courir le serveur web - toutefois, le point intéressant ici, c'est que nous ne touchons pas le serveur web; nous déclencher l'exécution "nativement" (CGI) à partir d'un navigateur web et le seul changement nécessaire dans le script CGI lui-même, est le changement de shebang (et bien sûr, la présence de l'arborescence script, en tant que fichier exécutable dans le même répertoire).
Eh bien, espérons que cela aide quelqu'un - bien sûr, j'aurais aimé avoir tombé sur ce, au lieu de l'écrire moi-même :)
Cheers!