8
votes

Comment étudier "tenter de libérer un scalaire non référencé"

Un script PERL (qui utilise une charge de modules écrits localement et est en développement actif) vient de commencer à produire sporadique

"Tentative de libre éclairage non référencé: SV 0xa6e685c, interprète Perl: 0x96D9008 pendant la destruction mondiale. "

messages. Ceci est toujours répétable, dans le sens où une séquence particulière de commandes produit toujours le message si jamais, mais je n'ai pas réussi à isoler un cas simple ou autonome qui l'inclure. En particulier, je ne l'ai pas encore vu lors de l'exécution du script de Perl Debugger (je peux l'obtenir lors du débogage d'un script qui utilise IPC :: Open3 pour exécuter mon script cible.)

Je me rends compte que ce n'est peut-être qu'un bug de Perl, mais beaucoup plus susceptible d'être quelque chose que je fais que je fais, très probablement autour de mes appels vers Svn :: Client; Mais je suis exclu pour une façon de l'enquêter, et je me demandais si quelqu'un avait des indicateurs.

Perl 5.10.0; Diverses versions de Fedora Linux. Je vais l'essayer sur Perl 5.12, mais à moins que cela ne manifeste là aussi, cela ne m'aidera pas vraiment. edit : un cas particulier qui donne le message de manière fiable en 5.10 en 5.12. Malheureusement, cela ne me dit pas vraiment rien.


1 commentaires

5.14 est la version actuelle de Perl. 5.12 et 5.10 sont plutôt vieux. Mais de toute façon, compiler Perl avec débogage afin que vous puissiez voir ce qui a créé le SV à 0xa6e685C. Cela devrait vous indiquer dans la bonne direction. (Je suppose que SVN :: Le client ou un autre module XS est cassé.)


5 Réponses :


1
votes

Ceci est souvent associé à des problèmes de filetage, en particulier en passant une variable d'un fil à un sous-programme exécutant dans une autre. Voici un exemple abstrait du motif:

a.pl fort> p> xxx pré>

b.pm strong> p>

....
sub c{...}
....


3 commentaires

Vous devriez donner un lien vers le message d'origine (je l'ai également trouvé sur Google).


Ce n'est pas simplement un repumet, mais oui, le code d'échantillon et l'idée de base a été prise de tek-tips.com/viewththread.cfm?qid=1346880&page=133 . J'ai confirmé l'idée sur plusieurs autres liens avant de composer cette réponse. J'aurais dû donner crédit pour commencer.


J'ai 99,9% certains que nous n'utilisons pas de threads dans notre code. Peut-être qu'un module standard ou cpan fait. Merci quand même.



1
votes

Je rencontre également ces messages beaucoup (dans le code qui utilise Fourche beaucoup) et le problème connexe des défauts de segmentation pendant la phase de destruction mondiale (c'est-à-dire que le programme peut terminer normalement, mais Une erreur pendant la destruction mondiale peut rendre le programme Quitter avec un code de sortie non nul). Je ne sais pas non plus si ces problèmes peuvent être réparés, mais ils peuvent généralement être résolus.

Tout d'abord, utilisez une variable globale pour détecter si vous êtes dans la phase de destruction globale: xxx

(voir aussi le $ {^ global_phase} variable disponible à Perl V> = 5.13.7)

puis évitez de courir le code gênant pendant la phase de destruction globale: xxx


3 commentaires

Parfois, il est nécessaire de sauter la destruction mondiale, mais si vous utilisez des modules XS qui ne peuvent pas survivre à Fork + Destroy, ils doivent être corrigés. Si le code PURE PERL fait cela, veuillez déposer un rapport de bogue PERL!


La situation spécifique que j'ai à l'esprit est un gestionnaire SIGCHLD qui met à jour beaucoup d'état lorsqu'un processus d'enfant est récolté. Supposons maintenant que le programme principal se termine et au milieu de la destruction mondiale, un processus d'enfant précédent se termine et le gestionnaire Sigchld est appelé. Il ne sert à rien de mettre à jour quoi que ce soit parce que le programme principal est terminé et la moitié des éléments que vous mettrez mis à jour a été recueilli (mais seulement la moitié). Vous indiquez donc à votre gestionnaire de signal qu'il n'a pas besoin de faire quoi que ce soit une fois que la file d'attente a commencé.


Merci pour la suggestion, mais je ne sais pas ce que "le code gênant" est. Je pense que c'est très probablement dans les liaisons de subversion que je n'ai aucun contrôle. La question est de savoir s'il s'agit simplement d'un bogue d'entre eux, ou s'il s'agit d'un appel louche que je fais.



2
votes

Réponse tardive, mais j'ai écrit un long article sur ce sujet particulier qui devrait aider à déboguer: la« tentative de scalaire libérée ».


1 commentaires

Bien que cela puisse théoriquement répondre à la question, Ce serait préférable d'inclure les parties essentielles de la réponse ici et de fournir le lien pour référence.



0
votes

Vérifiez tous les types de types de référence _g. un typeglob pour un hachage de hachage. J'ai couru dans ceci avec un typeglob utilisé pour basculer entre différents hachages de matrices. L'erreur s'est produite lorsque des entrées ont été supprimées à la fois sur le type Typeglob et le nom de hachage d'origine. Soit en utilisant un hasch simple sans niché ni débarrasser du typeglob éliminé le problème.


0 commentaires

0
votes

foreach (@var) code> est un autre bon candidat à l'inspection.

Le code suivant m'a donné cet avertissement: p> xxx pré>

mais SUIVANT N'A PAS: P>

while (scalar(@list1)) {
    my ($i, $j) = @{shift(@list1)};
    my $k = get_k($i, $j);
    foreach (@$k) {
        sub_that_uses_fork($_);
    }
}


0 commentaires