Speicherüberlauf mit dieser Konstellation

Hallo paresy,

nach einigen Test habe ich bei mir den Übeltäter dafür gefunden.

Das ganze lief unter V1 fast 2 Jahre ohne Probleme.

Die Daten kommen von einem Mega8 und werden im Sekundentakt über die Comschnittstelle eingelesen laufen über Cutter und Registervariable und werden Script ausgewertet. Wenn ich die Comschnittstelle deaktiviere bleibt der Speicherverbrauch konstant bei ca. 59MB. Sobald aktiv steigt der Verbrauch in einem Tag auf ca. 124 MB an. Nach 3 Tagen sind es so um die 360 MB.

Fällt Dir irgendetwas auf ?

Im Anhang die Daten von Com => Cutter => Regvar.

<?
/*
*******************************
 IP-SYMCON Event Scripting
*******************************
File     : DatenTempAlarm.ips.php
Trigger  :
Interval :
*/

//RegVar_SetRXMaxBufferSize(33453 /*[.DatenMega8\RegVTempAlarm]*/,128);

$Kennungen = array("1:" => 49915,
                   "2:" => 22029,
                   "3:" => 34762,
                   "4:" => 15613,
                   "5:" => 42420,
                   "6:" => 39046,
                   "7:" => 38608,
                   "A:" => 40356,
                   "B:" => 10482,
                   "C:" => 18347,
                   "D:" => 30103);

//Dateneingang von Registervariable
$Daten = $IPS_VALUE;
$Kennung = substr($Daten, 0, 2);
$buffer = explode($Kennung, $Daten);
//print_r($Kennung);
//print_r($buffer);
// Daten ausgeben
if (count($buffer) > 1)
{
if (ord($Kennung[0]) < ord('A'))
  SetValue($Kennungen[$Kennung], (float)trim($buffer[1]));
else
  SetValue($Kennungen[$Kennung], (integer)$buffer[1]);
}
?>

Hallo RWN,
Hallo Parsey,
ich erlaube mir, mich hier auch gleich wieder anzuhängen

… ich sende alle 2 Sekunden den Anforderungsrequest (5Byte) und erwarte dann den Response von 71Byte, diese Daten werden dann eben über das Script der RegisterVariable den Buffer hinzugefügt, normalerweise wird das Script für das empfangen der Daten (71byte) ==> 19mal aufgerufen = 18x4ms + 1x14ms (letzter Empfang dann wird auch gleich die Auswertung der Daten durchgeführt)

… in dieser Konstellation steigt eben bei einer 2 Sekundentaktung der Speicher um 10MB je Stunde

Als zweites Problem habe ich noch, wenn der RegVarBuffer über das Anforderungsscript zurückgesetzt (gelöscht) wird, dann kommt der Inhalt des Empfangsbuffers durcheinander nach ca. 2 Stunden durcheinander ==> es kommen im Buffer nicht mehr die Daten an, welche über das COM-Port gesendet wurden (Problem kann durch schliessen und wieder öffen des COM-Ports gelöst werden)

Das Projekt wo das Problem auftritt, kann man hier downloaden http://www.ip-symcon.de/forum/f53/siemens-logo-ip-symcon-7155/#post58951

tgusi74

REGVAR_BUFFER.jpg

Ich vermute ein Speicherleck im RegisterVariable Modul gefunden zu haben. Gebt mir noch ein wenig Zeit, um es zu verifizieren. Dann wird es den Fix geben.

paresy

Anbei eine neue Version von Register Variable, die das Speicherleck-Problem hoffentlich löst.

paresy

Hallo paresy,

das sieht nicht gut aus.

Sowie es aussieht kommt die Meldung von allen Serial Ports

Hallo Parsey,
kann leider auch keine positive Rückmeldung geben

… habe jetzt seit 18:30 den Test laufen und der Speicher sieht gut aus :slight_smile: steht nach 3 Stunden auf jedenfall noch unter 40MB, jedoch kommt es immer wieder zu Fehlermeldungen bzw. fehlerhalten Pufferinhalten (siehe Anhang - Meldungen der COM1)

