Stefan Welscher: Hilfe! Perl schmeißt Variablen durcheinander....

Hi,

ich hab grad ein sehr stranges Problem bei Perl.
Ich hab einene Automaten zur Konfigurationserstellung, der (alle Module zusammen gerechnet) ca. 750KB Quelltext beinhaltet. Benötigt werden davon für einen Durchlauf etwa 400KB (Es werden nicht immer alle Module geladen). Das Hauptmodul des Automaten verwendet ein zentrales Hash %I. Die Referenz auf dieses Hash wird an die Untermodule weitergegeben, so dass diese eigene Werte und Variablenstrukturen anfügen können. Das Hash hat dann schätzungsweise mal 250 Werte.

Bis jetzt hatte ich damit auch überhaupt keine Probleme, aber jetzt habe ich schon zwei mal das Phänomen, dass Perl Variablenwerte willkürlich tauscht.

Die zwei Beispiele sehen folgendermaßen aus:
1. Beispiel:

  
  
..........  
  
my $VOsched=abrunden(($VObw+$NCbw)/$L2BW,2);  
  
print "\n\nVOsched=".$VOsched."\n";  
  
my $BUbw=abrunden($L2BW*((1-$tmp3-(1/$L2BW*$VObw))*$business));  
my $BUsched=abrunden($BUbw/$L2BW,2);  
  
my $STbw=abrunden($L2BW*((1-$tmp3-(1/$L2BW*$VObw))*$stream));  
my $STsched=abrunden($STbw/$L2BW,2);  
  
print "\nSTsched=".$STsched."\n";  
  
my $ECsched=1-($STsched+$BUsched+$VOsched);  
  
..........  
  
$I{'pe'}{'qos'}{'wan'}{'mvpn'}{$count_vpn}{'ec'}{'epd'}=$ECepd;  
$I{'pe'}{'qos'}{'wan'}{'mvpn'}{$count_vpn}{'ec'}{'sched'}=$ECsched;  
$I{'pe'}{'qos'}{'wan'}{'mvpn'}{$count_vpn}{'vo'}{'pol'}=$VOpol;  
$I{'pe'}{'qos'}{'wan'}{'mvpn'}{$count_vpn}{'vo'}{'pol_ml'}=$VOpolML;  
$I{'pe'}{'qos'}{'wan'}{'mvpn'}{$count_vpn}{'vo'}{'epd'}=$VOepd;  
  
print ".VOsched=".$VOsched."\n";  
print ".VOsched=".$I{'pe'}{'qos'}{'wan'}{'mvpn'}{$count_vpn}{'vo'}{'sched'}."\n";  
  
$I{'pe'}{'qos'}{'wan'}{'mvpn'}{$count_vpn}{'vo'}{'sched'}=$VOsched;  
print "..VOsched=".$VOsched."-ECsched=".$ECsched."\n";  
print "..VOsched=".$I{'pe'}{'qos'}{'wan'}{'mvpn'}{$count_vpn}{'vo'}{'sched'}."\n";  
  
$I{'pe'}{'qos'}{'wan'}{'mvpn'}{$count_vpn}{'nc'}{'pol'}=$NCpol;  
$I{'pe'}{'qos'}{'wan'}{'mvpn'}{$count_vpn}{'nc'}{'pol_ml'}=$NCpolML;  
  
print "...VOsched=".$I{'pe'}{'qos'}{'wan'}{'mvpn'}{$count_vpn}{'vo'}{'sched'}."\n";  
  
$I{'pe'}{'qos'}{'wan'}{'mvpn'}{$count_vpn}{'st'}{'pol'}=$STpol;  
  
$I{'pe'}{'qos'}{'wan'}{'mvpn'}{$count_vpn}{'st'}{'burst'}=$STburst;  
$I{'pe'}{'qos'}{'wan'}{'mvpn'}{$count_vpn}{'st'}{'epd'}=$STepd;  
  
print "....VOsched=".$I{'pe'}{'qos'}{'wan'}{'mvpn'}{$count_vpn}{'vo'}{'sched'}."\n";  
  
#$I{'pe'}{'qos'}{'wan'}{'mvpn'}{$count_vpn}{'st'}{'sched'}=$STsched;  
  
print ".....VOsched=".$I{'pe'}{'qos'}{'wan'}{'mvpn'}{$count_vpn}{'vo'}{'sched'}."\n";  
  
