remotetimers für tvguide-0.0.6-git

  • Hi Saman,


    dann würde ich sagen...sch***ß der Hund drauf :D macht ja eh keiner, 20 Serientimer hintereinander anzulegen...


    Wenn ich dazu komme, werde ich deinen Patch ins Git aufnehmen.


    Ciao Louis

  • Super!


    Mir ist bei meiner Serientimer-Orgie noch was aufgefalllen:
    Im Gegensatz zu normalen Timern können Serientimer ja immer angelegt werden, egal ob schon ein Timer existiert oder nicht.
    Am Server werden dann auch zwei Timer erstellt.
    Sitzt man aber am Client, wird der erste Timer deaktiviert.


    Damit das Verhalten gleich ist, sollten wir ihmo den Patch da noch anpassen:


    Seit ich das 'seriesTimer = rt.timer' drinn habe, ist er mir auch nicht mehr abgeschmiert.


    Gruß S.

  • Moin!


    Wird durch den Service-Aufruf "RemoteTimers::NewTimer" ein neues Timer-Objekt erstellt? Wenn ja, dann hast du da einen Memory-Leak, weil dein seriesTimer nicht gelöscht wird. Oder macht das der Aufruf auch?


    Lars.

  • Moin Lars,


    ich meine das passt so, aber hier mal der dazugehörige Code


  • Ach meno,


    jetzt habe ich nochmal alle Timer gelöscht und drei Serientimer angelegt und bums...


    Vorschläge?

  • Debuggen

    - Client1: Thermaltake DH 102 mit 7" TouchTFT * Debian Stretch/vdr-2.4.0/graphtft/MainMenuHooks-Patch * Zotac H55-ITX WiFi * Core i3 540 * 4GB RAM ** Zotac GT630 * 1 TB System HDD * 4 GB RAM * Harmony 900 * satip-Plugin

    - Client2: Alfawise H96 Pro Plus * KODI
    - Server: Intel Pentium G3220 * DH87RL * 16GB RAM * 4x4TB 3.5" WD RED + 1x500GB 2.5" * satip-Plugin
    - SAT>IP: Inverto iLNB


  • Debuggen


    http://www.vdr-portal.de/board…de-0-0-6-git/#post1152481


    Und noch ein aktueller ...


    Da beschwert er sich jetzt darüber: #0 0x000000000050d71e in cTimer::IncDay (t=2325348707497949753, Days=-1) at timers.c:377

    Einmal editiert, zuletzt von Saman ()

  • Nachdem das einfach viel zu groß für einen gültigen Timestamp ist - läuft da evtl. eine Variable über oder ist falsch definiert?

    Code
    0x00007f4912ece796 in strftime_l () from /lib/x86_64-linux-gnu/libc.so.6
    #2  0x0000000000513425 in TimeString (t=3258125826116366386) at tools.c:1124

    yaVDR-Dokumentation (Ceterum censeo enchiridia esse lectitanda.)

  • Hi Saman,


    mini hat recht, du erzeugst auf jeden Fall ein Memory Leak.


    Ich erzeuge den Seriestimer mit new und übergebe diesen Timer dann mit Timers.Add(seriesTimer) an den VDR. Der kümmert sich dann um diesen Timer...


    Du hingegen erzeugst den Seriestimer mit new und übergibst dann diesen Timer an den Server...auf dem Client existiert dieses Objekt aber immer noch und hängt quasi in der Luft. Das ist ein bisschen blöd, da du den ja auch nicht mit delete löschen kannst, weil man die Infos vom Timer ja später noch für die Bestätigungsnachricht benötigt.


    Vor dem

    Code
    seriesTimer = rt.timer;


    muss auf jeden Fall ein

    Code
    delete seriesTimer


    Aber auch danach musst du dich darum kümmern, dass seriesTimer wieder gelöscht wird...vielleicht hängt das mit deinen Crashs zusammen?!


    Ciao Louis

  • Moin!


    remotetimers macht schon ein delete, wenn kein Fehler auftritt, siehe Zeile 10.
    Wenn vor dem "seriesTimer = rt.timer" noch mal ein delete aufgerufen wird, wird's doppelt gelöscht, das ergibt dann auch einen Fehler.
    Da hilft nichts, man muss alle möglichen Pfade einmal durchchecken, wer was wann löscht. Das hängt ja auch noch an der Konfigurationsoption "RemoteTimersSetup.addToRemote" und auch, ob ein Fehler aufgetreten ist oder nicht.
    Soweit ich das überblicke, wird beim Fehler das Timer-Objekt gelöscht und der Pointer in data auf NULL gesetzt (DELETENULL-Aufruf). Scheint also so, dass remotetimers die Verantwortung über das timer-Objekt übernimmt.


    Im Endeffekt heißt es eigentlich, dass "cRecManager::CreateSeriesTimer" ggf. NULL zurückgeben kann, berücksichtigt ihr das?


    Lars.

  • Jo Lars das klingt vernünftg ;)


    Die Frage ist, ob DELETENULL das Objekt dann auch explizit auf NULL setzt, es klingt schwer danach...falls nicht müsstest du im Falle eines Remotetimers explizit NULL in der Funktion CreateSeriesTimer zurückgeben.


    In der recmenus.c müsste das Objekt cRecMenuConfirmSeriesTimer ab Zeile 320 dann wiefolgt aussehen:



    So wird bei einem remotetimers Seriestimer keine genaue Info über den Timer ausgegeben...aber damit sollte man leben können.


    Ciao Louis

  • Moin!


    So sieht DELETENULL in vdr/tools.h aus:

    Code
    template<class T> inline void DELETENULL(T *&p) { T *q = p; p = NULL; delete q; }


    Der Pointer wird temporär gemerkt, der ursprüngliche auf NULL gesetzt und dann das Objekt gelöscht. rt.timer müsste also NULL enthalten, der wird dann auch durch die Zuweisung nach seriesTimer kopiert.


    Zu der Bemerkung "Seit ich das 'seriesTimer = rt.timer' drinn habe, ist er mir auch nicht mehr abgeschmiert." wird es auch klar: seriesTimer hat auf ein ungültiges Objekt gezeigt, dann kann alles passieren. Wenn der Speicher noch nicht überschrieben wurde, sieht der Code ein Timer-Objekt. Wenn der Speicher in der Zwischenzeit allerdings neu benutzt wurde, steht da irgendwas drin. Ein Wunder, dass er nicht immer abgeschmiert ist... :)


    Lars.

  • Ich hab jetzt in den letzten Tagen wirklich viiiiele Timer gesetzt, gelöscht, deaktiviert und wieder aktiviert. Probleme macht nur das setzen der Serientimer.
    cRecMenuConfirmSeriesTimer habe ich bei mir geändert und werde testen.

  • Bums...


    Mir ist jetzt noch aufgefallen, das Tage und Zeiten im Bestätigungsfenster manchmal nicht korrekt sind.
    Im Timermenü passt dann aber alles.


    Das würde auch dazu passen:

    Nachdem das einfach viel zu groß für einen gültigen Timestamp ist - läuft da evtl. eine Variable über oder ist falsch definiert?

    Code
    0x00007f4912ece796 in strftime_l () from /lib/x86_64-linux-gnu/libc.so.6
    #2  0x0000000000513425 in TimeString (t=3258125826116366386) at tools.c:1124

    Einmal editiert, zuletzt von Saman ()

  • Ist eigentlich klar, der seriesTimer Pointer ist nicht explizit auf NULL gesetzt, sonst würde dieser Codeblock mit dem TimeString() aus dem Crashlog doch gar nicht ausgeführt.


    Setze doch mal in der recmanager.c in der CreateSeriesTimer am Ende deines "if (tvguideConfig.useRemoteTimers && pRemoteTimers)" Zweigs ein


    seriesTimer = NULL;


    Dann sollte es eigentlich passen.


    Ciao Louis

  • Habe ich gemacht:



    Damit gibt es am Client natürlich nur noch ein 'Serientimer wurde angelegt', dafür bis jetzt aber noch keinen Absturz.
    Für mich wäre das ein brauchbarer Kompromis. Ich teste aber noch ein bisschen.

  • Ja, die kann dann natürlich noch raus.


    der Vollständikeit halber noch mal komplett


    30 Serientimer später habe ich immer noch keinen Absturz.
    Allerdings intressiert es mich schon, warum das mit der Rückgabe von seriesTimer nicht funktioniert... aber gut.

  • Saman: na dann passt es doch. Ich denke auch dass man mit der eingeschränkten Bestätigung leben kann. Sicherlich könnte man das auch noch einbauen, aber schlimm finde ich es nicht.


    Warum es nicht funktioniert ist eigentlich klar: mit "rt.timer = seriesTimer;" zeigen beide Timer-Pointer auf das ursprüngliche seriesTimer Objekt. Du übergibst dem remotetimers Plugin den rt.timer Pointer, und das remotetimers Plugin führt intern ein delete auf diesen Pointer aus. Nach Zeile 30 zeigt also der seriesTimer Pointer auf freigegebenen Speicher. Wie Lars schon geschrieben hat, solange der Speicher nicht überschrieben wird, funktioniert alles, wird aber in der Zeit, bis das Confirmation Fenster ausgegeben wird, dieser Speicherbereich von jemand anderem überschrieben, dann kann da sonstwas stehen und es kracht gewaltig. Das setzen des "seriesTimer = NULL" ist notwendig, da der Pointer ja immer noch auf den ursprünglichen Speicherbereich zeigt...


    Wenn du die ursprüngliche Ausgabe des Confirmation Fensters erhalten willst, müsstest du eigentlich nur ein zweites Timer Objekt als eine Kopie des seriesTimer Objekts erzeugen (also wirklich neu, in einem eigenen Speicherbereich auf dem Heap) und das dann zurückgeben. Das müsstest du dann allerdings auch selbstständig wieder per delete Löschen, nachdem das Confirmation Fenster angezeigt worden ist.


    Ciao Louis

Jetzt mitmachen!

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