Nicht beendete Skripte

Nach ca. 2 Tagen Laufzeit sieht es auf meinen Raspis in etwa so aus (bitte weit unterhalb des Bildes weiterlesen):

Hintergrund:
Ich verwende die JSON/RPC-Funktion sehr häufig: alle 10 Minuten senden die Raspis zeitversetzt an alle anderen mit denen sie Datenaustausch pflegen einen Aufruf; außerdem senden alle Daten an das Haupsystem, sobald diese Meßwerte verändert sind. Der Transfer erfolgt immer über das Skript JSON_TX.ips.php
Diese Skript bleibt irgendwann mal hängen (wird nicht beendet) obwohl es das Statement set_time_limit(50); enthält und sitz dann als „Mumie“ in der Liste der laufenden Threads.

Fragen:

  1. Wieso passiert das (ist irgenwas diesbezügliches über die JSON/RPC-Funktion bekannt)?
  2. Wie kann ich feststellen, an welcher Stelle des Skriptes die Ausführung hängt (Im Log ist nichts erkennbar)?
  3. Wie kann ich die hängenden Skripte innerhalb von IPS (oder Linux) beeenden ?

Mein Hauptsystem unter Win7 mit IPS 3.4 benutzt dasselbe Skript, ruft das Skript häufiger auf und dort tritt der Fehler nicht auf.

Viele Grüsse
Harald

Magst du mal ein paar Details zu deinem System geben? Insbesondere Linux-Version und Kernel-Version. Wir hatten hier im Linux Kernel vor ein paar Monaten einen Bug, der genau dieses Phänomen hatte. Ggf. somit mal alles aktualisieren. Insbesondere rpi-update.

paresy

IP-Symcon 4.00, 17.02.2016, 7a945af31e30

13:50:20[pi@RaspiB5:~] $ uname -a
Linux RaspiB5 4.1.13-v7+ #826 SMP PREEMPT Fri Nov 13 20:19:03 GMT 2015 armv7l GNU/Linux
13:50:22[pi@RaspiB5:~] $ cat /proc/version
Linux version 4.1.13-v7+ (dc4@dc4-XPS13-9333) (gcc version 4.8.3 20140303 (prerelease) (crosstool-NG linaro-1.13.1+bzr2650 - Linaro GCC 2014.03) ) #826 SMP PREEMPT Fri Nov 13 20:19:03 GMT 2015
13:50:40[pi@RaspiB5:~] $

HM, hatte mal Probleme mit einer Linux Version, könnte die 13 gewesen sein. Im Moment bin ich bei :
4.1.20-v7+

Wenn du rpi-update den Kernel aktualisierst, sollte der Fehler weg sein.

paresy

Hab alle meine Raspis per sudo rpi-update upgedated auf diese Version:

17:17:32[pi@RaspiB5:~] $ uname -a
Linux RaspiB5 4.4.7-v7+ #876 SMP Tue Apr 12 22:28:41 BST 2016 armv7l GNU/Linux
17:17:37[pi@RaspiB5:~] $ cat /proc/version
Linux version 4.4.7-v7+ (dc4@dc4-XPS13-9333) (gcc version 4.9.3 (crosstool-NG crosstool-ng-1.22.0-88-g8460611) ) #876 SMP Tue Apr 12 22:28:41 BST 2016
17:17:52[pi@RaspiB5:~] $

und da der Fehler seit 2 Tagen nicht mehr aufgetreten ist, ist er wohl beseitigt.

Vielen Dank für den Tip.

Lediglich mein Banana will nicht ganz aktuell werden:

20:20:42[pi@Banana1:~] $ sudo rpi-update
 *** Raspberry Pi firmware updater by Hexxeh, enhanced by AndrewS and Dom
 *** Performing self-update
 *** Relaunching after update
 *** Raspberry Pi firmware updater by Hexxeh, enhanced by AndrewS and Dom
 *** Your firmware is already up to date
20:20:47[pi@Banana1:~] $ uname -a
Linux Banana1 3.4.90 #1 SMP PREEMPT Wed Jul 2 15:10:20 CST 2014 armv7l GNU/Linux
20:21:08[pi@Banana1:~] $

Aber auch da tritt der Fehler nicht mehr auf.

Viele Gruesse
Harald

Beim Banana geht rpi-update nicht !
rpi-update ist nur für den Pi Kernel !

Abhilfe mit der Prozedur wie in https://www.bananian.org/upgrade beschrieben.

Besonders aktuell scheint der Bananien Fork aber nicht zu sein (wir haben jetzt 2016):

10:31:12[pi@Banana1:~] $ uname -a
Linux Banana1 3.4.90+ #1 SMP PREEMPT Fri Sep 12 18:13:45 CEST 2014 armv7l GNU/Linux
10:31:19[pi@Banana1:~] $ cat /proc/version
Linux version 3.4.90+ (root@nico-desktop) (gcc version 4.8.2 (Ubuntu/Linaro 4.8.2-16ubuntu4) ) #1 SMP PREEMPT Fri Sep 12 18:13:45 CEST 2014
10:32:17[pi@Banana1:~] $

Aber wie schonmal geschrieben: die Fehler treten nicht mehr auf.

Magst du die TX und RX Scripte zur Verfügung stellen ???

Stelle mir auch sowas vor - stehe aber mit RPC noch auf dem Schlauch

Das Posten dieser Skripte würde Dich sicher stark verunsichern (in etwa O-Ton Bundesinnereienminister):slight_smile:

Die sind nämlich eingebunden in verschiedene Parameterskripte, die ich sicher nicht erklären möchte, weil unendlich zeitaufwendig.

