VDR segfaults mit usbremote plugin – woran liegt es?

  • Ab und zu segfaultet VDR beim Druck auf eine Fernbedienungtaste.
    Für die Fernbedienung läuft das usbremote plugin.
    Hier ein Core vom segfault.
    Zuerst kommt eine lange Liste, welche debuginfos fehlen, dann:

    Code
    Core was generated by `./vdr -w 120 -d -m -v /video/video -c /video/video -s /z/nvram-wakeup/VDR/vdrsh'.
    Program terminated with signal 11, Segmentation fault.
    #0  cRemoteUSB::Action (this=0x0) at usbremote.c:97
    97                  cCondWait::SleepMs(_polldelay);
    (gdb) bt
    #0  cRemoteUSB::Action (this=0x0) at usbremote.c:97
    #1  0x000000000050996d in cThread::StartThread (Thread=0x1711c50) at thread.c:262
    #2  0x00007f3388d17e0f in start_thread () from /lib64/libpthread.so.0
    #3  0x00007f33877577dd in clone () from /lib64/libc.so.6

    der Auszug aus usbremote.c, die drittletzte Zeile ist die 97.:

    dabei ist int _polldelay = 50;


    Interpretiere ich das richtig, dass die VDR Funktion cCondWait::SleepMs(_polldelay) bzw. cCondWait::Wait der Schuldige ist, oder liegt es am usbremote plugin?
    Kann ich irgendwas tun, um weiter zu debuggen, oder ist das ein Fall für Klaus?

  • Moin!


    Code
    this=0x0


    Von einem Objekt, das nicht existiert, kann nicht die Action-Methode aufgerufen werden.
    Irgendwo wird ein Thread gestartet, der aber irgendwie kein cThread-Objekt vom Plugin enthält. Sieht merkwürdig aus, keine Ahnung, wie man das hinbekommt...


    Lars.

  • Ich bin mir nicht sicher, ob bei diesem Segfault tatsächlich ein Tastendruck oder etwas anderes die Ursache war.
    Diese Segfaults kommen nicht oft vor, sind dann aber manchmal der Grund für eine kaputte Aufnahme.
    Daher läuft seit einiger Zeit vdr immer mit ulimit -c unlimited.
    Ich habe aber zu viele Sachen gleichzeitig gemacht, und weiß nicht mehr, was zu dem Zeitpunkt des Segfaults tatsächlich passiert ist.
    Vorsichtshalber habe ich aber cCondWait::SleepMs durch usleep ersetzt. Der "große Bruder", das remote plugin, macht es nämlich auch so.

  • Wie mini73 schon festgestellt hat: es crasht, weil this == 0 ist. Der Crash passiert dann wenn auf ein Attribut des this-Objekts zugegriffen wird, hier also _polldelay. Da wird es wenig nützen, statt cCondWait::SleepMs usleep zu nehmen.


    Wolfgang

    MSI C847MS-E33, Cine S2 6.0, Zotac GT630 (GK208), dual boot
    Work: yaVDR 0.7 ansible Ubuntu 22.04. Backup: yaVDR 0.5 Ubuntu 12.06


  • Wird da irgendwo cRemoteUSB::Action(void) als Function aufgerufen, anstatt per Start() als Thread?


    Ist aber wirklich Fischen im Trüben.


    Gerald


    HP Proliant MicroServer Gen8, Xeon E3-1230, 12 GB RAM, 3xWD red 2TB im RAID 5, 2xSundtek MediaTV Home DVB-C/T, L4M TWIN-C/T, Ubuntu Server 14.04.1, Plex Media Server
    Samsung UE55H6470

  • Hier die usbremote.c
    Falls da jemandem ein Fehler ins Auge springt ;)

    Ansonsten warte ich auf das nächste core file, bei dem ich weiß, dass ich eine Taste gedrückt habe.


    Edit: Typischerweise tritt der segfault auf, wenn vdr vor sich hin läuft und was aufnimmt, und ich irgendwann zur Fernbedienung greife und xine starte. Also bei der ersten Benutzung der Fernbedienung.

  • Jetzt ist es wieder passiert: der VDR nimmt was auf, ich starte xine mit einem Druck auf die entsprechende Taste auf der Fernbedienung, um mal rein zu schauen, und der VDR segfaultet.
    Diesmal ist das Core 100% sicher von dem Segfault.
    Der einzige Unterschied zum letzten Mal ist, dass diesmal this=0x1 und ich cCondWait::SleepMs durch usleep ersetzt habe.


    Daher noch mal die Bitte an alle, die sich damit auskennen, mir zu helfen.
    Was sagt das, und hilft das weiter? Was kann ich tun, um da weiter zu kommen?


    Code
    Core was generated by `./vdr -w 120 -d -m -v /video/video -c /video/video -s /z/nvram-wakeup/VDR/vdrsh'.
    Program terminated with signal SIGSEGV, Segmentation fault.
    #0  cRemoteUSB::Action (this=0x1) at usbremote.c:96
    96                  usleep(1000*_polldelay);
    (gdb) bt
    #0  cRemoteUSB::Action (this=0x1) at usbremote.c:96
    #1  0x000000000050eaef in cThread::StartThread (Thread=0xcef7b0) at thread.c:262
    #2  0x00007fa0259190db in start_thread () from /lib64/libpthread.so.0
    #3  0x00007fa02434790d in clone () from /lib64/libc.so.6
  • Irgendwas in deinem Speicher wird überschrieben.
    Ist es sicher, dass alle Plugins gegen die gleichen und richtigen vdr-Header übersetzt sind?
    Notfalls mal alle Plugins lokal neubauen.


    Lars

  • Vdr und die Plugins wurden lokal in einem Rutsch gebaut.
    Woran siehst du das mit dem Speicher, und was kann ich da noch debuggen?
    Das Plugin hat früher jahrelang tadellos funktioniert, aber von Februar 2013 bis jetzt hatte ich an 6 Tagen diese Segfaults. Ich bin alle Änderungen durch gegangen, aber kann es nicht wirklich zuordnen.

  • "this=0x1" ist das Zeichen dafür. Sieht so aus, als ob irgend etwas den Speicher überschreibt, wo dieser Zeiger liegt.
    Das Problem muss noch nicht mal in usbremote sein, das kann auch irgend ein anderes Plugin sein. Deshalb meine Idee, mit dem neubauen, damit wir sicher sein können, dass alle Plugins und der vdr die richtigen struct-Größen haben. Wenn sonst z.B. ein Patch in einer Klasse ein neues Member einfügt, aber ein Plugin das nicht über den Header sieht, dann würde es Uneinigkeiten über die Zeiger geben.


    Aber es sieht schon merkwürdig aus. In cThread::StartThread ist Thread=0xcef7b0, aber in der Action-Funktion dann plötzlich 0x1.
    Wo ist der komplette Source zu usbremote? Auf die Schnelle finde ich nichts...


    Lars.

  • Und danke, dass du da reinschaust.


    Wobei es wirklich fragwürdig ist, ob der Zeitaufwand dafür lohnt. Dieses Plugin unterstützt nur einen einzigen aussterbenden IR-Empfänger, der auch sehr gut ohne das Plugin laufen würde.
    Würde man Lirc anstatt des Plugins verwenden, dann hätte man zusätzlich auch noch den Vorteil, dass da ein Plugin weniger ist, das den VDR herunterreißen kann.


    Immer wenn man die Wahl hat etwas über ein Plugin, oder über eine externe Lösung zu erreichen, sollte man die externe Lösung wählen, zugunsten von Stabilität und verringertem Supportaufwand.


    Gerald


    HP Proliant MicroServer Gen8, Xeon E3-1230, 12 GB RAM, 3xWD red 2TB im RAID 5, 2xSundtek MediaTV Home DVB-C/T, L4M TWIN-C/T, Ubuntu Server 14.04.1, Plex Media Server
    Samsung UE55H6470

  • Keine Ahnung, was da schief läuft. Evtl. bewahrt dich dieser Patch vor Abstürzen, aber besser wäre es herauszufinden, warum der Zeiger plötzlich kaputt ist.


    Oder statt direkt auf _polldelay usw. zuzugreifen, _current->_polldelay usw. benutzen.
    Verschleiert aber auch nur statt zu lösen.


    Die einzige Stelle, wo der Pointer auf das remote-Objekt gespeichert wird, ist die Liste "Remotes" im vdr.
    Erstellt noch irgendein anderes der von dir benutzten Plugins ein cRemote-Objekt? Brauchst du die cKbdRemote und cLircRemote des vdr? Kannst du die auch mal disablen?


    Lars.

  • Lars,


    wird das denn funktionieren? _current ist ja auch ein Attribut der Klasse cRemoteUSB, dann wird ein Zugriff darauf auch crashen, wenn this ungültig ist. Vielleicht _current als static deklarieren? Ist natürlich ein noch üblerer Hack und funktioniert auch nur, wenn es nur ein cRemoteUSB-Objekt gibt.


    Oder hab ich etwas übersehen?


    Wolfgang

    MSI C847MS-E33, Cine S2 6.0, Zotac GT630 (GK208), dual boot
    Work: yaVDR 0.7 ansible Ubuntu 22.04. Backup: yaVDR 0.5 Ubuntu 12.06


  • Ah, hab ich übersehen, ja, sollte static sein...
    Ich hab hier nichts zum Übersetzen, war nur im Editor zusammengehackt.


    Lars.

  • Und es gibt ja auch nur ein cRemoteUSB-Objekt, wenn es mehrere geben würde, gäbe es ein ganz anderes Problem.


    Danke!
    Lars.

  • Wie könnte ich herausfinden, warum der Zeiger plötzlich kaputt ist? Ich habe keine Ahnung von so was.
    Wenn ich das richtig verstehe, führt dein Patch statt zu einem Segfault zu einer Fehlermeldung (und es würde nicht mehr auf die Fernbedienung reagieren), oder?


    Ich könnte auch mal lirc ausprobieren, beim letzten Mal (lange her) war aber usbremote viel besser als lirc.
    gda: Hast du da praktische Erfahrung, dass der Igorplug jetzt mit lirc sehr gut läuft?

  • Genau, das ist der Plan. Wenn du Glück hast, taucht die Meldung evtl. unabhängig vom einem Tastendruck auf und anhand der Meldungen davor könnte man sich inspirieren lassen. Viel Hoffnung mache ich mir aber nicht, so einem Fehler auf die Spur zu kommen ist sehr schwer.


    Die header passen auch noch zum Treiber? Nicht, dass sich da struct-Größen oder so geändert haben.


    Lars

  • Der Fehler ist tatsächlich schon mal ohne Tastendruck aufgetreten, aber die letzte Meldung davor lag 13 Minuten zurück (da hatte der vdr die pids von einem Kanal geändert).


    Welche Header, und welcher Treiber? Muss ich nach einem Kernel Update das usbremote Plugin neu bauen? Geht es um usb.h?

  • Ich stochere da genauso im Dunkeln wie du. Neubau nach Kernelupdate kann man mal versuchen, auch wenn es theoretisch nicht nötig sein sollte. Aber wer weiß das schon...
    Die avr_*-Funktionen verstehe ich zwar im Prinzip, weiß aber nicht, wie abhängig die von sonstigen System-Dingen sind.


    Lars.

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!