$I{'pe'}{'qos'}{'wan'}{'mvpn'}{$count_vpn}{'bu'}{'pol'}=$BUpol;  
$I{'pe'}{'qos'}{'wan'}{'mvpn'}{$count_vpn}{'bu'}{'burst'}=$BUburst;  
$I{'pe'}{'qos'}{'wan'}{'mvpn'}{$count_vpn}{'bu'}{'epd'}=$BUepd;  
$I{'pe'}{'qos'}{'wan'}{'mvpn'}{$count_vpn}{'bu'}{'sched'}=$BUsched;  
print ".......VOsched=".$I{'pe'}{'qos'}{'wan'}{'mvpn'}{$count_vpn}{'vo'}{'sched'}."\n";  
  
..........  

Wenn ich die Kommentierte Zeile unkommentiert lasse, wird der Wert von VOsched zwischen der Ausgabe mit den 4Punkten und der Ausgabe mit den 5Punkten auf "0" gesetzt. STsched hätte zu diesem Zeitpunkt ebenfalls den Wert "0". Kommentiere ich die Zeile wie hier im Beispiel aus, wird die VOsched erst zwischen den Ausgabe mit 5 unkten und der mit 6 Punkten auf "0" gesetzt. Wenn ich nur ein VPN habe ($count_vpn bleibt immer "1") tritt der Fehler nicht auf.

2. Beispiel:

  
...........  
  
$I{'pe'}{'wan'}{'port'}{1}{'ifc'}=="e1-".$I{'pe'}{'wan'}{$a}{'port_number'}; }  
  
...........  
  
$I{'pe'}{'wan'}{1}{'ifc'}=$I{'pe'}{'wan'}{'mlfr'}{'ifc'};  
  
..........  
  

Wir die zweite hier aufgeführte Anweisung ausgeführt ändert sich der Wert der erten Anweisung auf den den zweiten.
Hier konnte ich mir folgenden Workaround basteln:

  
my $save_fist_port_if=$I{'pe'}{'wan'}{'port'}{1}{'ifc'};  
$I{'pe'}{'wan'}{1}{'ifc'}=$I{'pe'}{'wan'}{'mlfr'}{'ifc'};  
$I{'pe'}{'wan'}{'port'}{1}{'ifc'}=$save_fist_port_if;  

Und nun die Frage aller Fragen:
Warum würfelt Perl hier die Variablen durcheinander????

Gibt es evtl. eine Speicherbegrenzung für Perl, bzw. kann man unter Unix oder irgendwelchen Perl-Conf-Files Limits einstellen, die einen solchen Fehler verursachen können.
Hat Perl evtl. nur eine begrenzte Anzahl von Hash-Feldern zur Verfügung?
Oder kann es doch noch ein Fehler im Quelltext sein?

Bitte habt Verständnis, dass ich hier keine größeren Abschnitte firmeninterner Automaten bereitstellen kann und auch nicht den gesamten Automaten mit derzeit wohl ca. 10.000 Zeilen Quelltext hochladen kann.

1111101000 Dank schonmal!

  1. Hi Stefan,

    der Code ist sehr unübersichtlich, Kommentare fehlen. Indes verrät er mir, dass es um Internetzugänge und Abrechnungen geht (billing), das solltest Du hier nicht so zeigen ;-)

    Meine Hilfe beschränkt sich auf drei Tipps:

    perl -w
    use strict;

    use comments

    --roro

  2. Hallo !

    Dieser Teil Deiner Beschriebung

    Die Referenz auf dieses Hash wird an die Untermodule weitergegeben, so dass diese eigene Werte und Variablenstrukturen anfügen können.

    laesst mich ein Problem vermuten das durch die Kooperation der Untermodulen verursacht wird.

    Wenn z.B.

      
    $I{'pe'}{'qos'}{'wan'}{'mvpn'}{$count_vpn}{'vo'};  
    # und  
    $I{'pe'}{'qos'}{'wan'}{'mvpn'}{$count_vpn}{'st'};  
    
    

    in getrennten Modulen zufaellig mit Referenzen auf den gleichen Hash versorgt wurden ?

    Ist Dein System eigentlich nebenlaeufig ?
    Wenn ja, poste bitte mal den Code den die Module zum einfuegen in den Hash verwenden.

    Gruss

    Holger