Nur mal ein kurzer Abriß:
Die RPC-Aufrufe mache ich in separaten Skripten, damit die Wirk-Skripte weiterarbeiten, wenn wg. fehlendem Connect ein JSON-Fehler auftritt.

Wie die Daten des/der anderen PC’s hinterlegt sind, hatte ich hier schon mal beschrieben.

JSON_TX.ips.php funktioniert dann im Prinzip so:


...
include_once "ObjIDsLAN.inc.php";
...
switch ($_IPS['SENDER']) {      // woher aufgerufen ??
...
        
// ---- C. Skriptauslöser anderes Skript, ggf. Scheduler
    case "RunScript": /* Wenn das Skript durch eine IPS_RunScript Funktionen ausgeführt wurde
         */

        /* Aufruf wird normalerweise einfach an 'JSON/RX' des 'PcRX' durchgereicht
         * Sonderfälle sind 'Cmd' =>
         * dann ist hier der Postausgangskasten
         */

// POSTAUSGANG
// Test ob alle Parameter da 
        foreach (array ('PcRX', 'Cmd' ) as $Par) {
            if ( ! (isset ($_IPS[$Par])))
                die ("Mit RunScript wurde '$Par' nicht an JSON-TX übergeben!");
        }
...
            // $rpc = new JSONRPC ("http://user:password@'IP':'Port'/api/");
            $rpc = new JSONRPC ("http://" . $LAN['Svr1']['Li'] . ':' . $LAN[$_IPS['PcRX']]['PW'] . '@' .
                    $LAN[$_IPS['PcRX']]['IP'] . ':' . $LAN[$_IPS['PcRX']]['Port'] . '/api/');

// sonst Aufruf mit Cmd
            switch ($_IPS['Cmd']) {

                case 'Sonderfälle' :
                    break;

                default:                        // sende an Remote ObjID
                    $rpc -> IPS_RunScriptEx ($LAN[$_IPS['PcRX']]['ObjRX'], array_merge ($_IPS, array (// reiche Parameter durch
                        'PcTX'  => PCname,
                        'GenDt' => time (), // an dem Datum generiert
                        'TRIG'  => GetIdentPathByObjectID ($_IPS['TRIG']), // wurde ursprünglich aufgerufen von ....
                        'TRIG2' => GetIdentPathByObjectID ($_IPS['SELF']), // und transferiert von ....
                        'SEND2' => $_IPS['SENDER'])));
            }   // Ende Switch $_IPS['Cmd']
 
        break;  // Ende RunScript
        
....


Meine Spezialitäten mit „GetIdentPathByObjectID“ hatte ich mal hier beschrieben.

Auf dem ‚PcRX‘ wird per JSON ‚JSON_RX.ips.php‘ aufgerufen:


...
include_once "ObjIDsLAN.inc.php";
...
switch ($_IPS['SENDER']) {      // woher aufgerufen ??
...

// ---- C. Skriptauslöser anderes Skript, ggf. Scheduler
    case "RunScript": /* Wenn das Skript durch eine IPS_RunScript Funktionen ausgeführt wurde
         */

        /* Aufruf in diesem Format:
          IPS_RunScriptEx(PuIEreignis, array (
          'Cmd'   => 'GetBox', 'PutData', 'SetSkript', 'ActData', 'DtaData' (mand.)
          'Act'   => 'BLEscan/ACT'    (opt. Identpfad:)
          'PC'    => PCname,       // noch temporär
          'PcTX'  => PCnameSender
          'PcRX'  => PCnameEmpfänger
          'GenDt' => an dem Datum generiert
          'ObjTp' => LE = Bluetooth Low Energie
          'Box'   => optional $ID_der_remoten_Box,
          'ParPac'=> als serialized array gepackte Parameter
          'EAObj' => $ObjID
          'TRIG'  => $_IPS['SELF'],
          ));
         */

// POSTEINGANG

// Test ob alle Parameter da 
        foreach (array ('PcTX', 'Cmd') as $Par) {
            if ( ! (isset ($_IPS[$Par])))
                die ("Mit RunScript wurde '$Par' nicht an JSON-RX gesendet!");
        }

        if ( ! (isset ($LANListe[$_IPS['PcTX']])))
            die ("Sende-PC " . $_IPS['PcTX'] . " nicht bekannt!");        //return;     // erst mal
...
// sonst Aufruf mit Cmd
            if (strpos ($LAN[PCname]['OS'], 'Linux'))
                exec ('touch /tmp/JSON_RX-Cmd.tic');
            switch ($_IPS['Cmd']) {
...
// Nur ein paar Beispiele:
                case 'ActData' :    // 'Act'-Skript wird der Box-Inhalt direkt zugestellt in 'ParPac'
                    if (isset ($_IPS['Act'])) {
                        IPS_RunScriptEx (GetObjectIDByIdentPath ($_IPS['Act']), array_merge ($_IPS, array (// reiche Parameter durch
                            'TRIG'  => $_IPS['SELF'], // wurde aufgerufen von ....
                            'TRIG2' => $_IPS['TRIG'], // und vorher von ....
                            'SEND2' => $_IPS['SENDER'])));
                    } else {
                        
                    }
                    break;

                case 'BLE_Data' :     // Raspis werden neue Daten direkt zugestellt in 'ParPac' (NOCH NICHT GETESTET)
                    break;

                case 'SetSkript' :     // ein Skript wird überschrieben (NOCH NICHT GETESTET)
                    break;

....



Das nur mal als Kurzabriß. Das komplette Skript ist noch viel komplizierter :loveips:

Ich hoffe, das hilft Dir weiter.

Viele Grüße
Harald