… ich kann die neue DLL auch nur an der internen Schnittstelle des Rechners COM1 laufen lassen, den an der COM1 verhälten sich die Scriptaufrufe etwas anders als an der COM3 !!! ==> an der COM1 werden für die 71Byte normalerweise die RegVar-Scripts ca. 6 mal getriggert !! (siehe Anhang) an der COM3 (USB-COM-Adpater von C* mit Handshakeleitungen) werden die Scripts 19x getriggert (siehe Anhang vorheriges Posting) und es kommt nach ca. 30 Sekunden der Bufferinhalt durcheinander (Bufferinhalt entspricht nicht den Daten welche über das COM-Port geschickt wurden)

… verwende ich wieder die alte DLL für die COM3, ist wieder alles in Ordnung und es läuft sicher wieder 2-3 Stunden

tgusi74

Ok. Neuer Versuch. Habe noch ein paar Änderungen vorgenommen und ein wenig mehr „Stress-Getestet“, um zu sehen, ob Pakete verdreht/verschluckt werden. Bis jetzt funktioniert es bei mir aber gut.

paresy

StrUtilities.rar (89 KB)

läuft zumindest jetzt ohne Fehler :slight_smile:
mehr sehe ich bis morgen. Im Moment steht der Speicher bei 50MB.

Hallo PARESY,
leider wieder keine guten Nachrichten

COM1 (interne Schnittstelle) läuft bis jetzt fehlerfrei !! :slight_smile:

COM3 (USB-Adapter) kommt es immer wieder zu ACCESS VIOLATIONs bzw. zu fehlerhaften Pufferinhalten

Habe jetzt auch die Testscripts auf das nötigste reduziert

Anforderungsscript

<?
$ComPortID         = 33848 /*[Serial_Port_COM3]*/ ;
$RegVar_COM3_READ  = 35886 /*[LOGO\RegisterVariable_COM3_READ]*/ ;
$RegVar_COM3_WRITE = 39138 /*[LOGO\RegisterVariable_COM3_WRITE]*/ ;

COMPort_SetRTS ($ComPortID,false);
COMPort_SetDTR($ComPortID,false);
IPS_Sleep(50);

COMPort_SetDTR($ComPortID,true);
COMPort_SetRTS ($ComPortID,true);

//LeseBuffer leeren bevor neuen Request
RegVar_SetBuffer($RegVar_COM3_READ,"");
IPS_Sleep(50);

//dieses ECHO bewirkt offensichtlich wunder in Verbindung mit der USB-COM-Schnittstelle
echo("SENDE NEUE ANFORDERUNG " . date("H:i:s"));

//Schreibe BEFEHL an die LOGO! --> 0x55 0x13 0x23 0x00 0xAA
RegVar_SendText($RegVar_COM3_WRITE, chr(hexdec("55")).chr(hexdec("13")).chr(hexdec("13")).chr(hexdec("00")).chr(hexdec("AA")));
	
?>

RegVar - Read

<?
$RegVar_COM3_READ  = 35886 /*[LOGO\RegisterVariable_COM3_READ]*/  ;

//BUFFER FUELLEN --> Daten lesen von COM-Port
$buf = RegVar_GetBuffer($RegVar_COM3_READ) .$IPS_VALUE;
RegVar_SetBuffer($RegVar_COM3_READ,$buf);


