Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Perl IDE, leaks et crashs

1 réponse
Avatar
Martin
Bonjour,

Bien que novice en Perl, je m'apprète à mettre en production mon système
codé avec ce langage dans le courant de la semaine prochaine. Je suis plutôt
inquiet des découvertes que j'ai fait cette semaine et j'aimerais avoir
l'avis d'une personne expérimentée. Il semblerait que j'aie un problème
intermitant de leaks et de crashs de l'interpréteur Perl.exe. Voici un
exemple simplifié de mon projet :

use XML::Simple;

# sub test : Fonction interrogant des scripts CGI sur un site web et
retournant la page HTML désirée.
sub test{
my $xml_str = shift @_; # Recoit un XML énorme en parametre.

my $super_struct = XMLin( $xml_str );

my $resultat; # Contient du HTML obtenu par LWP::UserAgent dans chaque
fonction.

# Les fonctions 1 à 7 naviguent selon $super_struct à partir de la page
précédante.

$resultat = fonction1($super_struct);
$resultat = fonction2($super_struct, $resultat);
$resultat = fonction3($super_struct, $resultat);
$resultat = fonction4($super_struct, $resultat);
$resultat = fonction5($super_struct, $resultat);
$resultat = fonction6($super_struct, $resultat);
$resultat = fonction7($super_struct, $resultat);

return $resultat;
}

Toutes les variables sont locales et pourtant, la mémoire utilisé par
perl.exe augmente entre chaque appel des fonctions 1 à 7. Il est possible
que les fonctions utilisent de plus en plus de mémoire mais le nombre de
handles augmente aussi à chaque appel. Je crois donc avoir un problème de
leaks... chose que je croyais impossible avec Perl.

Le second problème troublant que j'ai eu est que l'appel de fonction6() à 2
reprises cause carrément un crash de Perl.exe lorsqu'il y a des breakpoints
dans mon IDE (Open Perl IDE). Sans breakpoint, tout va bien et si je laisse
les breakpoints et que je modifie un peu mes structures de données, tout
fonctionne bien aussi. J'espère de tout coeur que c'est relié uniquement à
l'IDE et que ca ne se produira pas en production. (Il faut comprendre que ce
script gèrera la partie la plus critique de la gestion d'une centrale
nucléaire... ;-) je blague, mais ca m'inquiète quand-même.) En production,
l'interpréteur sera embarqué dans le serveur et je ne voudrais pas voir le
serveur crasher fréquemment sans que je puisse en contrôler la cause. (J'ai
un collègue qui a ce problème avec l'interpréteur PHP dans Apache et je ne
l'envie pas.)

En cherchant, j'ai lu que le ramasse-miettes ne traitait pas les cas de
références cycliques, ce qui peut être une cause de leaks j'imagine. Il est
possible que les fonctions engendrent des références cycliques sur
$super_struct mais comment aurais-je pu faire ca sans m'en rendre compte? Je
n'ai encore jamais essayé d'en créer une volontairement. Et puis même si
c'était le cas, je n'arrive pas à m'expliquer l'augmentation des handles.
Qu'est-ce qu'on vérifie habituellement dans le cadre des projets Perl avant
la mise en production? Comment devrais-je construire mon plan de tests?
Est-ce que l'interpréteur Perl est vulnérable à certaines utilisations?

Vos conseils me seront très précieux!

Merci d'avance!

1 réponse

Avatar
Paul Gaborit
À (at) Sat, 7 Jan 2006 01:20:13 -0500,
"Martin" écrivait (wrote):
[...]
Toutes les variables sont locales et pourtant, la mémoire utilisé par
perl.exe augmente entre chaque appel des fonctions 1 à 7. Il est possible
que les fonctions utilisent de plus en plus de mémoire mais le nombre de
handles augmente aussi à chaque appel. Je crois donc avoir un problème de
leaks... chose que je croyais impossible avec Perl.


Ce n'est pas impossible si vos fonctions créent des références
cycliques...

Le second problème troublant que j'ai eu est que l'appel de fonction6() à 2
reprises cause carrément un crash de Perl.exe lorsqu'il y a des breakpoints
dans mon IDE (Open Perl IDE).
[...]


J'espère que le crash vient soit du debugger de perl soit de
l'IDE. Mais c'est difficile à prouver ;-)

En cherchant, j'ai lu que le ramasse-miettes ne traitait pas les cas de
références cycliques, ce qui peut être une cause de leaks j'imagine. Il est
possible que les fonctions engendrent des références cycliques sur
$super_struct mais comment aurais-je pu faire ca sans m'en rendre compte?


Pour s'en rendre compte (de la présence de cycles), il faut, au
minimum, lire la doc des modules utilisés (et celles des modules dont
ils dépendent...). Mais ce n'est parfois pas documenté. Sinon, il
existe des modules spécifiques pour les détecter :

Test::Memory::Cycle
Devel::Cycle
Devel::Leak::Object
Devel::Leak
...

Et puis même si c'était le cas, je n'arrive pas à m'expliquer
l'augmentation des handles. Qu'est-ce qu'on vérifie habituellement
dans le cadre des projets Perl avant la mise en production? Comment
devrais-je construire mon plan de tests? Est-ce que l'interpréteur
Perl est vulnérable à certaines utilisations?


Le plus simple consiste à faire des test unitaires pour détecter
l'apparation des problèmes. Une autre méthode consiste à utiliser des
modules adaptés. Quand on lit la doc de XML::Simple (en particulier la
section "WHERE TO FROM HERE?"), pour un gros projet, on décide
rapidement de passer à autre chose.

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>