[gelöst] Segmentation fault bei Aufruf von vdr --help mit installierten Plugin tvscraper

  • Hallo,

    beim Aufruf von vdr --help bekomme ich ein Segmentation fault.

    vdr 2.7.3 (etwas gepatched)
    tvscraper 1.2.12

    Der Segfault tritt nur auf, wenn tvscraper installiert ist.

    Hier der Aufruf und Backtrace dazu:

    MarkusE kannst Du Da schon etwas erkennen, bevor ich alles vanilla baue?

    Vielen Dank.

    Heiko

    Gentoo Linux ~ VDR 2.7.4 ~ DD Octopus NET V2 S2 Max - SAT>IP ~ Asrock N100M ~ 16GB RAM ~ NVIDIA T1000 8G

  • Ich kann diesen Fehler nicht reproduzieren. Ein ähnlicher Fehler wurde hier im Forum aber schon mal reportet. Möglicherweise hängt es an der Version von gcc. Mit welchem gcc übersetzt Du?

    Ich denke, es geht um die Implementierung einer Instanz von cEpgHandler. Da ist mein Destructor aber recht einfach, da kann eigentlich nichts schiefgehen:

    Code
     ~cExtEpgHandler() { }

    Du kannst Da testweise mal ein

    Code
    virtual ~cExtEpgHandler() { }     

    draus machen (in "tvscraper.c" Zeile 110.

    Oder diese Zeile komplett löschen, macht ja eh nichts ...


    ~ 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

  • Hallo MarkusE .

    Ich habe beide Varianten getestet, aber ohne Erfolg.

    und


    Es gibt in beiden Fällen trotzdem einen Segfault.

    Meine gcc-Version ist 14.2.1_p20241221.
    Allerdings spiele ich auch gerade ein wenig mit LTO rum, also mit dem Flag -flto...

    Gentoo Linux ~ VDR 2.7.4 ~ DD Octopus NET V2 S2 Max - SAT>IP ~ Asrock N100M ~ 16GB RAM ~ NVIDIA T1000 8G

  • Da kannst ja auch mal

    Code
    extEpgHandler = new cExtEpgHandler();

    in tvscraper.c Zeile 178 auskommentieren, zum Test.

    Eigentlich macht ja VDR alles: mit dem Erzeugen von cExtEpgHandler() fügt VDR das Objekt in die Liste der EPG Handler ein, und beim Verlassen von VDR löscht VDR diese EPG Handler. Ich mache da nichts, insbesondere lösche (delete) ich auch nie extEpgHandler. Das macht ja schon VDR.

    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

  • Da kannst ja auch mal

    Code
    extEpgHandler = new cExtEpgHandler();

    in tvscraper.c Zeile 178 auskommentieren, zum Test.

    Eigentlich macht ja VDR alles: mit dem Erzeugen von cExtEpgHandler() fügt VDR das Objekt in die Liste der EPG Handler ein, und beim Verlassen von VDR löscht VDR diese EPG Handler. Ich mache da nichts, insbesondere lösche (delete) ich auch nie extEpgHandler. Das macht ja schon VDR.

    Hallo MarkusE ,

    Das hat funktioniert. Damit kein Segfault beim Aufruf von vdr --help.

    Nebenwirkungen kann ich aber noch nicht beurteilen...

    Vielen Dank.

    Gentoo Linux ~ VDR 2.7.4 ~ DD Octopus NET V2 S2 Max - SAT>IP ~ Asrock N100M ~ 16GB RAM ~ NVIDIA T1000 8G

  • zu Nebenwirkungen: cExtEpgHandler, der jetzt nicht mehr aufgerufen wird, macht folgendes:

    • Verhindert, dass der VDR EPG Scan eine Description überschreibt, die von tvscraper ergänzt wurde (um Folgennummer/Episodennummer einer Serie)
    • Verhindert, dass der VDR EPG Scan eine Description überschreibt, die von einem tvscraper Plugin für externes EPG geholt wurde
    • Verhindert, dass der VDR EPG Scan einen Kurztext durch einen leeren Kurztext ersetzt.

    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

  • zu Nebenwirkungen: cExtEpgHandler, der jetzt nicht mehr aufgerufen wird, macht folgendes:

    • Verhindert, dass der VDR EPG Scan eine Description überschreibt, die von tvscraper ergänzt wurde (um Folgennummer/Episodennummer einer Serie)
    • Verhindert, dass der VDR EPG Scan eine Description überschreibt, die von einem tvscraper Plugin für externes EPG geholt wurde
    • Verhindert, dass der VDR EPG Scan einen Kurztext durch einen leeren Kurztext ersetzt.

    Klingt alles nützlich, so dass man es nicht einfach über Bord werfen sollte...

    Gentoo Linux ~ VDR 2.7.4 ~ DD Octopus NET V2 S2 Max - SAT>IP ~ Asrock N100M ~ 16GB RAM ~ NVIDIA T1000 8G

  • kls ,

    kannst Du dir das bitte mal anschauen? Der segfault passiert beim Abräumen der EPG Händler, und wie oben schon geschrieben, ich mache da nichts. Ich mache lediglich

    Code
    class cExtEpgHandler : public cEpgHandler
    {
      public:
        cExtEpgHandler() : cEpgHandler() { }
        ~cExtEpgHandler() { }
        ...
    };

    (die Klasse cExtEpgHandler hat keine Member Variablen) und später im Programm:

    Code
    cPluginTvscraper::cPluginTvscraper(void) {                                                                                                       
    // create, but never delete (because VDR deletes this during shutdown)                                                                           
      extEpgHandler = new cExtEpgHandler();                                                                                                          
    }

    also, extEpgHandler wird dann nie wieder verwendet, insbesondere mache ich definitiv kein delete(extEpgHandler).

    Der hier beobachtete segfault scheint aus

    Code: tools.h
    void cListBase::Clear(void)
    {
      while (objects) {
            cListObject *object = objects->Next();
            delete objects;
            objects = object;
            }
      objects = lastObject = NULL;
      count = 0;
    }

    zu kommen. Kann eigentlich nur passieren, wenn gleichzeitig ein anderer thread auch auf diese Liste zugreift.

    Mein Plugin (tvscraper) ist es nicht, tvscraper greift nie darauf zu.

    Räumt da ein thread schon auf, während ein anderer thread noch den Konstruktor des Plugins ruft?

    Oder ist das ein Compilerfehler?

    ~ 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 Wenn das nur bei "vdr --help" auftritt stellt sich die Frage, warum extEpgHandler dafür schon angelegt wird. Ich würde das erst im Initialize() anlegen. Und: warum wird extEpgHandler überhaupt gemerkt? Ein einfaches "new cExtEpgHandler();" in cPluginTvscraper::Initialize() würde doch reichen.

  • heifisch , kannst du mal testweise direkt nach

    Code
    bool cPluginTvscraper::Initialize(void) {

    (tvscraper.c Zeile 234)

    Code
    new cExtEpgHandler();

    einfügen, und dann noch mal testen?

    Aus tvscraper.c Zeile 178 hast Du es ja schon auskommentiert, es darf natürlich nur einmal gemacht werden.


    Bei mir tritt der Fehler ja nicht auf ...

    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 Mit dieser Änderung tritt kein Segfault auf.

    Ergänzung:
    Ich habe den VDR und das Plugin ohne die Korrekturen nochmal ohne LinkTimeOptimization compiliert.
    Da trat der Segfault auch nicht auf.

    Wenn die letzte Änderung sinnvoll ist, sollte man sie trotzdem übernehmen.

    Gruß und Danke

    Gentoo Linux ~ VDR 2.7.4 ~ DD Octopus NET V2 S2 Max - SAT>IP ~ Asrock N100M ~ 16GB RAM ~ NVIDIA T1000 8G

  • Ich habe das übernommen. Für mich ist es egal, ob das in Initialize oder im constructor passiert.

    Hoffen wir mal, dass VDR keinen EPG scan macht, bevor das Initialize der Plugins aufgerufen wird ... kls ?

    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

  • heifisch February 11, 2025 at 10:28 PM

    Changed the title of the thread from “Segmentation fault bei Aufruf von vdr --help mit installierten Plugin tvscraper” to “[gelöst] Segmentation fault bei Aufruf von vdr --help mit installierten Plugin tvscraper”.
  • Hi kls ,

    könntest Du noch in die Dokumentation (PLUGINS.html) aufnehmen, dass das Plugin eine Instanz erzeugen muss, und zwar in Initialize() ? Also in dem Beispiel in PLUGINS.html ein

    Code
    new cMyEpgHandler();

    in der Initialize() Methode stehen muss? Und auch, dass alles andere VDR macht, insbesondere auch das Löschen dieses Objektes.

    In der Doku steht zwar, dass im Constructor die globalen VDR Tabellen nicht verwendet werden dürfen. Für den Plugin-Entwickler ist aber nicht unbedingt ersichtlich, dass ein new cMyEpgHandler(); zu einem Zugriff auf eine globale VDR Tabelle führt.

    Auch ein späterer Aufruf von new cMyEpgHandler(); ist problematisch, wenn zu diesem Zeitpunkt gerade ein EPG Scan läuft.

    ~ 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

  • Naja, das EpgHandler-Objekt im Destructor von cListBase mit Clear() löschen zu lassen finde ich nicht wirklich elegant.

    Warum nicht einfach ein delete im Stop() des Plugins?

    Viele Wege führen nach Rom.

    Eine Designentscheidung die vor vielen Jahren getroffen wurde und jetzt nicht mehr geändert werden sollte. Ich glaube nicht, dass es hier einen Weg gibt der deutlich besser ist als die jetzige Implementierung.

    Wir brauchen "nur" eine Dokumentation, in der steht, wie es geht.

    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

  • Wir brauchen "nur" eine Dokumentation, in der steht, wie es geht.

    class cEpgHandler : public cListObject {
    public:
    cEpgHandler(void);
             ///< Constructs a new EPG handler and adds it to the list of EPG handlers.
             ///< Whenever an event is received from the EIT data stream, the EPG
             ///< handlers are queried in the order they have been created.
             ///< As soon as one of the EPG handlers returns true in a member function,
             ///< none of the remaining handlers will be queried. If none of the EPG
             ///< handlers returns true in a particular call, the default processing
             ///< will take place.
             ///< EPG handlers will be deleted automatically at the end of the program.

  • Eine Designentscheidung die vor vielen Jahren getroffen wurde und jetzt nicht mehr geändert werden sollte

    Das kann ich nachvollziehen (Never change a running system), andererseits musste das "new" ja auch schon nach Initalize() verschoben werden.
    Letzlich ist es Deine Entscheidung - ich kann nur sagen, dass ich ohne zusätzliche Doku in meinem EPG-Plugin das EPGHandler-Objekt in Initialize() erzeuge und in Stop() lösche und keine Probleme habe.

Participate now!

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