Absturz wegen cEvent::title == NULL - Warum???

  • Ich habe exemplarisch mal ein wenig in Live herumgestöbert und frage mich, ob zum Beispiel hier:

    ...

    … nicht auch noch ein LOCK_SCHEDULES_READ gebräucht würde.

    Die Funktion bekommt ja 'schedules' übergeben, welches nur über einen Lock erhalten werden konnte.

    Also nein.

    Heißt das, dass man keine Locks setzen muss, solange man den zugeordneten Pointer (Timers, Channels, Schedules, Recordings) im Code nicht benötigt?

    So ist es.

    Welche indirekte Abhängigkeiten gibt es diesbezüglich? Wie etwa die folgenden:

    Du musst nur die Listen locken, mit denen du arbeiten möchtest. Wenn du mit mehreren Listen gleichzeitig arbeiten möchtest, musst du sie alle locken, und zwar in genau der genannten Reihenfolge, da es sonst zu Verklemmungen kommen könnte, wenn mehrere Threads auf mehrere Listen warten, sie aber in unterschiedlicher Reihenfolge locken.

  • Ich denke, hier wäre zusätzliche Dokumentation hilfreich.

    Ist generell ein lesender Zugriff auf ein cEvent nur dann erlaubt, wenn ein read lock auf schedules gehalten wird?

    Oder: Darf ich auf bestimmte Methoden eines cEvent zugreifen, ohne einen read lock auf schedules? Z.B. auf EventID()?

    Und brauche den read lock auf schedules nur beim Zugriff auf "kritische" Methoden, z.B. Title(), ShortText(), ...?

    ~ Markus

    Client1: ASUS P5QC, Dual Core 3G, Cine S2, Ext. Board von TBE, Xubuntu 20.04, VDR 2.6x

    Client2: RPI3

    Server: RPI4, Sundtek SkyTV Dual 2x

  • MarkusE Sobald ein Pointer auf ein Objekt in einer dieser Listen dereferenziert wird, muss ein entsprechender Lock bestehen.

    Siehe auch tools.h:

  • Es gibt noch eine Stelle, an der ich mich nicht an meine eigene Vorgabe gehalten habe ;)

    Diff
    --- skinlcars.c 2024/09/21 10:53:07     5.7
    +++ skinlcars.c 2024/12/02 14:15:55
    @@ -1259,6 +1259,7 @@
          int NumDevices = 0;
          int y = ys04;
          // Timers and recording devices:
    +     LOCK_SCHEDULES_READ;
          while (1) {
                int NumTimers = 0;
                const cDevice *Device = NULL;
  • Sobald ein Pointer auf ein Objekt in einer dieser Listen dereferenziert wird, muss ein entsprechender Lock bestehen.

    Danke dir. Ich hatte so eine Antwort erwartet bzw. befürchtet. Da wird wohl in machen Plugins noch einiges zu berichtigten sein…

    Hardware: Antec NSK2480, Asus P8B75-M LX, Intel Core i5-3570T, 4 GB RAM, NVIDIA GT610, TT-Premium S2-6400, 128 GB SSD, 14 TB HDD, Pioneer BDR-207EBK
    Software: Ubuntu 22.04 LTS mit Kernel 6.8 und VDR 2.7.5 (mit offiziellen und eigenen Patches)
    Plugins: devstatus, dvbhddevice, dvd, dvdswitch, epgsearch, extrecmenu, recsearch, femon, live, markad, mlist, osdteletext, remote, screenshot, skinnopacity, streamdev, systeminfo, undelete, xineliboutput
    Addons: VDR Convert 0.1.0 (angepasst)

  • Heißt das, dass man keine Locks setzen muss, solange man den zugeordneten Pointer (Timers, Channels, Schedules, Recordings) im Code nicht benötigt?

    So ist es.

    und

    Sobald ein Pointer auf ein Objekt in einer dieser Listen dereferenziert wird, muss ein entsprechender Lock bestehen.

    Ist für mich gerade irgendwie ein Wiederspruch.

    Beispiel:

    Code
    bool cEpgHandlerMarkad::HandleEvent(cEvent *Event) {
    ... irgendwelcher Code
        if (Event->RunningStatus() <= 0) return false;

    Brauche ich da einen LOCK_SCHEDULES_READ oder kann ich davon ausgehen, dass das Objekt für die Dauer des Aufrufes unverändert bleibt ?

    Ich nutze ja nicht die Liste, sondern nur ein einzelnes Objekt davon.

    VDR

    Server: Ubuntu 24.04 headless VDR im LXC Container, Plugins: satip (Octopus NET SL SX8), live, epgsearch, epg2vdr, markad

    Clients: LibreELEC auf RasPi3 und RasPi 3+

  • Ich nutze ja nicht die Liste, sondern nur ein einzelnes Objekt davon.

    … das sich zwischen den Zeilen 1 und 3 ja inzwischen schon wieder geändert haben oder gar gelöscht worden sein könnte. Insofern wäre mir der Lock einsichtiger, aber irgendwie bin ich jetzt noch mehr verwirrt.

    Für mich stellt sich die Situation bislang so dar: Wann auch immer man auf eine der Listen zugreift (sprich: einen der besagten Pointer benötigt) oder (später) eines seiner Objekte referenziert, braucht man Locks auf die ursprüngliche Liste sowie die Listen aller Objekte, die davon direkt oder indirekt verlinkt sind.

    Liege ich jetzt damit richtig, oder ist das noch immer nicht die ganze Wahrheit?

    Hardware: Antec NSK2480, Asus P8B75-M LX, Intel Core i5-3570T, 4 GB RAM, NVIDIA GT610, TT-Premium S2-6400, 128 GB SSD, 14 TB HDD, Pioneer BDR-207EBK
    Software: Ubuntu 22.04 LTS mit Kernel 6.8 und VDR 2.7.5 (mit offiziellen und eigenen Patches)
    Plugins: devstatus, dvbhddevice, dvd, dvdswitch, epgsearch, extrecmenu, recsearch, femon, live, markad, mlist, osdteletext, remote, screenshot, skinnopacity, streamdev, systeminfo, undelete, xineliboutput
    Addons: VDR Convert 0.1.0 (angepasst)

  • … das sich zwischen den Zeilen 1 und 3 ja inzwischen schon wieder geändert haben oder gar gelöscht worden sein könnte.

    Nein, kann es nicht, da:

    Wenn du ein Objekt übergeben bekommst, ist dessen Liste gelockt.

    VDR

    Server: Ubuntu 24.04 headless VDR im LXC Container, Plugins: satip (Octopus NET SL SX8), live, epgsearch, epg2vdr, markad

    Clients: LibreELEC auf RasPi3 und RasPi 3+

  • Ich habe in den letzten Tagen noch einige Untersuchungen mit testausgaben gemacht und dabei ist manchmal der Fall aufgetreten, dass ein cEvent entsteht, bei dem title==NULL ist, der aber anscheinend nicht durch FixEpgBugs() geht. Warum das so ist, konnte ich nicht herausfinden. An fehlendem Locking scheint es wohl nicht (nehr) zu liegen. Daher nun als "ultima ratio":

  • Ich hatte für die Fehlersuche in cEvent::Title() und cEvent::SetTitle() jeweils eine Abfrage eingebaut, ob zu dem Zeitpunkt der jeweilige Thread einen Read- bzw. Write-Lock auf Schedules hat. Das war aber eine eher "krude" Angelegenheit, da ich dazu einen Pointer auf Schedules brauchte und Members von pthread_rwlock_t abfragen musste, die plattformabhängig sind (auf Raspberry Pi anders als auf Linux gcc). Das offiziell einzubauen würde ich gerne vermeiden.

    Ich bin nicht ganz sicher ob das funktioniert, aber könnte man nicht einfach die Threadid des erstellenden Threads im Statekey-Objekt mit speichern.
    Dann muss man nur prüfen, ob die Threadid des eigenen Thread in der Liste auftaucht und der Lock (read/write) stimmt, dann sollte alles o.k. sein.
    An die Threadid des aktuellen Prozesses sollte man mit gettid() (oder besser pthread_self() ???) doch überall recht einfach ran kommen.

    Eine einfache Möglichkeit die Locks zu prüfen wäre echt hilfreich.
    Da jetzt Jahre nach Einführung (die Locks dürften doch auch bald 10Jähriges Jubiläum haben ^^) sogar im VDR noch fehlende gefunden werden, befürchte ich, dass sich bei den Plugins Abgründe auftun werden :angst.

    dabei ist manchmal der Fall aufgetreten, dass ein cEvent entsteht, bei dem title==NULL ist, der aber anscheinend nicht durch FixEpgBugs() geht.

    Das wäre echt blöd, wenn das sporadisch auch mit "sinnvollen" Events passiert, einige von der Korrekturen sind ja nicht nur Kosmetik. Amok laufende Suchtimer wären dann das geringste Problem, was mir so einfällt...
    Irgendwie sehe aber auch keine ich Möglichkeit, wie sich ein Event an der Korrektur vorbei mogeln kann.

    Das SetTitle() in der epg.c kann man wohl ausschließen, da es nur beim einlesen der epg.data verwendet wird. Dann würden die Fehler nur nach einem Neustart des VDR Auftreten, das hätte auffallen müssen.

    Evtl. eine blöde Idee, aber ist wirklich sicher gestellt das FixEpgBugs() nicht aufgerufen wurde und dass das fragliche Event nie einen Titel hatte?
    Nicht dass es eine Fehlfunktion in FixEpgBugs() ist, die durch irgendwelche komischen Sonderzeichen ausgelöst wird oder wenn der Titel nach FixEpgBugs() am Ende dann leer ist.

    Wirklich gesehen habe ich da bislang nichts, aber könnte eine der Helper-Funktionen einen NULL-String zurück geben?

    Schon versucht eine Abfrage auf title==NULL ganz am Ende von FixEpgBugs() einbauen?
    Das wäre interessant, ob die anschlägt.


    Ehrlich gesagt, verstehe ich trotz der Beschreibung hier noch immer nicht wirklich, was das für Events sind.
    Mit ein Bisschen mehr Informationen könnte man vermutlich die Art des Fehlers deutlich eingrenzen.

    Gibt es Gemeisamkeiten (außer dass der Titel fehlt ;))?
    Trifft es immer den gleichen Kanal?
    Sind das echte, sinnvolle Events, also Startzeit in den nächsten Wochen, plausible Länge, ...?

    Existieren die Events wirklich im Schedule oder nur im Menü? Lassen sich zB. auch mit SVDRP ausgeben?
    Wenn nicht, fehlt wohl immer noch irgendwo ein Lock.

    Was passiert, wenn man das EPG mit CLRE komplett löscht und dann neu scannt? Tifft es dann die gleichen Everts erneut?

    Tauchen die Fehler auch in der epg.data auf der Festplatte auf?
    Wenn ich das richtig interpretiere, sollte da dann einfach der Titel fehlen.

    Ich habe bei mir eben gesucht und nichts gefunden.
    grep -zoP "\nE.+\n[^T]" ./epg.data (Liefert der Einfachheit halber nur die erste Zeile des Events!)
    Im Produktiv-system ist aber eine recht alte VDR-Version am laufen (längere Geschichte).
    Was, falls andere die Fehler finden, bedeuten müsste, dass der grundlegende Fehler erst später rein gekommen ist.

    Falls jemand so ein Event in der epg.data findet, dann bitte hier mal rein stellen, gern auch mehrere. Ich würde es mir gerne mal ansehen.

    Da das Problem anscheinend nicht viele haben und ORF erwähnt wurde, könnte es evtl. an der speziellen Emfangssituation liegen? An der Kombination DVB-S plus deutschem und österreichischem DVB-T, meine ich.

    Gruss
    SHF

    Mein (neuer) VDR:

    Software:
    Debian Wheezy mit Kernel 3.14
    VDR 2.0.7 & div. Plugins aus YaVDR-Paketen
    noad 0.8.6

    Hardware:
    MSI C847MS-E33, onboard 2x1,1GHz Sandybridge Celeron 847, 4GiB RAM
    32GB SSD (System), 4TB 3,5" WD-Red HDD (Video)
    TT FF DVB-S 1.5 FullTS-Mod PWM-Vreg-Mod, DVB-Sky 852 Dual DVB-S2
    Das ganze im alten HP Vectra VLi8-Gehäuse versorgt von:
    PicoPSU-160-XT und Meanwell EPP-150 im ATX-NT-Gehäuse

  • Ich habe das Gefühl, dass das, wenn überhaupt, bei obsoleten Kanälen auftritt. Irgendwas läuft da beim EPG anders als bei anderen.

    Ich werde das für die nächste Version in cEvent so machen:

    const char *Title(void) const { return title ? title : ""; }

  • Ich habe bei mir eben gesucht und nichts gefunden.
    grep -zoP "\nE.+\n[^T]" ./epg.data (Liefert der Einfachheit halber nur die erste Zeile des Events!)

    Code
    darkwing@vdr01:~/src/skin-flatplus/vdr-plugin-skinflatplus-1.0.7$ grep -zoP "\nE.+\n[^T]" /var/cache/vdr/epg.data
    
    E 39470 1741595400 900 4E FF
    edarkwing@vdr01:~/src/skin-flatplus/vdr-plugin-skinflatplus-1.0.7$ 

    Man beachte das e zu beginn der letzten Zeile

    Kanallogos: Picon.cz2VDR | Picons2VDR | MP-Logos
    Backupskripte:
    MV_Backup (RSync) | MV_BorgBackup (Borg)

    Skin: Skin FlatPlus  VDR-Add_MSGT

    "Es gibt keinen Grund, warum irgendjemand einen Computer in seinem Haus wollen würde."
    [Ken Olson], Präsident der Digital Equipment Corp., 1977

    VDR01 - yaVDR 0.7 (VDR 2.7.3)

    VDR 2.7.3; Gehäuse: Antec Fusion V2 Black & iMon LCD; Atric IR-Einschalter Rev. 4; Board: Intel DH77EB, Core i5-3550, GTX 1050 Ti, 8 GB RAM; DVB: 1x Digital Devices CineS2 Quad V6.5

    >Systeminfo.txt< [VDR-User #1540]

  • Genau das Gleiche auf meinem VDR:

    root@VDR-2404-Dev:~# grep -zoP "\nE.+\n[^T]" /var/cache/vdr/epg.data

    E 39470 1741595400 900 4E FF
    eroot@VDR-2404-Dev:~#

    Das ist der ganze Eintrag inklusive der davor und danach:

    E 39062 1741593600 1800 4E 18
    T Medienwerkstatt (Wh.)
    S Dokus und Reportagen aus Nürnberg und der Region. Mehr Informationen finden Sie unter www.medienwerkstatt-franken.de
    D Die MEDIENWERKSTATT Franken realisiert Dokumentationen und Reportagen über zeitgeschichtliche, kulturelle und soziale Themen aus Nürnberg und der Region. Ob Künstlerporträt, Stadtteil-Film, Milieu-Studie, Langzeitdokumentation oder ausführliches Interview - in ihren 30-minütigen Filmen berichtet die MEDIENWERKSTATT stets auf Augenhöhe und lässt Menschen zu Wort kommen, die eher selten Gehör finden. Die Sendung läuft jeden Sonntag um 19, 21 und 22 Uhr, sowie montags, mittwochs und freitags in Wiederholungen. Mehr Infos unter medienwerkstatt-franken.de.
    e
    E 39470 1741595400 900 4E FF
    e
    E 39471 1741596300 1800 4E 1D
    T Medienwerkstatt (Wh.)
    S Dokus und Reportagen aus Nürnberg und der Region. Mehr Informationen finden Sie unter www.medienwerkstatt-franken.de
    D Die MEDIENWERKSTATT Franken realisiert Dokumentationen und Reportagen über zeitgeschichtliche, kulturelle und soziale Themen aus Nürnberg und der Region. Ob Künstlerporträt, Stadtteil-Film, Milieu-Studie, Langzeitdokumentation oder ausführliches Interview - in ihren 30-minütigen Filmen berichtet die MEDIENWERKSTATT stets auf Augenhöhe und lässt Menschen zu Wort kommen, die eher selten Gehör finden. Die Sendung läuft jeden Sonntag um 19, 21 und 22 Uhr, sowie montags, mittwochs und freitags in Wiederholungen. Mehr Infos unter medienwerkstatt-franken.de.
    e

    VDR

    Server: Ubuntu 24.04 headless VDR im LXC Container, Plugins: satip (Octopus NET SL SX8), live, epgsearch, epg2vdr, markad

    Clients: LibreELEC auf RasPi3 und RasPi 3+

    Edited once, last by kfb77 (March 10, 2025 at 10:42 AM).

Participate now!

Don’t have an account yet? Register yourself now and be a part of our community!