if (strlen($buf)>= 71)
	{
    if (ord($buf[8]) == 17)
         {
		  echo("DATENEMPFANG OKAY Byte8=" . ord($buf[8]) . " ==> " . strlen($buf) . " Zeichen
");
		 }
    else
		 {
        echo ("ERROR: Lesebuffer verschoben !! --> Typ=Byte[8]='" . ord($buf[8])."' (Pufferheader='" 
           . ord($buf[0]) . " " . ord($buf[1]) . " " . ord($buf[2]) . " " 
           . ord($buf[3]) . " " . ord($buf[4]) . " " . ord($buf[5]) . " " 
           . ord($buf[6]) . " " . ord($buf[7]) . " " . ord($buf[8]) . " " 
           . ord($buf[9]) . " " . ord($buf[10]) . " " . ord($buf[11]) . "')
" );
		 }
	}
?>

… irgendwie bewirkt die ECHO - Ausgabe vor dem „neuen Request“ aber in Verbindung mit dem USB-COM-Port wunder, es kommt auf einmal zuviel weniger Pufferfehlern ==> daher meine Frage, löst das ECHO eine Verzögerung aus, welche irgendwie das Puffer schreiben (der beiden Scripte ==> 1. will löschen / 2. will Daten im Puffer hinzufügen) positv beeinflusst ==> Habe mir auch schon überlegt nach den Löschen eine WHILE-Schleife einzubauen, welche prüft ob der Puffer wirklich leer ist bevor der neue Request abgesetzt wird ?? (Glaube zwar das es keinen positven Erfolg bringt wird) ==> gibts dafür eine andere Möglichkeit eine Art SEMAPHORE zwischen die beiden Scripts zu bekommen ??

Was mir auch mit den beiden neuen DLLs aufgefallen ist (verstärkt mit der heutigen), das man beim Arbeiten in der Konsole vorhältnissmässig oft, das POPUP „Socket-Fehler #10048 Die Adresse ist bereits in Gebrauch“ bekommt, wenn man ein Objekt öffnen will (z.B. IO-Instanz des COM-Ports / Script der RegVariable)

tgusi74

SOCKET_ERROR.jpg

Dir ist bewusst, dass es eine Suchfunktion gibt? Die hätte Dir dann zu Semaphore z.B. IPS_SemaphoreEnter - IP-Symcon :: Automatisierungssoftware ausgegeben… :rolleyes:

Hallo paresy,

zuerst dachte ich, sieht gut aus. Der Speicher stand heute Morgen bei 54MB.
Leider ist das System heute Nacht um 3:24 Uhr ohne ersichtlichen Grund stehen geblieben. Dienst beenden ging nicht nur über Taskmanager killen.

Neu gestartet, 10min später ging wieder nichts. Das war das erste mal in fast 2,5 Jahren das bei mir das System ohne ersichtlichen Grund stehen blieb.

29.05.2009 03:23:00.503 | 36350 | DEBUG   | ExecuteThreadID #3   | Skriptausführung: Graphenupdate.php ~ Absender: Ereignis #18120, Zeit Ereignis
29.05.2009 03:23:00.581 | 36350 | DEBUG   | ExecuteThreadID #3   | Ausgeführt, Resultat: 1, Erfolgreich: True, Zeit: 90 ms
29.05.2009 03:23:00.987 | 15808 | DEBUG   | ExecuteThreadID #3   | Skriptausführung: 15808.ips.php ~ Absender: RegisterVariable
29.05.2009 03:23:00.987 | 39046 | DEBUG   | VariableManager      | [.DatenMega8\DatenTempAlarm\Temp2] = 19.1
29.05.2009 03:23:00.987 | 15808 | DEBUG   | ExecuteThreadID #3   | Ausgeführt, Resultat: 1, Erfolgreich: True, Zeit: 1 ms
29.05.2009 03:23:01.987 | 15808 | DEBUG   | ExecuteThreadID #3   | Skriptausführung: 15808.ips.php ~ Absender: RegisterVariable
29.05.2009 03:23:01.987 | 38608 | DEBUG   | VariableManager      | [.DatenMega8\DatenTempAlarm\Temp3] = 19.1
29.05.2009 03:23:01.987 | 15808 | DEBUG   | ExecuteThreadID #3   | Ausgeführt, Resultat: 1, Erfolgreich: True, Zeit: 1 ms
29.05.2009 03:23:02.987 | 15808 | DEBUG   | ExecuteThreadID #3   | Skriptausführung: 15808.ips.php ~ Absender: RegisterVariable
29.05.2009 03:24:07.925 | 34525 | DEBUG   | VariableManager      | [Obergeschoss\Badezimmer\Heizungsregler Bad\Ventilposition] = 0

Das war der letzte Eintrag!
Ich werde es weiter beobachten.

Edit: grade ein Serial Fehler.
Edit2: im Log von 00:00 Uhr bis3:24 Uhr hab ich das auch noch gefunden.

und hängt schon wieder. Ich mach die alte dll. wieder drauf :frowning:

Hallo zusammen

Ich hab ja auch das „Speicherproblem“ und muss sagen seit ich gestern die dll von paresy installiert habe hab ich fast keinen Anstieg mehr. Seit 18 Stunden ca. 67mb Speicher bzw 58mb virtuellem Speicher. Sonst ist der Speicherbedarf in der Zeit immer um 300mb und mehr gestiegen.

Bin bis jetzt also zufrieden, habe auch keine Fehler im Log gefunden, geschweige denn einen absturz wie von RWN berichtet.

Gruß Jannis

Hallo,
habe vorhin einen Sempahore über eine IPS-Variable eingebaut, damit die Scripts sich auf keinen Fall mehr in die Wege kommen können !!!

… seit dem habe ich auch keine „korrupten Daten“ mehr von USB_COM-Port :slight_smile: , mir fällt auf das seit den „neuen DLLs“ sich eben das Auslesen des Buffers komisch verhält !!

Wenn man sich das Debugfenster ansieht, werden die Daten „Receive“ in Millisekundentakt empfangen (so wie Sie eben über das COM-Port gesendet werden), jedoch dann das Buffer auslesen „Buffer“ dauert oft „ewig“ bis dann die Daten verarbeitet werden ==> Im meinen konkreten Fall liegen zwischen Datenempfang und das alle Daten im RegVarBuffer sind bis zu 11 Sekunden (Sriptlaufzeit 1-2ms) :confused:

… daher auch kein Wunder das sich die Scripts in die Wege gekommen sind !! ==> eigentlich müsste die Verarbeitung leicht innerhalb einer Sekunde fertig sein :wink:

@Horst:
mir waren die Befehle „IPS_SemaphoreEnter“ und „IPS_SemaphoreLeave“ bekannt, aber was bringen die mir wenn ich über Scriptgrenzenhinweg eine Verriegelung brauche (RegVar - Script wird meist >5 mal aufgerufen) und die Befehle aber innerhalb des Scriptes wieder aufgehoben werden müssen, ansonsten „Warning: Semaphore ‚LOGO_SEMAPHORE‘ was not released!“ und der Script wird fehlerhaft makiert

tgusi74

Hallo PARESY,
habe jetzt zwar keine Pufferprobleme mehr seit 17:30, jedoch ist IPS wie schon RWN beobachtet hat seit dem zweimal eingeschlafen !!!

… es wird nichteinmal mehr das Timerevent gestartet

Habe auch seit 19:00 das Anforderunginterval auf 10 Sekunden gestellt und einen Zähler eingerichtet welcher mir die Aufrufe zählt, wo es zu einer Kollision der Scripte gekommen währe ==> Habe so 4x das Ereigniss gehabt das der Bufferinhalt über 10 Sekunden zum auslesen benötigt hat (Zähle einfach die TimerEvents wenn der Semaphore noch sitzt)

Semaphore ist im Moment so programmiert ==> Es wird das Anforderungsscript abgebrochen wenn der Semaphore noch beim neuen Timerevent sitzt bzw. das Timerevent mehr als 10x durchlaufen wurde und der Semaphore immer noch sitzt wird eine Zwangslöschen des Semaphore durchgeführt (nächstes Timerevent setzt dann den Request ab)

tgusi74

Es muss sich irgendwo noch ein Deadlock Problem eingeschlichen haben. Meine Test-Cases scheinen noch nicht genügend komplex zu sein. Muss mir da noch etwas ausdenken, wie ich das gut simulieren kann. Das Geschwindigkeitsproblem werde ich mir ansehen.

paresy

Hallo paresy,

die beste Testumgebung hast Du warscheinlich bei uns.
Du darfst mir gerne die dll zusenden. Viel schlimmer kann es ja nicht mehr werden :smiley:

Hallo paresy,

wie weit bist du denn mit deiner Testumgebung ?

Hallo paresy,

mit der 2.1 ist es besser geworden. Nach 24h nur noch 71MB anstatt 124MB.
Also scheint es nicht nur an der RegVar zu liegen.

Hilft Dir jetzt warscheinlich auch nicht viel, daher nur zur Info :slight_smile:

Nach 60h steht der Speicher bei 81MB.

Ist zwar schon ein bischen angestaubt der Thread, aber ich geb noch mal Feedback.
Bei mir läuft es jetzt. Speicher pendelt je nach Auslastung zwischen 45 und 55 MB. Alles im grünen Bereich. :cool: