ring buffer overflows -> cDevice::Detach() blockiert...

  • Vielleicht spielt die Startreihenfolge der Plugins eine Rolle!? Ich hatte ähnliche Probleme vor 1 Jahr, hatte diese aber auf ein zu schlechtes Netzteil für den Raspberry schließen können....
    Ich habe aktuell erst das Ausgabe Plugin (rpihddevice), dann das OSD Teletext Plugin und dann das satip Plugin konfiguriert. Seit Monaten läuft nun auch das OSD Teletext Plugin ohne Probleme mit raspberry. :)

  • iNOB ja das ist klar und auch logisch. Ohne Anwender ist ja auch die beste Software nichts wert, und deren Erfahrung ist das A und O zum Erfolg.


    Uwe : das osdteletext plugin hatte ich heute morgen mal deaktiviert, dieses hat ja auch einen cReceiver-Thread, oder sogar mehrere, am laufen. Mit einem Skript, dass alle 5 Sekunden den Kanal wechselt hat es nun sehr lange gedauert, bis wieder ein deadlock und dan ring buffer offerflows passieren. Es hat also schon mit den cReceiver-Threads etwas zu tun. Aber somit ist es trotzdem nicht das osdteletext Plugin allein. Ich vermute ein Prinzipielles Problem, dass mit dem Handling des cThread Mutex zusammenhängt.


    Da ist nun wirklich jemand gefordert, der da den ganzen Durchblick hat...


    Gruss, und vielen Dank an alle die Mithelfen.
    Xcoder

    VDR: Zotac ZBOX EN860, 16GB RAM, 2 TB HDD, Debian Stretch, vdr-2.4.1, softhddevice, satip

  • Ich habe in device.c noch log Meldungen eingebaut und den Kanal alle 5 Sekunden gewechselt. Nach x-mal umschalten steckte es wie im oben imgdb backtrace zu sehen in cDevice::Detach()->cMutexLock::Lock()->cMutex::Lock() fest.



    Hier der Ausschnitt mit meinem Log-Code in cDevice::Detach():



    Wie kann ich was sonst noch mit dem Mutex vom receiver 0 device abhängt und diesen zu diesem Zeitpunkt lockt?


    Gruss, Xcoder

    VDR: Zotac ZBOX EN860, 16GB RAM, 2 TB HDD, Debian Stretch, vdr-2.4.1, softhddevice, satip

  • vdr-2.2.0 ist ja schon etwas älter, und es gibt da einige Patche dafür.
    Ich habe da z.B.
    Fix_TS_buffer_thread_high_CPU_usage.diff
    vdr-2.1.6-emmtime.diff
    vdr-2.2.0-caid_buffer-v2.diff
    vdr-clear-pids.diff
    Vermutlich hier aus dem Forum und auch von der VDR Mailing Liste.
    Der letzte könnte eventuell was mit deinem Problem zu tun haben, probier‘s einfach mal aus.


    Sonst wäre noch die Frage, ob er nur bei bestimmten Sendern crasht.

  • jrie Leider ohne Einfluss. Da ich das satip Plugin und minisatip nutze, sehe ich auch gut, dass die PIDs i.O. sind. Habe den Path eingespielt aber dieser hat keinen Einfluss.


    Ich denke ich habe nun die Threads isoliert welche sich gleichzeitig locken. Mit aktive osdteletext kommt der Fehler viel schneller. Nun hier der Backtrace der involvierten Threads. Der Pointer 0x2048660 ist das betreffende cThread Objekt und sowohl in Thread 1 und 159 vorhanden.



    Aber da habe ich immer noch nicht wirklich den Durchblick...

    VDR: Zotac ZBOX EN860, 16GB RAM, 2 TB HDD, Debian Stretch, vdr-2.4.1, softhddevice, satip

  • Das heisst aber erstmal nur, dass osdteletext da ein Problem hat.
    Weitaus interessanter wäre so ein backtrace ohne dass osdteletext läuft.


    Und wegen des Zürcher Senders empfehle ich:

  • Habe ich auch gedacht. Dann konnte ich das Problem aber auch ohne osdteletext reproduzieren... einfach mit leicht anderem backtrace. Das Problem bleibt aber, dass sich zwei Threads jeweils in einem Detach gegenseitig blockieren. Der eine Thread (jeweils #1) wartet in pthread_mutex_lock() auf einen mutex dessen owner ein anderer Thread ist, und dieser macht das umgekehrte...


    Momentan kann ich das Problem gerade nicht mehr reproduzieren, die Plugins femon, osdteletext, play und streamdev-server sind nicht installiert, dvb-api, satip, epgsearch, skindesigner, softhddevice, live und permashift sind aktiv. Der VDR schaltet nun seit 1h ohne deadlock von von Sender zu Sender... Eines der 4 noch nicht aktivierten wird es dann wohl sein.

    VDR: Zotac ZBOX EN860, 16GB RAM, 2 TB HDD, Debian Stretch, vdr-2.4.1, softhddevice, satip

  • Xcoder



    Momentan kann ich das Problem gerade nicht mehr reproduzieren, die Plugins femon, osdteletext, play und streamdev-server sind nicht installiert, dvb-api, satip, epgsearch, skindesigner, softhddevice, live und permashift sind aktiv. Der VDR schaltet nun seit 1h ohne deadlock von von Sender zu Sender... Eines der 4 noch nicht aktivierten wird es dann wohl sein.


    Da ich das Problem, besonders bei laufenden Aufnahmen, auch habe:
    Bei mir sind von den deaktivierten nur osdteletext (derzeit deaktiviert, Fehler bleibt) und femon installiert.


    Grüße,
    42

  • Oder dann doch nicht... Es ist wirklich zum verzweifeln. Nachdem permashift als Quelle schon ausgeschlossen hatte, ca 1h alle 5 sec Sender umschalten, kam es nun doch wieder zum deadlock. Aus dem Backtrace sieht man, dass 2 Threads auf einen mutex warten:



    Der owner des jeweiligen mutex ist der andere Thread:



    Eine Gemeinsamkeit ist, dass es jeweils in Thread #1 bis MsgChannelSwitch() geht, ab da kommt dann offenbar eine Methode aus einem beliebigen Plugin. Daher könnte es doch um ein prinzipielles VDR Problem gehen und ist nicht spezifisch für ein bestimmtes Plugin.


    Ideen wie man das weiter eingrenzt?


    Gruss, Xcoder

    VDR: Zotac ZBOX EN860, 16GB RAM, 2 TB HDD, Debian Stretch, vdr-2.4.1, softhddevice, satip

  • bei jedem Thread der neu erzeugt wird, dh. jedem Plugin und jedem thread in vdr selbst, im constructor dessen Adresse ausprinten.
    Dann kannst du anhand der Pointer Adressen sehen wer sich gegenseitig aufhängt.
    Interessant sind nur die Plugins und Threads, die Daten von einem (DVB-) Device holen.


    Ist nat. beliebig aufwändig.

  • Moin,

    bei jedem Thread der neu erzeugt wird, dh. jedem Plugin und jedem thread in vdr selbst, im constructor dessen Adresse ausprinten.


    oder alternativ den Debug Output in der Start Funktion von cThread anpassen...oder besser vor der Abfrage, ob der Thread eine Description hat, einen weiteren Debug Output einfügen. Am besten so:


    Code
    1. +dsyslog("starting thread, pointer %p", Thread);
    2. if (Thread->description) {
    3. dsyslog("%s thread started (pid=%d, tid=%d, prio=%s)", Thread->description, getpid(), Thread->childThreadId, Thread->lowPriority ? "low" : "high");


    Ciao Louis

  • ich würde


    .. %p", this);



    bevorzugen.


  • Hm, wenn ich mir diese Zeile so anschaue, dann kommt das aufs gleiche raus ;)


    Ciao Louis

  • By the way...ich habe zwar ein komplett anderes Setup (siehe Signatur, direkt eingebauter DVB-C Tuner), aber meine Frau schafft es auch mal ab und an, durch wildes Zappen den VDR in eine Deadlock Situation zu befördern. Da das aber extrem selten passiert (vielleicht einmal alle 4 Wochen bei sehr schnellem mehrfachem Umschalten), habe ich mich noch nicht so wirklich mit dem debugging beschäftigt. Beim letzten mal habe ich den VDR mit "killall -SIGSEGV vdr" abgeschossen, der VDR auf meinem Prod System ist aber ohne Debug Symbole gebaut. Deshalb war der coredump nicht so wirklich hilfreich. Wenn ich mich aber recht erinnere, war der Deadlock an einer ähnlichen Stelle...


    Ciao Louis

  • der VDR auf meinem Prod System ist aber ohne Debug Symbole gebaut


    Der vdr muss nicht mit Debug-Symbolen gebaut sein, die kann man beim Bauen auch in eine extra Datei extrahieren, so dass gdb sie wiederfindet und benutzen kann, das Programm selbst aber trotzdem kleiner bleibt. Müsstest du mal gucken, wie das unter gentoo funktioniert, bei Debian kann man die Symbole automatisch in ein dbg-Paket verschieben, welches man bei Bedarf installieren kann.


    Die werden dann unter /usr/lib/debug/.build-id/... abgelegt.


    Lars.

  • Ich weis ja, welche beiden Threads sich gegenseitig blockieren: es ist der main-Thread #1 und der jeweilige receiver Thread desjenigen Devices welches das Live Signal empfängt. Die Frage ist doch, wieso haben 2 Threads eine Referenz auf ein fremdes cThread Objekt und führe dessen Methode Lock() aus... Wenn das zufällig gleichzeitig passier, dann gibt es einen klassischen Deadlock.


    louis : das bestärkt mich in der Ansicht, dass es nicht an einem bestimmten Plugin liegen könnte, sondern am Design der Klassenhierarchie des VDR selber. Wenn ich bei mir alle gewünschten Plugins aktiviere, passiert es zu oft. Aber auch eher beim schnellen zappen, gelegentlich aber auch spontan beim ersten Umschalten nachdem stundenlang der selbe Sender lief. Es ist wohl reiner Zufall, passiert aber vermutlich öfter, wenn viele cReceiver Objekte in cDevice->receiver[] registriert sind (passiert in cDevice::AttachReceiver()). Eventuell hängt es ja sogar von der Hardware ab, wie oft es dazu kommen kann.


    Leider fehlt es mir da immer noch am Durchblick wie das zustande kommt. Schaut man sich nur schon mal den Backtrace an, sieht man um wie viele Ecken es da geht. Es ist schon ein ziemliches Gewimmel an Klassen und Methoden...



    Gruss, Xcoder

    VDR: Zotac ZBOX EN860, 16GB RAM, 2 TB HDD, Debian Stretch, vdr-2.4.1, softhddevice, satip

  • Hi, some time ago I looked at this propblem. Didn't fully understand it, but according to my documentation from then I believe:


    The main thread is busy detaching receivers. ( void cDevice::Detach(cReceiver *Receiver in device.c)
    holding mutexreceiver and doing a Lock()


    Another thread is doing "Distribute the packet to all attached receivers" (device.c 1605)
    If you put a delay after the lock at line 1606 you will see the deadlock very fast.


    At this time I am not shure if this is the problem, but maybe worth investigating.


    As a bypass I put a "cMutexLock MutexLock(&mutexReceiver);" before the Lock() in line 1605, this problem seems to be gone,
    but now I somethimes have lock problems with the streamdev plugin (but not very often) , so this is not a real solution.

    Greetings Rene

  • As a bypass I put a "cMutexLock MutexLock(&mutexReceiver);" before the Lock() in line 1605, this problem seems to be gone


    With that I get sometimes a black screen after channel switch (no streamdev involved).